- patches.arch/x86_mce_intel_decode_physical_address.patch:
[linux-flexiantxendom0-3.2.10.git] / drivers / scsi / qla2xxx / qla_isr.c
index db539b0..be3d8be 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/slab.h>
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_bsg_fc.h>
+#include <scsi/scsi_eh.h>
 
 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
 static void qla2x00_process_completed_request(struct scsi_qla_host *,
@@ -326,7 +327,7 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
 
        /* Setup to process RIO completion. */
        handle_cnt = 0;
-       if (IS_QLA81XX(ha))
+       if (IS_QLA8XXX_TYPE(ha))
                goto skip_rio;
        switch (mb[0]) {
        case MBA_SCSI_COMPLETION:
@@ -544,7 +545,7 @@ skip_rio:
                if (IS_QLA2100(ha))
                        break;
 
-               if (IS_QLA81XX(ha))
+               if (IS_QLA8XXX_TYPE(ha))
                        DEBUG2(printk("scsi(%ld): DCBX Completed -- %04x %04x "
                            "%04x\n", vha->host_no, mb[1], mb[2], mb[3]));
                else
@@ -845,7 +846,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
                qla2x00_sp_compl(ha, sp);
        } else {
                DEBUG2(printk("scsi(%ld) Req:%d: Invalid ISP SCSI completion"
-                       " handle(%d)\n", vha->host_no, req->id, index));
+                       " handle(0x%x)\n", vha->host_no, req->id, index));
                qla_printk(KERN_WARNING, ha,
                    "Invalid ISP SCSI completion handle\n");
 
@@ -895,36 +896,26 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
 {
        const char func[] = "MBX-IOCB";
        const char *type;
-       struct qla_hw_data *ha = vha->hw;
        fc_port_t *fcport;
        srb_t *sp;
-       struct srb_logio *lio;
-       uint16_t data[2];
+       struct srb_iocb *lio;
+       struct srb_ctx *ctx;
+       uint16_t *data;
+       uint16_t status;
 
        sp = qla2x00_get_sp_from_handle(vha, func, req, mbx);
        if (!sp)
                return;
 
-       type = NULL;
-       lio = sp->ctx;
-       switch (lio->ctx.type) {
-       case SRB_LOGIN_CMD:
-               type = "login";
-               break;
-       case SRB_LOGOUT_CMD:
-               type = "logout";
-               break;
-       default:
-               qla_printk(KERN_WARNING, ha,
-                   "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
-                   lio->ctx.type);
-               return;
-       }
-
-       del_timer(&lio->ctx.timer);
+       ctx = sp->ctx;
+       lio = ctx->u.iocb_cmd;
+       type = ctx->name;
        fcport = sp->fcport;
+       data = lio->u.logio.data;
 
-       data[0] = data[1] = 0;
+       data[0] = MBS_COMMAND_ERROR;
+       data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ?
+           QLA_LOGIO_LOGIN_RETRIED : 0;
        if (mbx->entry_status) {
                DEBUG2(printk(KERN_WARNING
                    "scsi(%ld:%x): Async-%s error entry - entry-status=%x "
@@ -935,23 +926,28 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
                    le16_to_cpu(mbx->status_flags)));
                DEBUG2(qla2x00_dump_buffer((uint8_t *)mbx, sizeof(*mbx)));
 
-               data[0] = MBS_COMMAND_ERROR;
-               data[1] = lio->flags & SRB_LOGIN_RETRIED ?
-                   QLA_LOGIO_LOGIN_RETRIED: 0;
-               goto done_post_logio_done_work;
+               goto logio_done;
        }
 
-       if (!mbx->status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
+       status = le16_to_cpu(mbx->status);
+       if (status == 0x30 && ctx->type == SRB_LOGIN_CMD &&
+           le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE)
+               status = 0;
+       if (!status && le16_to_cpu(mbx->mb0) == MBS_COMMAND_COMPLETE) {
                DEBUG2(printk(KERN_DEBUG
                    "scsi(%ld:%x): Async-%s complete - mbx1=%x.\n",
                    fcport->vha->host_no, sp->handle, type,
                    le16_to_cpu(mbx->mb1)));
 
                data[0] = MBS_COMMAND_COMPLETE;
-               if (lio->ctx.type == SRB_LOGIN_CMD && le16_to_cpu(mbx->mb1) & BIT_1)
-                       fcport->flags |= FCF_FCP2_DEVICE;
-
-               goto done_post_logio_done_work;
+               if (ctx->type == SRB_LOGIN_CMD) {
+                       fcport->port_type = FCT_TARGET;
+                       if (le16_to_cpu(mbx->mb1) & BIT_0)
+                               fcport->port_type = FCT_INITIATOR;
+                       if (le16_to_cpu(mbx->mb1) & BIT_1)
+                               fcport->flags |= FCF_FCP2_DEVICE;
+               }
+               goto logio_done;
        }
 
        data[0] = le16_to_cpu(mbx->mb0);
@@ -963,25 +959,19 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
                break;
        default:
                data[0] = MBS_COMMAND_ERROR;
-               data[1] = lio->flags & SRB_LOGIN_RETRIED ?
-                   QLA_LOGIO_LOGIN_RETRIED: 0;
                break;
        }
 
        DEBUG2(printk(KERN_WARNING
            "scsi(%ld:%x): Async-%s failed - status=%x mb0=%x mb1=%x mb2=%x "
            "mb6=%x mb7=%x.\n",
-           fcport->vha->host_no, sp->handle, type, le16_to_cpu(mbx->status),
+           fcport->vha->host_no, sp->handle, type, status,
            le16_to_cpu(mbx->mb0), le16_to_cpu(mbx->mb1),
            le16_to_cpu(mbx->mb2), le16_to_cpu(mbx->mb6),
            le16_to_cpu(mbx->mb7)));
 
-done_post_logio_done_work:
-       lio->ctx.type == SRB_LOGIN_CMD ?
-           qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
-           qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
-
-       lio->ctx.free(sp);
+logio_done:
+       lio->done(sp);
 }
 
 static void
@@ -992,7 +982,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
        const char *type;
        struct qla_hw_data *ha = vha->hw;
        srb_t *sp;
-       struct srb_bsg *sp_bsg;
+       struct srb_ctx *sp_bsg;
        struct fc_bsg_job *bsg_job;
        uint16_t comp_status;
        uint32_t fw_status[3];
@@ -1001,11 +991,11 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
        sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
        if (!sp)
                return;
-       sp_bsg = (struct srb_bsg*)sp->ctx;
-       bsg_job = sp_bsg->bsg_job;
+       sp_bsg = sp->ctx;
+       bsg_job = sp_bsg->u.bsg_job;
 
        type = NULL;
-       switch (sp_bsg->ctx.type) {
+       switch (sp_bsg->type) {
        case SRB_ELS_CMD_RPT:
        case SRB_ELS_CMD_HST:
                type = "els";
@@ -1016,7 +1006,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
        default:
                qla_printk(KERN_WARNING, ha,
                    "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
-                   sp_bsg->ctx.type);
+                   sp_bsg->type);
                return;
        }
 
@@ -1070,8 +1060,8 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
        dma_unmap_sg(&ha->pdev->dev,
            bsg_job->reply_payload.sg_list,
            bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
-       if ((sp_bsg->ctx.type == SRB_ELS_CMD_HST) ||
-           (sp_bsg->ctx.type == SRB_CT_CMD))
+       if ((sp_bsg->type == SRB_ELS_CMD_HST) ||
+           (sp_bsg->type == SRB_CT_CMD))
                kfree(sp->fcport);
        kfree(sp->ctx);
        mempool_free(sp, ha->srb_mempool);
@@ -1084,37 +1074,26 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
 {
        const char func[] = "LOGIO-IOCB";
        const char *type;
-       struct qla_hw_data *ha = vha->hw;
        fc_port_t *fcport;
        srb_t *sp;
-       struct srb_logio *lio;
-       uint16_t data[2];
+       struct srb_iocb *lio;
+       struct srb_ctx *ctx;
+       uint16_t *data;
        uint32_t iop[2];
 
        sp = qla2x00_get_sp_from_handle(vha, func, req, logio);
        if (!sp)
                return;
 
-       type = NULL;
-       lio = sp->ctx;
-       switch (lio->ctx.type) {
-       case SRB_LOGIN_CMD:
-               type = "login";
-               break;
-       case SRB_LOGOUT_CMD:
-               type = "logout";
-               break;
-       default:
-               qla_printk(KERN_WARNING, ha,
-                   "%s: Unrecognized SRB: (%p) type=%d.\n", func, sp,
-                   lio->ctx.type);
-               return;
-       }
-
-       del_timer(&lio->ctx.timer);
+       ctx = sp->ctx;
+       lio = ctx->u.iocb_cmd;
+       type = ctx->name;
        fcport = sp->fcport;
+       data = lio->u.logio.data;
 
-       data[0] = data[1] = 0;
+       data[0] = MBS_COMMAND_ERROR;
+       data[1] = lio->u.logio.flags & SRB_LOGIN_RETRIED ?
+               QLA_LOGIO_LOGIN_RETRIED : 0;
        if (logio->entry_status) {
                DEBUG2(printk(KERN_WARNING
                    "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n",
@@ -1122,10 +1101,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
                    logio->entry_status));
                DEBUG2(qla2x00_dump_buffer((uint8_t *)logio, sizeof(*logio)));
 
-               data[0] = MBS_COMMAND_ERROR;
-               data[1] = lio->flags & SRB_LOGIN_RETRIED ?
-                   QLA_LOGIO_LOGIN_RETRIED: 0;
-               goto done_post_logio_done_work;
+               goto logio_done;
        }
 
        if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) {
@@ -1135,8 +1111,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
                    le32_to_cpu(logio->io_parameter[0])));
 
                data[0] = MBS_COMMAND_COMPLETE;
-               if (lio->ctx.type == SRB_LOGOUT_CMD)
-                       goto done_post_logio_done_work;
+               if (ctx->type != SRB_LOGIN_CMD)
+                       goto logio_done;
 
                iop[0] = le32_to_cpu(logio->io_parameter[0]);
                if (iop[0] & BIT_4) {
@@ -1151,7 +1127,7 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
                if (logio->io_parameter[9] || logio->io_parameter[10])
                        fcport->supported_classes |= FC_COS_CLASS3;
 
-               goto done_post_logio_done_work;
+               goto logio_done;
        }
 
        iop[0] = le32_to_cpu(logio->io_parameter[0]);
@@ -1172,8 +1148,6 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
                /* Fall through. */
        default:
                data[0] = MBS_COMMAND_ERROR;
-               data[1] = lio->flags & SRB_LOGIN_RETRIED ?
-                   QLA_LOGIO_LOGIN_RETRIED: 0;
                break;
        }
 
@@ -1184,12 +1158,101 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
            le32_to_cpu(logio->io_parameter[0]),
            le32_to_cpu(logio->io_parameter[1])));
 
-done_post_logio_done_work:
-       lio->ctx.type == SRB_LOGIN_CMD ?
-           qla2x00_post_async_login_done_work(fcport->vha, fcport, data):
-           qla2x00_post_async_logout_done_work(fcport->vha, fcport, data);
+logio_done:
+       lio->done(sp);
+}
 
-       lio->ctx.free(sp);
+static void
+qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
+    struct tsk_mgmt_entry *tsk)
+{
+       const char func[] = "TMF-IOCB";
+       const char *type;
+       fc_port_t *fcport;
+       srb_t *sp;
+       struct srb_iocb *iocb;
+       struct srb_ctx *ctx;
+       struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk;
+       int error = 1;
+
+       sp = qla2x00_get_sp_from_handle(vha, func, req, tsk);
+       if (!sp)
+               return;
+
+       ctx = sp->ctx;
+       iocb = ctx->u.iocb_cmd;
+       type = ctx->name;
+       fcport = sp->fcport;
+
+       if (sts->entry_status) {
+               DEBUG2(printk(KERN_WARNING
+                   "scsi(%ld:%x): Async-%s error - entry-status(%x).\n",
+                   fcport->vha->host_no, sp->handle, type,
+                   sts->entry_status));
+       } else if (sts->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) {
+               DEBUG2(printk(KERN_WARNING
+                   "scsi(%ld:%x): Async-%s error - completion status(%x).\n",
+                   fcport->vha->host_no, sp->handle, type,
+                   sts->comp_status));
+       } else if (!(le16_to_cpu(sts->scsi_status) &
+           SS_RESPONSE_INFO_LEN_VALID)) {
+               DEBUG2(printk(KERN_WARNING
+                   "scsi(%ld:%x): Async-%s error - no response info(%x).\n",
+                   fcport->vha->host_no, sp->handle, type,
+                   sts->scsi_status));
+       } else if (le32_to_cpu(sts->rsp_data_len) < 4) {
+               DEBUG2(printk(KERN_WARNING
+                   "scsi(%ld:%x): Async-%s error - not enough response(%d).\n",
+                   fcport->vha->host_no, sp->handle, type,
+                   sts->rsp_data_len));
+       } else if (sts->data[3]) {
+               DEBUG2(printk(KERN_WARNING
+                   "scsi(%ld:%x): Async-%s error - response(%x).\n",
+                   fcport->vha->host_no, sp->handle, type,
+                   sts->data[3]));
+       } else {
+               error = 0;
+       }
+
+       if (error) {
+               iocb->u.tmf.data = error;
+               DEBUG2(qla2x00_dump_buffer((uint8_t *)sts, sizeof(*sts)));
+       }
+
+       iocb->done(sp);
+}
+
+static void
+qla24xx_marker_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
+    struct mrk_entry_24xx *mrk)
+{
+       const char func[] = "MRK-IOCB";
+       const char *type;
+       fc_port_t *fcport;
+       srb_t *sp;
+       struct srb_iocb *iocb;
+       struct srb_ctx *ctx;
+       struct sts_entry_24xx *sts = (struct sts_entry_24xx *)mrk;
+
+       sp = qla2x00_get_sp_from_handle(vha, func, req, mrk);
+       if (!sp)
+               return;
+
+       ctx = sp->ctx;
+       iocb = ctx->u.iocb_cmd;
+       type = ctx->name;
+       fcport = sp->fcport;
+
+       if (sts->entry_status) {
+               iocb->u.marker.data = 1;
+               DEBUG2(printk(KERN_WARNING
+                   "scsi(%ld:%x): Async-%s error entry - entry-status=%x.\n",
+                   fcport->vha->host_no, sp->handle, type,
+                   sts->entry_status));
+               DEBUG2(qla2x00_dump_buffer((uint8_t *)mrk, sizeof(*sts)));
+       }
+
+       iocb->done(sp);
 }
 
 /**
@@ -1256,6 +1319,7 @@ qla2x00_process_response_queue(struct rsp_que *rsp)
                case MBX_IOCB_TYPE:
                        qla2x00_mbx_iocb_entry(vha, rsp->req,
                            (struct mbx_entry *)pkt);
+                       break;
                default:
                        /* Type Not Supported. */
                        DEBUG4(printk(KERN_WARNING
@@ -1301,6 +1365,78 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len,
                DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, sense_len));
 }
 
+struct scsi_dif_tuple {
+       __be16 guard;       /* Checksum */
+       __be16 app_tag;         /* APPL identifer */
+       __be32 ref_tag;         /* Target LBA or indirect LBA */
+};
+
+/*
+ * Checks the guard or meta-data for the type of error
+ * detected by the HBA. In case of errors, we set the
+ * ASC/ASCQ fields in the sense buffer with ILLEGAL_REQUEST
+ * to indicate to the kernel that the HBA detected error.
+ */
+static inline void
+qla2x00_handle_dif_error(srb_t *sp, struct sts_entry_24xx *sts24)
+{
+       struct scsi_cmnd *cmd = sp->cmd;
+       struct scsi_dif_tuple   *ep =
+                       (struct scsi_dif_tuple *)&sts24->data[20];
+       struct scsi_dif_tuple   *ap =
+                       (struct scsi_dif_tuple *)&sts24->data[12];
+       uint32_t        e_ref_tag, a_ref_tag;
+       uint16_t        e_app_tag, a_app_tag;
+       uint16_t        e_guard, a_guard;
+
+       e_ref_tag = be32_to_cpu(ep->ref_tag);
+       a_ref_tag = be32_to_cpu(ap->ref_tag);
+       e_app_tag = be16_to_cpu(ep->app_tag);
+       a_app_tag = be16_to_cpu(ap->app_tag);
+       e_guard = be16_to_cpu(ep->guard);
+       a_guard = be16_to_cpu(ap->guard);
+
+       DEBUG18(printk(KERN_DEBUG
+           "%s(): iocb(s) %p Returned STATUS\n", __func__, sts24));
+
+       DEBUG18(printk(KERN_ERR "DIF ERROR in cmd 0x%x lba 0x%llx act ref"
+           " tag=0x%x, exp ref_tag=0x%x, act app tag=0x%x, exp app"
+           " tag=0x%x, act guard=0x%x, exp guard=0x%x\n",
+           cmd->cmnd[0], (u64)scsi_get_lba(cmd), a_ref_tag, e_ref_tag,
+           a_app_tag, e_app_tag, a_guard, e_guard));
+
+
+       /* check guard */
+       if (e_guard != a_guard) {
+               scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
+                   0x10, 0x1);
+               set_driver_byte(cmd, DRIVER_SENSE);
+               set_host_byte(cmd, DID_ABORT);
+               cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
+               return;
+       }
+
+       /* check appl tag */
+       if (e_app_tag != a_app_tag) {
+               scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
+                   0x10, 0x2);
+               set_driver_byte(cmd, DRIVER_SENSE);
+               set_host_byte(cmd, DID_ABORT);
+               cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
+               return;
+       }
+
+       /* check ref tag */
+       if (e_ref_tag != a_ref_tag) {
+               scsi_build_sense_buffer(1, cmd->sense_buffer, ILLEGAL_REQUEST,
+                   0x10, 0x3);
+               set_driver_byte(cmd, DRIVER_SENSE);
+               set_host_byte(cmd, DID_ABORT);
+               cmd->result |= SAM_STAT_CHECK_CONDITION << 1;
+               return;
+       }
+}
+
 /**
  * qla2x00_status_entry() - Process a Status IOCB entry.
  * @ha: SCSI driver HA context
@@ -1316,6 +1452,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
        struct sts_entry_24xx *sts24;
        uint16_t        comp_status;
        uint16_t        scsi_status;
+       uint16_t        ox_id;
        uint8_t         lscsi_status;
        int32_t         resid;
        uint32_t        sense_len, rsp_info_len, resid_len, fw_resid_len;
@@ -1324,6 +1461,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
        uint32_t handle;
        uint16_t que;
        struct req_que *req;
+       int logit = 1;
 
        sts = (sts_entry_t *) pkt;
        sts24 = (struct sts_entry_24xx *) pkt;
@@ -1337,6 +1475,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
        handle = (uint32_t) LSW(sts->handle);
        que = MSW(sts->handle);
        req = ha->req_q_map[que];
+
        /* Fast path completion. */
        if (comp_status == CS_COMPLETE && scsi_status == 0) {
                qla2x00_process_completed_request(vha, req, handle);
@@ -1352,9 +1491,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                sp = NULL;
 
        if (sp == NULL) {
-               DEBUG2(printk("scsi(%ld): Status Entry invalid handle.\n",
-                   vha->host_no));
-               qla_printk(KERN_WARNING, ha, "Status Entry invalid handle.\n");
+               qla_printk(KERN_WARNING, ha,
+                   "scsi(%ld): Invalid status handle (0x%x).\n", vha->host_no,
+                   sts->handle);
 
                set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
                qla2xxx_wake_dpc(vha);
@@ -1362,10 +1501,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
        }
        cp = sp->cmd;
        if (cp == NULL) {
-               DEBUG2(printk("scsi(%ld): Command already returned back to OS "
-                   "pkt->handle=%d sp=%p.\n", vha->host_no, handle, sp));
                qla_printk(KERN_WARNING, ha,
-                   "Command is NULL: already returned to OS (sp=%p)\n", sp);
+                   "scsi(%ld): Command already returned (0x%x/%p).\n",
+                   vha->host_no, sts->handle, sp);
 
                return;
        }
@@ -1374,6 +1512,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
 
        fcport = sp->fcport;
 
+       ox_id = 0;
        sense_len = rsp_info_len = resid_len = fw_resid_len = 0;
        if (IS_FWI2_CAPABLE(ha)) {
                if (scsi_status & SS_SENSE_LEN_VALID)
@@ -1387,6 +1526,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                rsp_info = sts24->data;
                sense_data = sts24->data;
                host_to_fcp_swap(sts24->data, sizeof(sts24->data));
+               ox_id = le16_to_cpu(sts24->ox_id);
        } else {
                if (scsi_status & SS_SENSE_LEN_VALID)
                        sense_len = le16_to_cpu(sts->req_sense_length);
@@ -1403,17 +1543,13 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                if (IS_FWI2_CAPABLE(ha))
                        sense_data += rsp_info_len;
                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", 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]));
+                       DEBUG2(qla_printk(KERN_INFO, ha,
+                           "scsi(%ld:%d:%d): FCP I/O protocol failure "
+                           "(0x%x/0x%x).\n", vha->host_no, cp->device->id,
+                           cp->device->lun, rsp_info_len, rsp_info[3]));
 
                        cp->result = DID_BUS_BUSY << 16;
-                       qla2x00_sp_compl(ha, sp);
-                       return;
+                       goto out;
                }
        }
 
@@ -1440,12 +1576,10 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                            ((unsigned)(scsi_bufflen(cp) - resid) <
                             cp->underflow)) {
                                qla_printk(KERN_INFO, ha,
-                                          "scsi(%ld:%d:%d:%d): Mid-layer underflow "
-                                          "detected (%x of %x bytes)...returning "
-                                          "error status.\n", vha->host_no,
-                                          cp->device->channel, cp->device->id,
-                                          cp->device->lun, resid,
-                                          scsi_bufflen(cp));
+                                   "scsi(%ld:%d:%d): Mid-layer underflow "
+                                   "detected (0x%x of 0x%x bytes).\n",
+                                   vha->host_no, cp->device->id,
+                                   cp->device->lun, resid, scsi_bufflen(cp));
 
                                cp->result = DID_ERROR << 16;
                                break;
@@ -1454,12 +1588,12 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                cp->result = DID_OK << 16 | lscsi_status;
 
                if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
-                       DEBUG2(printk(KERN_INFO
-                           "scsi(%ld): QUEUE FULL status detected "
-                           "0x%x-0x%x.\n", vha->host_no, comp_status,
-                           scsi_status));
+                       DEBUG2(qla_printk(KERN_INFO, ha,
+                           "scsi(%ld:%d:%d) QUEUE FULL detected.\n",
+                           vha->host_no, cp->device->id, cp->device->lun));
                        break;
                }
+               logit = 0;
                if (lscsi_status != SS_CHECK_CONDITION)
                        break;
 
@@ -1471,23 +1605,14 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                break;
 
        case CS_DATA_UNDERRUN:
-               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",
-                   vha->host_no, cp->device->id, cp->device->lun, comp_status,
-                   scsi_status, resid_len, fw_resid_len, cp->cmnd[0],
-                   cp->underflow));
-
                /* Use F/W calculated residual length. */
                resid = IS_FWI2_CAPABLE(ha) ? fw_resid_len : resid_len;
                scsi_set_resid(cp, resid);
                if (scsi_status & SS_RESIDUAL_UNDER) {
                        if (IS_FWI2_CAPABLE(ha) && fw_resid_len != resid_len) {
-                               DEBUG2(printk(
-                                   "scsi(%ld:%d:%d:%d) Dropped frame(s) "
-                                   "detected (%x of %x bytes)...residual "
-                                   "length mismatch...retrying command.\n",
-                                   vha->host_no, cp->device->channel,
+                               DEBUG2(qla_printk(KERN_INFO, ha,
+                                   "scsi(%ld:%d:%d) Dropped frame(s) detected "
+                                   "(0x%x of 0x%x bytes).\n", vha->host_no,
                                    cp->device->id, cp->device->lun, resid,
                                    scsi_bufflen(cp)));
 
@@ -1499,21 +1624,18 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                            ((unsigned)(scsi_bufflen(cp) - resid) <
                            cp->underflow)) {
                                qla_printk(KERN_INFO, ha,
-                                   "scsi(%ld:%d:%d:%d): Mid-layer underflow "
-                                   "detected (%x of %x bytes)...returning "
-                                   "error status.\n", vha->host_no,
-                                   cp->device->channel, cp->device->id,
+                                   "scsi(%ld:%d:%d): Mid-layer underflow "
+                                   "detected (0x%x of 0x%x bytes).\n",
+                                   vha->host_no, cp->device->id,
                                    cp->device->lun, resid, scsi_bufflen(cp));
 
                                cp->result = DID_ERROR << 16;
                                break;
                        }
                } else if (!lscsi_status) {
-                       DEBUG2(printk(
-                           "scsi(%ld:%d:%d:%d) Dropped frame(s) detected "
-                           "(%x of %x bytes)...firmware reported underrun..."
-                           "retrying command.\n", vha->host_no,
-                           cp->device->channel, cp->device->id,
+                       DEBUG2(qla_printk(KERN_INFO, ha,
+                           "scsi(%ld:%d:%d) Dropped frame(s) detected (0x%x "
+                           "of 0x%x bytes).\n", vha->host_no, cp->device->id,
                            cp->device->lun, resid, scsi_bufflen(cp)));
 
                        cp->result = DID_ERROR << 16;
@@ -1521,6 +1643,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                }
 
                cp->result = DID_OK << 16 | lscsi_status;
+               logit = 0;
 
                /*
                 * Check to see if SCSI Status is non zero. If so report SCSI
@@ -1528,10 +1651,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                 */
                if (lscsi_status != 0) {
                        if (lscsi_status == SAM_STAT_TASK_SET_FULL) {
-                               DEBUG2(printk(KERN_INFO
-                                   "scsi(%ld): QUEUE FULL status detected "
-                                   "0x%x-0x%x.\n", vha->host_no, comp_status,
-                                   scsi_status));
+                               DEBUG2(qla_printk(KERN_INFO, ha,
+                                   "scsi(%ld:%d:%d) QUEUE FULL detected.\n",
+                                   vha->host_no, cp->device->id,
+                                   cp->device->lun));
+                               logit = 1;
                                break;
                        }
                        if (lscsi_status != SS_CHECK_CONDITION)
@@ -1545,109 +1669,60 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
                }
                break;
 
-       case CS_DATA_OVERRUN:
-               DEBUG2(printk(KERN_INFO
-                   "scsi(%ld:%d:%d): OVERRUN status detected 0x%x-0x%x\n",
-                   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",
-                   cp->cmnd[0], cp->cmnd[1], cp->cmnd[2], cp->cmnd[3],
-                   cp->cmnd[4], cp->cmnd[5]));
-               DEBUG2(printk(KERN_INFO
-                   "PID=0x%lx req=0x%x xtra=0x%x -- returning DID_ERROR "
-                   "status!\n",
-                   cp->serial_number, scsi_bufflen(cp), resid_len));
-
-               cp->result = DID_ERROR << 16;
-               break;
-
        case CS_PORT_LOGGED_OUT:
        case CS_PORT_CONFIG_CHG:
        case CS_PORT_BUSY:
        case CS_INCOMPLETE:
        case CS_PORT_UNAVAILABLE:
-               /*
-                * If the port is in Target Down state, return all IOs for this
-                * Target with DID_NO_CONNECT ELSE Queue the IOs in the
-                * retry_queue.
-                */
-               DEBUG2(printk("scsi(%ld:%d:%d): status_entry: Port Down "
-                   "pid=%ld, compl status=0x%x, port state=0x%x\n",
-                   vha->host_no, cp->device->id, cp->device->lun,
-                   cp->serial_number, comp_status,
-                   atomic_read(&fcport->state)));
-
+       case CS_TIMEOUT:
                /*
                 * 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 (comp_status == CS_TIMEOUT) {
+                       if (IS_FWI2_CAPABLE(ha))
+                               break;
+                       else if ((le16_to_cpu(sts->status_flags) &
+                           SF_LOGOUT_SENT) == 0)
+                               break;
+               }
+
+               DEBUG2(qla_printk(KERN_INFO, ha,
+                       "scsi(%ld:%d:%d) Port down status: port-state=0x%x\n",
+                       vha->host_no, cp->device->id, cp->device->lun,
+                       atomic_read(&fcport->state)));
+
                if (atomic_read(&fcport->state) == FCS_ONLINE)
                        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",
-                   vha->host_no, comp_status, scsi_status));
-
-               cp->result = DID_RESET << 16;
-               break;
-
        case CS_ABORTED:
-               /*
-                * hv2.19.12 - DID_ABORT does not retry the request if we
-                * aborted this request then abort otherwise it must be a
-                * reset.
-                */
-               DEBUG2(printk(KERN_INFO
-                   "scsi(%ld): ABORT status detected 0x%x-0x%x.\n",
-                   vha->host_no, comp_status, scsi_status));
-
                cp->result = DID_RESET << 16;
                break;
 
-       case CS_TIMEOUT:
-               /*
-                * 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", 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", 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->vha, fcport, 1, 1);
+       case CS_DIF_ERROR:
+               qla2x00_handle_dif_error(sp, sts24);
                break;
-
        default:
-               DEBUG3(printk("scsi(%ld): Error detected (unknown 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);
-
                cp->result = DID_ERROR << 16;
                break;
        }
 
-       /* Place command on done queue. */
+out:
+       if (logit)
+               DEBUG2(qla_printk(KERN_INFO, ha,
+                   "scsi(%ld:%d:%d) FCP command status: 0x%x-0x%x (0x%x) "
+                   "oxid=0x%x ser=0x%lx cdb=%02x%02x%02x len=0x%x "
+                   "rsp_info=0x%x resid=0x%x fw_resid=0x%x\n", vha->host_no,
+                   cp->device->id, cp->device->lun, comp_status, scsi_status,
+                   cp->result, ox_id, cp->serial_number, cp->cmnd[0],
+                   cp->cmnd[1], cp->cmnd[2], scsi_bufflen(cp), rsp_info_len,
+                   resid_len, fw_resid_len));
+
        if (rsp->status_srb == NULL)
                qla2x00_sp_compl(ha, sp);
 }
@@ -1806,6 +1881,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
        struct rsp_que *rsp)
 {
        struct sts_entry_24xx *pkt;
+       struct qla_hw_data *ha = vha->hw;
 
        if (!vha->flags.online)
                return;
@@ -1846,6 +1922,14 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
                        qla24xx_logio_entry(vha, rsp->req,
                            (struct logio_entry_24xx *)pkt);
                        break;
+               case TSK_MGMT_IOCB_TYPE:
+                       qla24xx_tm_iocb_entry(vha, rsp->req,
+                           (struct tsk_mgmt_entry *)pkt);
+                       break;
+               case MARKER_TYPE:
+                       qla24xx_marker_iocb_entry(vha, rsp->req,
+                           (struct mrk_entry_24xx *)pkt);
+                       break;
                 case CT_IOCB_TYPE:
                        qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
                        clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags);
@@ -1866,7 +1950,11 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
        }
 
        /* Adjust ring index */
-       WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
+       if (IS_QLA82XX(ha)) {
+               struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;
+               WRT_REG_DWORD(&reg->rsp_q_out[0], rsp->ring_index);
+       } else
+               WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
 }
 
 static void
@@ -2169,6 +2257,11 @@ static struct qla_init_msix_entry msix_entries[3] = {
        { "qla2xxx (multiq)", qla25xx_msix_rsp_q },
 };
 
+static struct qla_init_msix_entry qla82xx_msix_entries[2] = {
+       { "qla2xxx (default)", qla82xx_msix_default },
+       { "qla2xxx (rsp_q)", qla82xx_msix_rsp_q },
+};
+
 static void
 qla24xx_disable_msix(struct qla_hw_data *ha)
 {
@@ -2195,7 +2288,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
        struct qla_msix_entry *qentry;
 
        entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count,
-                                       GFP_KERNEL);
+                       GFP_KERNEL);
        if (!entries)
                return -ENOMEM;
 
@@ -2240,8 +2333,15 @@ msix_failed:
        /* Enable MSI-X vectors for the base queue */
        for (i = 0; i < 2; i++) {
                qentry = &ha->msix_entries[i];
-               ret = request_irq(qentry->vector, msix_entries[i].handler,
-                                       0, msix_entries[i].name, rsp);
+               if (IS_QLA82XX(ha)) {
+                       ret = request_irq(qentry->vector,
+                               qla82xx_msix_entries[i].handler,
+                               0, qla82xx_msix_entries[i].name, rsp);
+               } else {
+                       ret = request_irq(qentry->vector,
+                               msix_entries[i].handler,
+                               0, msix_entries[i].name, rsp);
+               }
                if (ret) {
                        qla_printk(KERN_WARNING, ha,
                        "MSI-X: Unable to register handler -- %x/%d.\n",
@@ -2272,7 +2372,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
 
        /* If possible, enable MSI-X. */
        if (!IS_QLA2432(ha) && !IS_QLA2532(ha) &&
-               !IS_QLA8432(ha) && !IS_QLA8001(ha))
+               !IS_QLA8432(ha) && !IS_QLA8XXX_TYPE(ha))
                goto skip_msi;
 
        if (ha->pdev->subsystem_vendor == PCI_VENDOR_ID_HP &&
@@ -2302,7 +2402,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp)
                goto clear_risc_ints;
        }
        qla_printk(KERN_WARNING, ha,
-           "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
+           "MSI-X: Falling back-to MSI mode -- %d.\n", ret);
 skip_msix:
 
        if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) &&
@@ -2313,7 +2413,9 @@ skip_msix:
        if (!ret) {
                DEBUG2(qla_printk(KERN_INFO, ha, "MSI: Enabled.\n"));
                ha->flags.msi_enabled = 1;
-       }
+       } else
+               qla_printk(KERN_WARNING, ha,
+                   "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
 skip_msi:
 
        ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
@@ -2331,7 +2433,7 @@ clear_risc_ints:
         * FIXME: Noted that 8014s were being dropped during NK testing.
         * Timing deltas during MSI-X/INTa transitions?
         */
-       if (IS_QLA81XX(ha))
+       if (IS_QLA81XX(ha) || IS_QLA82XX(ha))
                goto fail;
        spin_lock_irq(&ha->hardware_lock);
        if (IS_FWI2_CAPABLE(ha)) {