⬢ DragonFlyBSD Kernel Audit
DF-4841 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/raid/tws/tws_hdm.c
+++ b/sys/dev/raid/tws/tws_hdm.c
@@ -77,6 +77,7 @@
 void tws_enable_db_intr(struct tws_softc *sc);
 void tws_aen_synctime_with_host(struct tws_softc *sc);
 void tws_init_obfl_q(struct tws_softc *sc);
+void tws_reset_obfl_q(struct tws_softc *sc);
 void tws_display_ctlr_info(struct tws_softc *sc);
 
 int
@@ -147,6 +148,27 @@
         sc->obfl_q_overrun = false;
 }
 
+
+/*
+ * DF-4841: a controller soft reset wipes the firmware's copy of the
+ * outbound free list, but sc->sense_bufs[i].posted still says every frame
+ * is queued.  Clear the flags on the reset path BEFORE tws_init_obfl_q()
+ * re-runs, otherwise the "refill" posts nothing and the firmware is left
+ * with zero response frames (every post-reset I/O times out forever).
+ * (Do NOT clear inside tws_init_obfl_q() itself: its other caller,
+ * tws_submit_command() on OBFL overrun, must not double-post frames that
+ * are still queued.)
+ */
+void
+tws_reset_obfl_q(struct tws_softc *sc)
+{
+    int i;
+
+    TWS_TRACE_DEBUG(sc, "reset obfl q", 0, 0);
+    for ( i=0; i < tws_queue_depth; i++ )
+        sc->sense_bufs[i].posted = false;
+}
+
 int
 tws_init_connect(struct tws_softc *sc, u_int16_t mcreadits )
 {
--- a/sys/dev/raid/tws/tws_cam.c
+++ b/sys/dev/raid/tws/tws_cam.c
@@ -120,6 +120,7 @@
                     struct tws_circular_q *cq, struct tws_event_packet *aen);
 extern int tws_use_32bit_sgls;
 extern boolean tws_ctlr_reset(struct tws_softc *sc);
+extern void tws_reset_obfl_q(struct tws_softc *sc);
 extern struct tws_request * tws_q_remove_tail(struct tws_softc *sc,
                                                            u_int8_t q_type );
 extern void tws_turn_off_interrupts(struct tws_softc *sc);
@@ -1260,6 +1261,7 @@
     timeout_val=0;
     try = 2;
     sc->obfl_q_overrun = false;
+    tws_reset_obfl_q(sc);
     if ( tws_init_connect(sc, tws_queue_depth) ) {
         TWS_TRACE_DEBUG(sc, "initConnect failed", 0, sc->is64bit);
     }