* 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);
}
} else /* IS_QLA23XX(ha) */ {
stat = RD_REG_DWORD(®->u.isp2300.host_status);
- if ((stat & HSR_RISC_INT) == 0)
+ if (stat & HSR_RISC_PAUSED) {
+ hccr = RD_REG_WORD(®->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(®->hccr, HCCR_RESET_RISC);
+ RD_REG_WORD(®->hccr);
+ set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
+ break;
+ } else if ((stat & HSR_RISC_INT) == 0)
break;
mbx = MSW(stat);
qla2x00_async_event(ha, mbx);
break;
default:
- hccr = RD_REG_WORD(®->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(®->hccr,
- HCCR_RESET_RISC);
- RD_REG_WORD(®->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(®->hccr, HCCR_CLR_RISC_INT);
- RD_REG_WORD(®->hccr);
+ RD_REG_WORD_RELAXED(®->hccr);
}
}
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);
break;
}
- mb[0] = LSW(mbx);
switch (mb[0]) {
case MBA_SCSI_COMPLETION: /* Fast Post */
if (!ha->flags.online)
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;
* 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)) {
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;
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;
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
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);
}
/* Handle mid-layer underflow */
- cp->resid = resid;
if ((unsigned)(cp->request_bufflen - resid) <
cp->underflow) {
qla_printk(KERN_INFO, ha,
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)
"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);