Commit fc2e60a5 authored by Andrew Vasquez's avatar Andrew Vasquez Committed by James Bottomley

[PATCH] [4/18] qla2xxx: ISR RISC paused fixes

  Problem reported/corrected by Michael Reed [mdr@sgi.com]:

  We have a 2312 that puts the 8.00.00b12-k qla2xxx driver
  into an infinite loop with a solid interrupt, 0x8008,
  hcsr = 0x7430, risc status register 0x40008110,
  immediately after enabling parity on the board.

  It looks as though the early out test in
  qla_isr.c:qla2x00_intr_handler() against stat is broken.
  HSR_RISC_PAUSED is set.  Also, there's a stale mailbox
  completion flagged (stat&0xff) which will short circuit
  the default case in the switch if it got that far.
Signed-off-by: default avatarAndrew Vasquez <andrew.vasquez@qlogic.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 5be2620e
...@@ -109,7 +109,25 @@ qla2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) ...@@ -109,7 +109,25 @@ qla2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
} }
} else /* IS_QLA23XX(ha) */ { } else /* IS_QLA23XX(ha) */ {
stat = RD_REG_DWORD(&reg->u.isp2300.host_status); 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; break;
mbx = MSW(stat); mbx = MSW(stat);
...@@ -139,29 +157,9 @@ qla2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs) ...@@ -139,29 +157,9 @@ qla2x00_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
qla2x00_async_event(ha, mbx); qla2x00_async_event(ha, mbx);
break; break;
default: default:
hccr = RD_REG_WORD(&reg->hccr); DEBUG2(printk("scsi(%ld): Unrecognized "
if (hccr & HCCR_RISC_PAUSE) { "interrupt type (%d)\n",
qla_printk(KERN_INFO, ha, ha->host_no, stat & 0xff));
"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));
}
break; break;
} }
WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT); WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
...@@ -344,7 +342,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx) ...@@ -344,7 +342,6 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint32_t mbx)
break; break;
} }
mb[0] = LSW(mbx);
switch (mb[0]) { switch (mb[0]) {
case MBA_SCSI_COMPLETION: /* Fast Post */ case MBA_SCSI_COMPLETION: /* Fast Post */
if (!ha->flags.online) if (!ha->flags.online)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment