VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / scsi / qla2xxx / qla_isr.c
index 382a4fe..f9284fd 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,29 +154,9 @@ 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);
@@ -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)
@@ -692,7 +686,7 @@ qla2x00_process_completed_request(struct scsi_qla_host *ha, uint32_t index)
        sp = ha->outstanding_cmds[index];
        if (sp) {
                /* Free outstanding command slot. */
-               ha->outstanding_cmds[index] = 0;
+               ha->outstanding_cmds[index] = NULL;
 
                if (ha->actthreads)
                        ha->actthreads--;
@@ -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;
 
@@ -842,7 +836,7 @@ qla2x00_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
        /* Validate handle. */
        if (pkt->handle < MAX_OUTSTANDING_COMMANDS) {
                sp = ha->outstanding_cmds[pkt->handle];
-               ha->outstanding_cmds[pkt->handle] = 0;
+               ha->outstanding_cmds[pkt->handle] = NULL;
        } else
                sp = NULL;
 
@@ -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;
@@ -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 
@@ -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,
@@ -1319,7 +1320,7 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
 
        if (sp) {
                /* Free outstanding command slot. */
-               ha->outstanding_cmds[pkt->handle] = 0;
+               ha->outstanding_cmds[pkt->handle] = NULL;
                if (ha->actthreads)
                        ha->actthreads--;
                sp->lun_queue->out_cnt--;
@@ -1382,7 +1383,7 @@ qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
        CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
 
        /* Free outstanding command slot. */
-       ha->outstanding_cmds[pkt->handle1] = 0;
+       ha->outstanding_cmds[pkt->handle1] = NULL;
 
        add_to_done_queue(ha, sp);
 }