DF-4351 / fix.diff
--- a/sys/dev/disk/advansys/advansys.c +++ b/sys/dev/disk/advansys/advansys.c @@ -1089,9 +1089,15 @@ #endif adv->cur_active -= sg_queue_cnt + 1; + /* + * DF-4351: q_status is a device-written byte. Do not + * panic the kernel on hostile or corrupt LRAM status. + */ if ((scsiq.q_status != QS_DONE) && (scsiq.q_status & QS_ABORTED) == 0) - panic("adv_qdone: completed scsiq with unknown status"); + kprintf("%s: done queue entry %d has unknown status " + "0x%x, completing with error\n", adv_name(adv), + done_qno, scsiq.q_status); scsiq.remain_bytes += scsiq.extra_bytes; @@ -1233,9 +1239,17 @@ case QHSTA_D_LRAM_CMP_ERROR: case QHSTA_M_MICRO_CODE_ERROR_HALT: default: - panic("%s: Unhandled Host status error %x", - adv_name(adv), host_stat); - /* NOTREACHED */ + /* + * DF-4351: the RISC ABI defines codes this switch + * does not handle (and two it only enumerates in + * order to panic). Fail the transaction instead + * of taking the system down. + */ + xpt_print_path(ccb->ccb_h.path); + kprintf("adv_done - unhandled host status error %x\n", + host_stat); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + break; } break; |