--- a/sys/dev/raid/mps/mps.c +++ b/sys/dev/raid/mps/mps.c @@ mps_update_events @@ error = mps_request_polled(sc, cm); reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply; if ((reply == NULL) || (reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) error = ENXIO; - mps_print_event(sc, reply); + if (reply != NULL) + mps_print_event(sc, reply); mps_dprint(sc, MPS_TRACE, "%s finished error %d\n", __func__, error); @@ mps_request_polled @@ 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"); error = ETIMEDOUT; break; } } + /* + * On timeout the request is still posted to the IOC: mark the command + * so callers do not free a live request (late completion is handled by + * the interrupt path / diag-reset reinit). + */ + if (error == ETIMEDOUT) + cm->cm_flags |= MPS_CM_FLAGS_TIMEDOUT; return (error);