diff --git a/sys/dev/mpr/mpr.c b/sys/dev/mpr/mpr.c index eead6b572b0c..7b04d541d7c5 100644 --- a/sys/dev/mpr/mpr.c +++ b/sys/dev/mpr/mpr.c @@ -436,6 +436,8 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching) /* Only deallocate and reallocate if relevant IOC Facts have changed */ reallocating = FALSE; + sc->mpr_flags &= ~MPR_FLAGS_REALLOCATED; + if ((!attaching) && ((saved_facts.MsgVersion != sc->facts->MsgVersion) || (saved_facts.HeaderVersion != sc->facts->HeaderVersion) || @@ -458,6 +460,9 @@ mpr_iocfacts_allocate(struct mpr_softc *sc, uint8_t attaching) (saved_facts.MaxPersistentEntries != sc->facts->MaxPersistentEntries))) { reallocating = TRUE; + + /* Record that we reallocated everything */ + sc->mpr_flags |= MPR_FLAGS_REALLOCATED; } /* @@ -2229,8 +2234,8 @@ mpr_update_events(struct mpr_softc *sc, struct mpr_event_handle *handle, uint8_t *mask) { MPI2_EVENT_NOTIFICATION_REQUEST *evtreq; - MPI2_EVENT_NOTIFICATION_REPLY *reply; - struct mpr_command *cm; + MPI2_EVENT_NOTIFICATION_REPLY *reply = NULL; + struct mpr_command *cm = NULL; struct mpr_event_handle *eh; int error, i; @@ -2263,8 +2268,9 @@ mpr_update_events(struct mpr_softc *sc, struct mpr_event_handle *handle, cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_request_polled(sc, cm); - reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply; + error = mpr_request_polled(sc, &cm); + if (cm != NULL) + reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply; if ((reply == NULL) || (reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) error = ENXIO; @@ -2274,7 +2280,8 @@ mpr_update_events(struct mpr_softc *sc, struct mpr_event_handle *handle, mpr_dprint(sc, MPR_TRACE, "%s finished error %d\n", __func__, error); - mpr_free_command(sc, cm); + if (cm != NULL) + mpr_free_command(sc, cm); return (error); } @@ -3260,11 +3267,12 @@ mpr_map_command(struct mpr_softc *sc, struct mpr_command *cm) * be executed and enqueued automatically. Other errors come from msleep(). */ int -mpr_wait_command(struct mpr_softc *sc, struct mpr_command *cm, int timeout, +mpr_wait_command(struct mpr_softc *sc, struct mpr_command **cmp, int timeout, int sleep_flag) { int error, rc; struct timeval cur_time, start_time; + struct mpr_command *cm = *cmp; if (sc->mpr_flags & MPR_FLAGS_DIAGRESET) return EBUSY; @@ -3319,6 +3327,13 @@ mpr_wait_command(struct mpr_softc *sc, struct mpr_command *cm, int timeout, rc = mpr_reinit(sc); mpr_dprint(sc, MPR_FAULT, "Reinit %s\n", (rc == 0) ? "success" : "failed"); + if (sc->mpr_flags & MPR_FLAGS_REALLOCATED) { + /* + * Tell the caller that we freed the command in a + * reinit. + */ + *cmp = NULL; + } error = ETIMEDOUT; } return (error); @@ -3329,10 +3344,11 @@ mpr_wait_command(struct mpr_softc *sc, struct mpr_command *cm, int timeout, * completion. Its use should be rare. */ int -mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm) +mpr_request_polled(struct mpr_softc *sc, struct mpr_command **cmp) { - int error, timeout = 0, rc; + int error, rc; struct timeval cur_time, start_time; + struct mpr_command *cm = *cmp; error = 0; @@ -3340,7 +3356,7 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm) cm->cm_complete = NULL; mpr_map_command(sc, cm); - getmicrotime(&start_time); + getmicrouptime(&start_time); while ((cm->cm_flags & MPR_CM_FLAGS_COMPLETE) == 0) { mpr_intr_locked(sc); @@ -3353,9 +3369,9 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm) /* * Check for real-time timeout and fail if more than 60 seconds. */ - getmicrotime(&cur_time); - timeout = cur_time.tv_sec - start_time.tv_sec; - if (timeout > 60) { + getmicrouptime(&cur_time); + timevalsub(&cur_time, &start_time); + if (cur_time.tv_sec > 60) { mpr_dprint(sc, MPR_FAULT, "polling failed\n"); error = ETIMEDOUT; break; @@ -3367,6 +3383,14 @@ mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm) rc = mpr_reinit(sc); mpr_dprint(sc, MPR_FAULT, "Reinit %s\n", (rc == 0) ? "success" : "failed"); + + if (sc->mpr_flags & MPR_FLAGS_REALLOCATED) { + /* + * Tell the caller that we freed the command in a + * reinit. + */ + *cmp = NULL; + } } return (error); } @@ -3432,11 +3456,12 @@ mpr_read_config_page(struct mpr_softc *sc, struct mpr_config_params *params) cm->cm_complete = mpr_config_complete; return (mpr_map_command(sc, cm)); } else { - error = mpr_wait_command(sc, cm, 0, CAN_SLEEP); + error = mpr_wait_command(sc, &cm, 0, CAN_SLEEP); if (error) { mpr_dprint(sc, MPR_FAULT, "Error %d reading config page\n", error); - mpr_free_command(sc, cm); + if (cm != NULL) + mpr_free_command(sc, cm); return (error); } mpr_config_complete(sc, cm); diff --git a/sys/dev/mpr/mpr_config.c b/sys/dev/mpr/mpr_config.c index 1ae070056159..9f1ed1d0f566 100644 --- a/sys/dev/mpr/mpr_config.c +++ b/sys/dev/mpr/mpr_config.c @@ -95,8 +95,9 @@ mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->Header.PageLength = request->Header.PageVersion = 0; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -153,8 +154,9 @@ mpr_config_get_ioc_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, } cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -225,8 +227,9 @@ mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->Header.PageLength = request->Header.PageVersion = 0; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -283,8 +286,9 @@ mpr_config_get_iounit_pg8(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, } cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -393,8 +397,9 @@ mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -453,8 +458,9 @@ mpr_config_get_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, goto out; } cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -529,8 +535,9 @@ int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->PageAddress |= htole16(entry_idx); cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -591,8 +598,9 @@ int mpr_config_set_dpm_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(config_page, page, MIN(cm->cm_length, (sizeof(Mpi2DriverMappingPage0_t)))); cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -664,8 +672,9 @@ mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t request->ExtPageLength = request->Header.PageVersion = 0; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -724,8 +733,9 @@ mpr_config_get_sas_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -799,8 +809,9 @@ mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t request->ExtPageLength = request->Header.PageVersion = 0; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -859,8 +870,9 @@ mpr_config_get_pcie_device_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -934,8 +946,9 @@ mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t request->ExtPageLength = request->Header.PageVersion = 0; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -994,8 +1007,9 @@ mpr_config_get_pcie_device_pg2(struct mpr_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1066,8 +1080,9 @@ mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->Header.PageLength = request->Header.PageVersion = 0; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1124,8 +1139,9 @@ mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, } cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1173,7 +1189,7 @@ mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mpr_command *cm; Mpi2RaidVolPage0_t *page = NULL; int error = 0; @@ -1201,8 +1217,9 @@ mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mpr_request_polled(sc, cm); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_request_polled(sc, &cm); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ @@ -1258,8 +1275,9 @@ mpr_config_get_raid_volume_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mpr_request_polled(sc, cm); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_request_polled(sc, &cm); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ @@ -1325,8 +1343,9 @@ mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t request->Header.PageLength = request->Header.PageVersion = 0; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1384,8 +1403,9 @@ mpr_config_get_raid_volume_pg1(struct mpr_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1459,7 +1479,7 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mpr_command *cm; Mpi2RaidPhysDiskPage0_t *page = NULL; int error = 0; @@ -1487,8 +1507,9 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mpr_request_polled(sc, cm); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_request_polled(sc, &cm); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ @@ -1544,8 +1565,9 @@ mpr_config_get_raid_pd_pg0(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mpr_request_polled(sc, cm); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mpr_request_polled(sc, &cm); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ diff --git a/sys/dev/mpr/mpr_sas.c b/sys/dev/mpr/mpr_sas.c index e724bd43086c..bdaa4abe5819 100644 --- a/sys/dev/mpr/mpr_sas.c +++ b/sys/dev/mpr/mpr_sas.c @@ -1193,13 +1193,8 @@ mprsas_complete_all_commands(struct mpr_softc *sc) completed = 1; } - if (cm->cm_sc->io_cmds_active != 0) { + if (cm->cm_sc->io_cmds_active != 0) cm->cm_sc->io_cmds_active--; - } else { - mpr_dprint(cm->cm_sc, MPR_INFO, "Warning: " - "io_cmds_active is out of sync - resynching to " - "0\n"); - } if ((completed == 0) && (cm->cm_state != MPR_CM_STATE_FREE)) { /* this should never happen, but if it does, log */ diff --git a/sys/dev/mpr/mpr_sas_lsi.c b/sys/dev/mpr/mpr_sas_lsi.c index 5f7a4c6dd43c..2d346d56199e 100644 --- a/sys/dev/mpr/mpr_sas_lsi.c +++ b/sys/dev/mpr/mpr_sas_lsi.c @@ -324,7 +324,7 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event) { // build RAID Action message Mpi2RaidActionRequest_t *action; - Mpi2RaidActionReply_t *reply; + Mpi2RaidActionReply_t *reply = NULL; struct mpr_command *cm; int error = 0; if ((cm = mpr_alloc_command(sc)) == NULL) { @@ -344,8 +344,10 @@ mprsas_fw_work(struct mpr_softc *sc, struct mpr_fw_event_work *fw_event) action->PhysDiskNum = element->PhysDiskNum; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; - error = mpr_request_polled(sc, cm); - reply = (Mpi2RaidActionReply_t *)cm->cm_reply; + error = mpr_request_polled(sc, &cm); + if (cm != NULL) + reply = (Mpi2RaidActionReply_t *) + cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1132,12 +1134,14 @@ mprsas_get_sata_identify(struct mpr_softc *sc, u16 handle, "command\n", __func__); callout_reset(&cm->cm_callout, MPR_ATA_ID_TIMEOUT * hz, mprsas_ata_id_timeout, cm); - error = mpr_wait_command(sc, cm, 60, CAN_SLEEP); + error = mpr_wait_command(sc, &cm, 60, CAN_SLEEP); mpr_dprint(sc, MPR_XINFO, "%s stop timeout counter for SATA ID " "command\n", __func__); + /* XXX KDM need to fix the case where this command is destroyed */ callout_stop(&cm->cm_callout); - reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply; + if (cm != NULL) + reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1603,7 +1607,7 @@ mprsas_ir_shutdown(struct mpr_softc *sc) action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; mpr_lock(sc); - mpr_wait_command(sc, cm, 5, CAN_SLEEP); + mpr_wait_command(sc, &cm, 5, CAN_SLEEP); mpr_unlock(sc); /* diff --git a/sys/dev/mpr/mpr_user.c b/sys/dev/mpr/mpr_user.c index 750b126368b8..fb9a0ba0ceff 100644 --- a/sys/dev/mpr/mpr_user.c +++ b/sys/dev/mpr/mpr_user.c @@ -652,7 +652,7 @@ static int mpr_user_command(struct mpr_softc *sc, struct mpr_usr_command *cmd) { MPI2_REQUEST_HEADER *hdr; - MPI2_DEFAULT_REPLY *rpl; + MPI2_DEFAULT_REPLY *rpl = NULL; void *buf = NULL; struct mpr_command *cm = NULL; int err = 0; @@ -664,7 +664,7 @@ mpr_user_command(struct mpr_softc *sc, struct mpr_usr_command *cmd) if (cm == NULL) { mpr_printf(sc, "%s: no mpr requests\n", __func__); err = ENOMEM; - goto Ret; + goto RetFree; } mpr_unlock(sc); @@ -706,15 +706,16 @@ mpr_user_command(struct mpr_softc *sc, struct mpr_usr_command *cmd) goto RetFreeUnlocked; mpr_lock(sc); - err = mpr_wait_command(sc, cm, 30, CAN_SLEEP); + err = mpr_wait_command(sc, &cm, 30, CAN_SLEEP); - if (err) { + if (err || (cm == NULL)) { mpr_printf(sc, "%s: invalid request: error %d\n", __func__, err); - goto Ret; + goto RetFree; } - rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply; + if (cm != NULL) + rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply; if (rpl != NULL) sz = rpl->MsgLength * 4; else @@ -734,9 +735,9 @@ mpr_user_command(struct mpr_softc *sc, struct mpr_usr_command *cmd) RetFreeUnlocked: mpr_lock(sc); +RetFree: if (cm != NULL) mpr_free_command(sc, cm); -Ret: mpr_unlock(sc); if (buf != NULL) free(buf, M_MPRUSER); @@ -850,7 +851,7 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data) err = 1; } else { mprsas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD); - err = mpr_wait_command(sc, cm, 30, CAN_SLEEP); + err = mpr_wait_command(sc, &cm, 30, CAN_SLEEP); } if (err != 0) { @@ -861,7 +862,7 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data) /* * Copy the reply data and sense data to user space. */ - if (cm->cm_reply != NULL) { + if ((cm != NULL) && (cm->cm_reply != NULL)) { rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply; sz = rpl->MsgLength * 4; @@ -1054,13 +1055,12 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data) mpr_lock(sc); - err = mpr_wait_command(sc, cm, 30, CAN_SLEEP); + err = mpr_wait_command(sc, &cm, 30, CAN_SLEEP); - if (err) { + if (err || (cm == NULL)) { mpr_printf(sc, "%s: invalid request: error %d\n", __func__, err); - mpr_unlock(sc); - goto RetFreeUnlocked; + goto RetFree; } /* @@ -1153,6 +1153,7 @@ mpr_user_pass_thru(struct mpr_softc *sc, mpr_pass_thru_t *data) RetFreeUnlocked: mpr_lock(sc); +RetFree: if (cm != NULL) { if (cm->cm_data) free(cm->cm_data, M_MPRUSER); @@ -1301,8 +1302,8 @@ mpr_post_fw_diag_buffer(struct mpr_softc *sc, /* * Send command synchronously. */ - status = mpr_wait_command(sc, cm, 30, CAN_SLEEP); - if (status) { + status = mpr_wait_command(sc, &cm, 30, CAN_SLEEP); + if (status || (cm == NULL)) { mpr_printf(sc, "%s: invalid request: error %d\n", __func__, status); status = MPR_DIAG_FAILURE; @@ -1333,7 +1334,8 @@ mpr_post_fw_diag_buffer(struct mpr_softc *sc, status = MPR_DIAG_SUCCESS; done: - mpr_free_command(sc, cm); + if (cm != NULL) + mpr_free_command(sc, cm); return (status); } @@ -1387,8 +1389,8 @@ mpr_release_fw_diag_buffer(struct mpr_softc *sc, /* * Send command synchronously. */ - status = mpr_wait_command(sc, cm, 30, CAN_SLEEP); - if (status) { + status = mpr_wait_command(sc, &cm, 30, CAN_SLEEP); + if (status || (cm == NULL)) { mpr_printf(sc, "%s: invalid request: error %d\n", __func__, status); status = MPR_DIAG_FAILURE; @@ -1423,6 +1425,9 @@ mpr_release_fw_diag_buffer(struct mpr_softc *sc, } done: + if (cm != NULL) + mpr_free_command(sc, cm); + return (status); } diff --git a/sys/dev/mpr/mprvar.h b/sys/dev/mpr/mprvar.h index bab76604549f..fd16bef30fed 100644 --- a/sys/dev/mpr/mprvar.h +++ b/sys/dev/mpr/mprvar.h @@ -275,6 +275,7 @@ struct mpr_softc { #define MPR_FLAGS_DIAGRESET (1 << 4) #define MPR_FLAGS_ATTACH_DONE (1 << 5) #define MPR_FLAGS_GEN35_IOC (1 << 6) +#define MPR_FLAGS_REALLOCATED (1 << 7) u_int mpr_debug; u_int disable_msix; u_int disable_msi; @@ -732,9 +733,9 @@ void mprsas_record_event(struct mpr_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event_reply); int mpr_map_command(struct mpr_softc *sc, struct mpr_command *cm); -int mpr_wait_command(struct mpr_softc *sc, struct mpr_command *cm, int timeout, +int mpr_wait_command(struct mpr_softc *sc, struct mpr_command **cm, int timeout, int sleep_flag); -int mpr_request_polled(struct mpr_softc *sc, struct mpr_command *cm); +int mpr_request_polled(struct mpr_softc *sc, struct mpr_command **cm); int mpr_config_get_bios_pg3(struct mpr_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage3_t *config_page); diff --git a/sys/dev/mps/mps.c b/sys/dev/mps/mps.c index 378cb044e66a..56cb61d8483a 100644 --- a/sys/dev/mps/mps.c +++ b/sys/dev/mps/mps.c @@ -427,6 +427,8 @@ mps_iocfacts_allocate(struct mps_softc *sc, uint8_t attaching) /* Only deallocate and reallocate if relevant IOC Facts have changed */ reallocating = FALSE; + sc->mps_flags &= ~MPS_FLAGS_REALLOCATED; + if ((!attaching) && ((saved_facts.MsgVersion != sc->facts->MsgVersion) || (saved_facts.HeaderVersion != sc->facts->HeaderVersion) || @@ -447,6 +449,9 @@ mps_iocfacts_allocate(struct mps_softc *sc, uint8_t attaching) (saved_facts.MaxPersistentEntries != sc->facts->MaxPersistentEntries))) { reallocating = TRUE; + + /* Record that we reallocated everything */ + sc->mps_flags |= MPS_FLAGS_REALLOCATED; } /* @@ -2075,7 +2080,7 @@ mps_update_events(struct mps_softc *sc, struct mps_event_handle *handle, u32 *mask) { MPI2_EVENT_NOTIFICATION_REQUEST *evtreq; - MPI2_EVENT_NOTIFICATION_REPLY *reply; + MPI2_EVENT_NOTIFICATION_REPLY *reply = NULL; struct mps_command *cm; int error, i; @@ -2113,8 +2118,9 @@ mps_update_events(struct mps_softc *sc, struct mps_event_handle *handle, cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_wait_command(sc, cm, 60, 0); - reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, 0); + if (cm != NULL) + reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply; if ((reply == NULL) || (reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) error = ENXIO; @@ -2124,7 +2130,8 @@ mps_update_events(struct mps_softc *sc, struct mps_event_handle *handle, mps_dprint(sc, MPS_TRACE, "%s finished error %d\n", __func__, error); - mps_free_command(sc, cm); + if (cm != NULL) + mps_free_command(sc, cm); return (error); } @@ -2530,11 +2537,12 @@ mps_map_command(struct mps_softc *sc, struct mps_command *cm) * be executed and enqueued automatically. Other errors come from msleep(). */ int -mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout, +mps_wait_command(struct mps_softc *sc, struct mps_command **cmp, int timeout, int sleep_flag) { int error, rc; struct timeval cur_time, start_time; + struct mps_command *cm = *cmp; if (sc->mps_flags & MPS_FLAGS_DIAGRESET) return EBUSY; @@ -2588,6 +2596,13 @@ mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout, rc = mps_reinit(sc); mps_dprint(sc, MPS_FAULT, "Reinit %s\n", (rc == 0) ? "success" : "failed"); + if (sc->mps_flags & MPS_FLAGS_REALLOCATED) { + /* + * Tell the caller that we freed the command in a + * reinit. + */ + *cmp = NULL; + } error = ETIMEDOUT; } return (error); @@ -2654,11 +2669,12 @@ mps_read_config_page(struct mps_softc *sc, struct mps_config_params *params) cm->cm_complete = mps_config_complete; return (mps_map_command(sc, cm)); } else { - error = mps_wait_command(sc, cm, 0, CAN_SLEEP); + error = mps_wait_command(sc, &cm, 0, CAN_SLEEP); if (error) { mps_dprint(sc, MPS_FAULT, "Error %d reading config page\n", error); - mps_free_command(sc, cm); + if (cm != NULL) + mps_free_command(sc, cm); return (error); } mps_config_complete(sc, cm); diff --git a/sys/dev/mps/mps_config.c b/sys/dev/mps/mps_config.c index e435d4f83d67..cfaf0a472f6a 100644 --- a/sys/dev/mps/mps_config.c +++ b/sys/dev/mps/mps_config.c @@ -71,7 +71,7 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2IOCPage8_t *config_page) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; MPI2_CONFIG_PAGE_IOC_8 *page = NULL; int error = 0; @@ -94,8 +94,9 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->Header.PageVersion = MPI2_IOCPAGE8_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -152,8 +153,9 @@ mps_config_get_ioc_pg8(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, } cm->cm_data = page; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -200,7 +202,7 @@ int mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; pMpi2ManufacturingPagePS_t page = NULL; uint32_t *pPS_info; @@ -230,8 +232,9 @@ mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply) * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mps_wait_command(sc, cm, 60, 0); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, 0); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ @@ -286,8 +289,9 @@ mps_config_get_man_pg10(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply) * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mps_wait_command(sc, cm, 60, 0); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, 0); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ @@ -559,7 +563,7 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2DriverMappingPage0_t *config_page, u16 sz) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; Mpi2DriverMappingPage0_t *page = NULL; int error = 0; @@ -586,8 +590,9 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, MPI2_DPM_PGAD_ENTRY_COUNT_SHIFT; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -646,8 +651,9 @@ mps_config_get_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, goto out; } cm->cm_data = page; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -695,7 +701,7 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2DriverMappingPage0_t *config_page, u16 entry_idx) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; MPI2_CONFIG_PAGE_DRIVER_MAPPING_0 *page = NULL; int error = 0; @@ -722,8 +728,9 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->PageAddress |= htole16(entry_idx); cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -784,8 +791,9 @@ int mps_config_set_dpm_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, bcopy(config_page, page, MIN(cm->cm_length, (sizeof(Mpi2DriverMappingPage0_t)))); cm->cm_data = page; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -833,7 +841,7 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2SasDevicePage0_t *config_page, u32 form, u16 handle) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; Mpi2SasDevicePage0_t *page = NULL; int error = 0; @@ -857,8 +865,9 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t request->Header.PageVersion = MPI2_SASDEVICE0_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -917,8 +926,9 @@ mps_config_get_sas_device_pg0(struct mps_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -966,7 +976,7 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2BiosPage3_t *config_page) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; Mpi2BiosPage3_t *page = NULL; int error = 0; @@ -989,8 +999,9 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, request->Header.PageVersion = MPI2_BIOSPAGE3_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1047,8 +1058,9 @@ mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, } cm->cm_data = page; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1096,7 +1108,7 @@ mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage0_t *config_page, u32 page_address) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; Mpi2RaidVolPage0_t *page = NULL; int error = 0; @@ -1124,8 +1136,9 @@ mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mps_wait_command(sc, cm, 60, 0); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, 0); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ @@ -1181,8 +1194,9 @@ mps_config_get_raid_volume_pg0(struct mps_softc *sc, Mpi2ConfigReply_t * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mps_wait_command(sc, cm, 60, 0); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, 0); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ @@ -1225,7 +1239,7 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2RaidVolPage1_t *config_page, u32 form, u16 handle) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; Mpi2RaidVolPage1_t *page = NULL; int error = 0; @@ -1248,8 +1262,9 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t request->Header.PageVersion = MPI2_RAIDVOLPAGE1_PAGEVERSION; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; cm->cm_data = NULL; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1307,8 +1322,9 @@ mps_config_get_raid_volume_pg1(struct mps_softc *sc, Mpi2ConfigReply_t } cm->cm_data = page; - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -1382,7 +1398,7 @@ mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, Mpi2RaidPhysDiskPage0_t *config_page, u32 page_address) { MPI2_CONFIG_REQUEST *request; - MPI2_CONFIG_REPLY *reply; + MPI2_CONFIG_REPLY *reply = NULL; struct mps_command *cm; Mpi2RaidPhysDiskPage0_t *page = NULL; int error = 0; @@ -1410,8 +1426,9 @@ mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mps_wait_command(sc, cm, 60, 0); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, 0); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ @@ -1467,8 +1484,9 @@ mps_config_get_raid_pd_pg0(struct mps_softc *sc, Mpi2ConfigReply_t *mpi_reply, * This page must be polled because the IOC isn't ready yet when this * page is needed. */ - error = mps_wait_command(sc, cm, 60, 0); - reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; + error = mps_wait_command(sc, &cm, 60, 0); + if (cm != NULL) + reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* If the poll returns error then we need to do diag reset */ diff --git a/sys/dev/mps/mps_sas.c b/sys/dev/mps/mps_sas.c index be864effc69f..c09df175425d 100644 --- a/sys/dev/mps/mps_sas.c +++ b/sys/dev/mps/mps_sas.c @@ -1131,13 +1131,8 @@ mpssas_complete_all_commands(struct mps_softc *sc) completed = 1; } - if (cm->cm_sc->io_cmds_active != 0) { + if (cm->cm_sc->io_cmds_active != 0) cm->cm_sc->io_cmds_active--; - } else { - mps_dprint(cm->cm_sc, MPS_INFO, "Warning: " - "io_cmds_active is out of sync - resynching to " - "0\n"); - } if ((completed == 0) && (cm->cm_state != MPS_CM_STATE_FREE)) { /* this should never happen, but if it does, log */ diff --git a/sys/dev/mps/mps_sas_lsi.c b/sys/dev/mps/mps_sas_lsi.c index 618d193bfedf..3d62a9a4bff5 100644 --- a/sys/dev/mps/mps_sas_lsi.c +++ b/sys/dev/mps/mps_sas_lsi.c @@ -915,7 +915,7 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle, Mpi2SataPassthroughReply_t *mpi_reply, char *id_buffer, int sz, u32 devinfo) { Mpi2SataPassthroughRequest_t *mpi_request; - Mpi2SataPassthroughReply_t *reply; + Mpi2SataPassthroughReply_t *reply = NULL; struct mps_command *cm; char *buffer; int error = 0; @@ -957,12 +957,14 @@ mpssas_get_sata_identify(struct mps_softc *sc, u16 handle, "command\n", __func__); callout_reset(&cm->cm_callout, MPS_ATA_ID_TIMEOUT * hz, mpssas_ata_id_timeout, cm); - error = mps_wait_command(sc, cm, 60, CAN_SLEEP); + error = mps_wait_command(sc, &cm, 60, CAN_SLEEP); mps_dprint(sc, MPS_XINFO, "%s stop timeout counter for SATA ID " "command\n", __func__); + /* XXX KDM need to fix the case where this command is destroyed */ callout_stop(&cm->cm_callout); - reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply; + if (cm != NULL) + reply = (Mpi2SataPassthroughReply_t *)cm->cm_reply; if (error || (reply == NULL)) { /* FIXME */ /* @@ -989,7 +991,8 @@ out: * it. The command will be freed after sending a target reset TM. If * the command did timeout, use EWOULDBLOCK. */ - if ((cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0) + if ((cm != NULL) + && (cm->cm_flags & MPS_CM_FLAGS_SATA_ID_TIMEOUT) == 0) mps_free_command(sc, cm); else if (error == 0) error = EWOULDBLOCK; @@ -1285,7 +1288,7 @@ mpssas_ir_shutdown(struct mps_softc *sc) action->Action = MPI2_RAID_ACTION_SYSTEM_SHUTDOWN_INITIATED; cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; mps_lock(sc); - mps_wait_command(sc, cm, 5, CAN_SLEEP); + mps_wait_command(sc, &cm, 5, CAN_SLEEP); mps_unlock(sc); /* diff --git a/sys/dev/mps/mps_user.c b/sys/dev/mps/mps_user.c index dc1ced14840f..c245efa969e9 100644 --- a/sys/dev/mps/mps_user.c +++ b/sys/dev/mps/mps_user.c @@ -677,7 +677,7 @@ mps_user_command(struct mps_softc *sc, struct mps_usr_command *cmd) if (cm == NULL) { mps_printf(sc, "%s: no mps requests\n", __func__); err = ENOMEM; - goto Ret; + goto RetFree; } mps_unlock(sc); @@ -719,12 +719,12 @@ mps_user_command(struct mps_softc *sc, struct mps_usr_command *cmd) goto RetFreeUnlocked; mps_lock(sc); - err = mps_wait_command(sc, cm, 60, CAN_SLEEP); + err = mps_wait_command(sc, &cm, 60, CAN_SLEEP); - if (err) { + if (err || (cm == NULL)) { mps_printf(sc, "%s: invalid request: error %d\n", __func__, err); - goto Ret; + goto RetFree; } rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply; @@ -747,9 +747,9 @@ mps_user_command(struct mps_softc *sc, struct mps_usr_command *cmd) RetFreeUnlocked: mps_lock(sc); +RetFree: if (cm != NULL) mps_free_command(sc, cm); -Ret: mps_unlock(sc); if (buf != NULL) free(buf, M_MPSUSER); @@ -760,7 +760,7 @@ static int mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data) { MPI2_REQUEST_HEADER *hdr, tmphdr; - MPI2_DEFAULT_REPLY *rpl; + MPI2_DEFAULT_REPLY *rpl = NULL; struct mps_command *cm = NULL; int err = 0, dir = 0, sz; uint8_t function = 0; @@ -861,7 +861,7 @@ mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data) err = 1; } else { mpssas_prepare_for_tm(sc, cm, targ, CAM_LUN_WILDCARD); - err = mps_wait_command(sc, cm, 30, CAN_SLEEP); + err = mps_wait_command(sc, &cm, 30, CAN_SLEEP); } if (err != 0) { @@ -872,7 +872,7 @@ mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data) /* * Copy the reply data and sense data to user space. */ - if (cm->cm_reply != NULL) { + if ((cm != NULL) && (cm->cm_reply != NULL)) { rpl = (MPI2_DEFAULT_REPLY *)cm->cm_reply; sz = rpl->MsgLength * 4; @@ -993,9 +993,9 @@ mps_user_pass_thru(struct mps_softc *sc, mps_pass_thru_t *data) mps_lock(sc); - err = mps_wait_command(sc, cm, 30, CAN_SLEEP); + err = mps_wait_command(sc, &cm, 30, CAN_SLEEP); - if (err) { + if (err || (cm == NULL)) { mps_printf(sc, "%s: invalid request: error %d\n", __func__, err); mps_unlock(sc); @@ -1161,7 +1161,7 @@ mps_post_fw_diag_buffer(struct mps_softc *sc, mps_fw_diagnostic_buffer_t *pBuffer, uint32_t *return_code) { MPI2_DIAG_BUFFER_POST_REQUEST *req; - MPI2_DIAG_BUFFER_POST_REPLY *reply; + MPI2_DIAG_BUFFER_POST_REPLY *reply = NULL; struct mps_command *cm = NULL; int i, status; @@ -1208,8 +1208,8 @@ mps_post_fw_diag_buffer(struct mps_softc *sc, /* * Send command synchronously. */ - status = mps_wait_command(sc, cm, 30, CAN_SLEEP); - if (status) { + status = mps_wait_command(sc, &cm, 30, CAN_SLEEP); + if (status || (cm == NULL)) { mps_printf(sc, "%s: invalid request: error %d\n", __func__, status); status = MPS_DIAG_FAILURE; @@ -1240,7 +1240,8 @@ mps_post_fw_diag_buffer(struct mps_softc *sc, status = MPS_DIAG_SUCCESS; done: - mps_free_command(sc, cm); + if (cm != NULL) + mps_free_command(sc, cm); return (status); } @@ -1250,7 +1251,7 @@ mps_release_fw_diag_buffer(struct mps_softc *sc, uint32_t diag_type) { MPI2_DIAG_RELEASE_REQUEST *req; - MPI2_DIAG_RELEASE_REPLY *reply; + MPI2_DIAG_RELEASE_REPLY *reply = NULL; struct mps_command *cm = NULL; int status; @@ -1294,8 +1295,8 @@ mps_release_fw_diag_buffer(struct mps_softc *sc, /* * Send command synchronously. */ - status = mps_wait_command(sc, cm, 30, CAN_SLEEP); - if (status) { + status = mps_wait_command(sc, &cm, 30, CAN_SLEEP); + if (status || (cm == NULL)) { mps_printf(sc, "%s: invalid request: error %d\n", __func__, status); status = MPS_DIAG_FAILURE; @@ -1330,6 +1331,9 @@ mps_release_fw_diag_buffer(struct mps_softc *sc, } done: + if (cm != NULL) + mps_free_command(sc, cm); + return (status); } diff --git a/sys/dev/mps/mpsvar.h b/sys/dev/mps/mpsvar.h index b7cc549d3a96..b8d074a8e2bb 100644 --- a/sys/dev/mps/mpsvar.h +++ b/sys/dev/mps/mpsvar.h @@ -271,6 +271,7 @@ struct mps_softc { #define MPS_FLAGS_DIAGRESET (1 << 4) #define MPS_FLAGS_ATTACH_DONE (1 << 5) #define MPS_FLAGS_WD_AVAILABLE (1 << 6) +#define MPS_FLAGS_REALLOCATED (1 << 7) u_int mps_debug; u_int disable_msix; u_int disable_msi; @@ -697,7 +698,7 @@ void mpssas_record_event(struct mps_softc *sc, MPI2_EVENT_NOTIFICATION_REPLY *event_reply); int mps_map_command(struct mps_softc *sc, struct mps_command *cm); -int mps_wait_command(struct mps_softc *sc, struct mps_command *cm, int timeout, +int mps_wait_command(struct mps_softc *sc, struct mps_command **cm, int timeout, int sleep_flag); int mps_config_get_bios_pg3(struct mps_softc *sc, Mpi2ConfigReply_t