⬢ DragonFlyBSD Kernel Audit
DF-4351 / fix.diff
← back to finding ↓ download raw
--- 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;