DF-4364 / fix.diff
diff --git a/sys/dev/raid/mps/mps.c b/sys/dev/raid/mps/mps.c index 3333333..4444444 100644 --- a/sys/dev/raid/mps/mps.c +++ b/sys/dev/raid/mps/mps.c @@ -2150,10 +2150,21 @@ mps_request_polled(struct mps_softc *sc, struct mps_command *cm) while ((cm->cm_flags & MPS_CM_FLAGS_COMPLETE) == 0) { mps_intr_locked(sc); DELAY(50 * 1000); if (timeout++ > 1000) { mps_dprint(sc, MPS_FAULT, "polling failed\n"); + /* + * DF-4364: the request for this SMID is still + * posted to the IOC. Returning with the command + * in flight lets the mps_config.c callers + * (mps_free_command at every `out:' label) free + * it while the hardware owns it; a later reply + * then completes/confuses a reallocated command + * and corrupts the reply free queue. + * + * Mirror the mpr driver fix (mpr_wait_command, + * sys/dev/raid/mpr/mpr.c:3557): diag-reset the + * chip so the stale request can never complete, + * making the caller's free safe. + */ + mps_reinit(sc); error = ETIMEDOUT; break; } } |