# HG changeset patch # User Taylor R Campbell # Date 1597974123 0 # Fri Aug 21 01:42:03 2020 +0000 # Branch trunk # Node ID bb8fb73dbefe6cafd7c2a64b30087ffad783f8c9 # Parent d01cf28fde8015fc34a9724a9edc4f99c7035a8f # EXP-Topic riastradh-mptfixes mpt(4): Formalize request state transitions and make assertions. diff -r d01cf28fde80 -r bb8fb73dbefe sys/dev/ic/mpt.c --- a/sys/dev/ic/mpt.c Thu Aug 20 19:43:42 2020 +0000 +++ b/sys/dev/ic/mpt.c Fri Aug 21 01:42:03 2020 +0000 @@ -286,17 +286,33 @@ mpt_reset(mpt_softc_t *mpt) return ret; } +void +mpt_transition_request(mpt_softc_t *mpt, request_t *req, + enum mpt_req_state ostate, enum mpt_req_state nstate) +{ + + KASSERT(req); + KASSERTMSG(req == &mpt->request_pool[req->index], + "request %u is %p, not %p", + req->index, &mpt->request_pool[req->index], req); + KASSERTMSG(req->debug == ostate, + "transition to %s -- request %p is in state %s, not %s", + mpt_req_state(nstate), + req, + mpt_req_state(req->debug), + mpt_req_state(ostate)); + + req->debug = nstate; +} + /* Return a command buffer to the free queue */ void mpt_free_request(mpt_softc_t *mpt, request_t *req) { - if (req == NULL || req != &mpt->request_pool[req->index]) { - panic("mpt_free_request bad req ptr\n"); - return; - } + + mpt_transition_request(mpt, req, REQ_DONE, REQ_FREE); req->sequence = 0; req->xfer = NULL; - req->debug = REQ_FREE; SLIST_INSERT_HEAD(&mpt->request_free_list, req, link); } @@ -305,17 +321,13 @@ request_t * mpt_get_request(mpt_softc_t *mpt) { request_t *req; + req = SLIST_FIRST(&mpt->request_free_list); - if (req != NULL) { - if (req != &mpt->request_pool[req->index]) { - panic("mpt_get_request: corrupted request free list\n"); - } - if (req->xfer != NULL) { - panic("mpt_get_request: corrupted request free list (xfer)\n"); - } - SLIST_REMOVE_HEAD(&mpt->request_free_list, link); - req->debug = REQ_IN_PROGRESS; - } + if (req == NULL) + return NULL; + + mpt_transition_request(mpt, req, REQ_FREE, REQ_IN_PROGRESS); + SLIST_REMOVE_HEAD(&mpt->request_free_list, link); return req; } @@ -323,6 +335,8 @@ mpt_get_request(mpt_softc_t *mpt) void mpt_send_cmd(mpt_softc_t *mpt, request_t *req) { + + mpt_transition_request(mpt, req, REQ_IN_PROGRESS, REQ_ON_CHIP); req->sequence = mpt->sequence++; if (mpt->verbose > 1) { u_int32_t *pReq; @@ -339,7 +353,6 @@ mpt_send_cmd(mpt_softc_t *mpt, request_t pReq[12], pReq[13], pReq[14], pReq[15]); } MPT_SYNC_REQ(mpt, req, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - req->debug = REQ_ON_CHIP; mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf); } diff -r d01cf28fde80 -r bb8fb73dbefe sys/dev/ic/mpt.h --- a/sys/dev/ic/mpt.h Thu Aug 20 19:43:42 2020 +0000 +++ b/sys/dev/ic/mpt.h Fri Aug 21 01:42:03 2020 +0000 @@ -168,6 +168,8 @@ int mpt_hw_init(mpt_softc_t *); int mpt_init(mpt_softc_t *, u_int32_t); int mpt_reset(mpt_softc_t *); int mpt_send_handshake_cmd(mpt_softc_t *, size_t, void *); +void mpt_transition_request(mpt_softc_t *, request_t *, enum mpt_req_state, + enum mpt_req_state); request_t * mpt_get_request(mpt_softc_t *); void mpt_free_request(mpt_softc_t *, request_t *); int mpt_intr(void *); diff -r d01cf28fde80 -r bb8fb73dbefe sys/dev/ic/mpt_netbsd.c --- a/sys/dev/ic/mpt_netbsd.c Thu Aug 20 19:43:42 2020 +0000 +++ b/sys/dev/ic/mpt_netbsd.c Fri Aug 21 01:42:03 2020 +0000 @@ -1288,7 +1288,13 @@ mpt_ctlop(mpt_softc_t *mpt, void *vmsg, mpt_prt(mpt, "enable port reply index %d", index); if (index >= 0 && index < MPT_MAX_REQUESTS(mpt)) { request_t *req = &mpt->request_pool[index]; - req->debug = REQ_DONE; + if (req->debug != REQ_ON_CHIP) { + mpt_prt(mpt, "bogus port reply %d (%s)", + req->index, mpt_req_state(req->debug)); + } else { + mpt_transition_request(mpt, req, REQ_ON_CHIP, + REQ_DONE); + } } mpt_free_reply(mpt, (reply << 1)); break; @@ -1300,8 +1306,14 @@ mpt_ctlop(mpt_softc_t *mpt, void *vmsg, int index = le32toh(msg->MsgContext) & ~0x80000000; if (index >= 0 && index < MPT_MAX_REQUESTS(mpt)) { request_t *req = &mpt->request_pool[index]; - req->debug = REQ_DONE; - req->sequence = reply; + if (req->debug != REQ_ON_CHIP) { + mpt_prt(mpt, "bogus config reply %d (%s)", + req->index, mpt_req_state(req->debug)); + } else { + mpt_transition_request(mpt, req, REQ_ON_CHIP, + REQ_DONE); + req->sequence = reply; + } } else mpt_free_reply(mpt, (reply << 1)); break;