This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / scsi / qla2xxx / qla_isr.c
index 415242a..1458404 100644 (file)
@@ -16,9 +16,6 @@
  * General Public License for more details.
  *
  */
-
-#include "qla_os.h"
-
 #include "qla_def.h"
 
 static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t);
@@ -109,7 +106,25 @@ qla2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
                        }
                } else /* IS_QLA23XX(ha) */ {
                        stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
-                       if ((stat & HSR_RISC_INT) == 0)
+                       if (stat & HSR_RISC_PAUSED) {
+                               hccr = RD_REG_WORD(&reg->hccr);
+                               if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8))
+                                       qla_printk(KERN_INFO, ha,
+                                           "Parity error -- HCCR=%x.\n", hccr);
+                               else
+                                       qla_printk(KERN_INFO, ha,
+                                           "RISC paused -- HCCR=%x\n", hccr);
+
+                               /*
+                                * Issue a "HARD" reset in order for the RISC
+                                * interrupt bit to be cleared.  Schedule a big
+                                * hammmer to get out of the RISC PAUSED state.
+                                */
+                               WRT_REG_WORD(&reg->hccr, HCCR_RESET_RISC);
+                               RD_REG_WORD(&reg->hccr);
+                               set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+                               break;
+                       } else if ((stat & HSR_RISC_INT) == 0)
                                break;
 
                        mbx = MSW(stat);
@@ -139,33 +154,13 @@ qla2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
                                qla2x00_async_event(ha, mbx);
                                break;
                        default:
-                               hccr = RD_REG_WORD(&reg->hccr);
-                               if (hccr & HCCR_RISC_PAUSE) {
-                                       qla_printk(KERN_INFO, ha,
-                                           "RISC paused, dumping HCCR=%x\n",
-                                           hccr);
-
-                                       /*
-                                        * Issue a "HARD" reset in order for
-                                        * the RISC interrupt bit to be
-                                        * cleared.  Schedule a big hammmer to
-                                        * get out of the RISC PAUSED state.
-                                        */
-                                       WRT_REG_WORD(&reg->hccr,
-                                           HCCR_RESET_RISC);
-                                       RD_REG_WORD(&reg->hccr);
-                                       set_bit(ISP_ABORT_NEEDED,
-                                           &ha->dpc_flags);
-                                       break;
-                               } else {
-                                       DEBUG2(printk("scsi(%ld): Unrecognized "
-                                           "interrupt type (%d)\n",
-                                           ha->host_no, stat & 0xff));
-                               }
+                               DEBUG2(printk("scsi(%ld): Unrecognized "
+                                   "interrupt type (%d)\n",
+                                   ha->host_no, stat & 0xff));
                                break;
                        }
                        WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
-                       RD_REG_WORD(&reg->hccr);
+                       RD_REG_WORD_RELAXED(&reg->hccr);
                }
        }
 
@@ -235,7 +230,7 @@ qla2x00_mbx_completion(scsi_qla_host_t *ha, uint16_t mb0)
        device_reg_t    *reg = ha->iobase;
 
        /* Load return mailbox registers. */
-       ha->flags.mbox_int = TRUE;
+       ha->flags.mbox_int = 1;
        ha->mailbox_out[0] = mb0;
        wptr = (uint16_t *)MAILBOX_REG(ha, reg, 1);
 
@@ -344,7 +339,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
                break;
        }
 
-       mb[0] = LSW(mbx);
        switch (mb[0]) {
        case MBA_SCSI_COMPLETION:       /* Fast Post */
                if (!ha->flags.online)
@@ -827,7 +821,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
        uint16_t        comp_status;
        uint16_t        scsi_status;
        uint8_t         lscsi_status;
-       uint32_t        resid;
+       int32_t         resid;
        uint8_t         sense_sz = 0;
        uint16_t        rsp_info_len;
 
@@ -907,7 +901,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
         * If loop is in transient state Report DID_BUS_BUSY
         */
        if ((comp_status != CS_COMPLETE || scsi_status != 0)) {
-               if (!(sp->flags & SRB_IOCTL) &&
+               if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
                    (atomic_read(&ha->loop_down_timer) ||
                        atomic_read(&ha->loop_state) != LOOP_READY)) {
 
@@ -948,6 +942,11 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
                        cp->result = DID_OK << 16;
                        break;
                }
+               if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
+                       resid = le32_to_cpu(pkt->residual_length);
+                       cp->resid = resid;
+                       CMD_RESID_LEN(cp) = resid;
+               }
                if (lscsi_status == SS_BUSY_CONDITION) {
                        cp->result = DID_BUS_BUSY << 16 | lscsi_status;
                        break;
@@ -986,7 +985,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
                if (sp->request_sense_length != 0)
                        ha->status_srb = sp;
 
-               if (!(sp->flags & SRB_IOCTL) &&
+               if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
                    qla2x00_check_sense(cp, lq) == QLA_SUCCESS) {
                        /* Throw away status_cont if any */
                        ha->status_srb = NULL;
@@ -1009,7 +1008,10 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
                    ha->host_no, t, l, comp_status, scsi_status));
 
                resid = le32_to_cpu(pkt->residual_length);
-               CMD_RESID_LEN(cp) = resid;
+               if (scsi_status & SS_RESIDUAL_UNDER) {
+                       cp->resid = resid;
+                       CMD_RESID_LEN(cp) = resid;
+               }
 
                /*
                 * Check to see if SCSI Status is non zero. If so report SCSI 
@@ -1053,7 +1055,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
                        if (sp->request_sense_length != 0)
                                ha->status_srb = sp;
 
-                       if (!(sp->flags & SRB_IOCTL) &&
+                       if (!(sp->flags & (SRB_IOCTL | SRB_TAPE)) &&
                            (qla2x00_check_sense(cp, lq) == QLA_SUCCESS)) {
                                ha->status_srb = NULL;
                                add_to_scsi_retry_queue(ha, sp);
@@ -1085,7 +1087,6 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
                        }
 
                        /* Handle mid-layer underflow */
-                       cp->resid = resid;
                        if ((unsigned)(cp->request_bufflen - resid) <
                            cp->underflow) {
                                qla_printk(KERN_INFO, ha,
@@ -1137,7 +1138,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
                    ha->host_no, t, l, cp->serial_number, comp_status,
                    atomic_read(&fcport->state)));
 
-               if ((sp->flags & SRB_IOCTL) ||
+               if ((sp->flags & (SRB_IOCTL | SRB_TAPE)) ||
                    atomic_read(&fcport->state) == FCS_DEVICE_DEAD) {
                        cp->result = DID_NO_CONNECT << 16;
                        if (atomic_read(&ha->loop_state) == LOOP_DOWN) 
@@ -1162,7 +1163,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
                    "scsi(%ld): RESET status detected 0x%x-0x%x.\n",
                    ha->host_no, comp_status, scsi_status));
 
-               if (sp->flags & SRB_IOCTL) {
+               if (sp->flags & (SRB_IOCTL | SRB_TAPE)) {
                        cp->result = DID_RESET << 16;
                } else {
                        qla2x00_extend_timeout(cp, EXTEND_CMD_TIMEOUT);