If we're in mpt_wait_req and the command times out,

mark it as timed out. Don't try and free the config
request for read_cfg_header that times out because
it's still active. Put in code for the config reply
handler that will then free up timed out requests.

Fix the FC_PRIMITIVE_SEND completion to not try
and free a command twice. Dunno how this possibly
could have been working for awhile.

MFC after:	2 weeks
This commit is contained in:
Matt Jacob 2006-07-16 03:34:55 +00:00
parent 784880db25
commit 6621d786eb
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=160396
2 changed files with 18 additions and 4 deletions

View file

@ -483,6 +483,11 @@ mpt_config_reply_handler(struct mpt_softc *mpt, request_t *req,
TAILQ_REMOVE(&mpt->request_pending_list, req, links);
if ((req->state & REQ_STATE_NEED_WAKEUP) != 0) {
wakeup(req);
} else if ((req->state & REQ_STATE_TIMEDOUT) != 0) {
/*
* Whew- we can free this request (late completion)
*/
mpt_free_request(mpt, req);
}
}
@ -1282,6 +1287,7 @@ mpt_wait_req(struct mpt_softc *mpt, request_t *req,
}
if (time_ms && timeout <= 0) {
MSG_REQUEST_HEADER *msg_hdr = req->req_vbuf;
req->state |= REQ_STATE_TIMEDOUT;
mpt_prt(mpt, "mpt_wait_req(%x) timed out\n", msg_hdr->Function);
return (ETIMEDOUT);
}
@ -1560,7 +1566,12 @@ mpt_read_cfg_header(struct mpt_softc *mpt, int PageType, int PageNumber,
PageType, PageAddress, /*addr*/0, /*len*/0,
sleep_ok, timeout_ms);
if (error != 0) {
mpt_free_request(mpt, req);
/*
* Leave the request. Without resetting the chip, it's
* still owned by it and we'll just get into trouble
* freeing it now. Mark it as abandoned so that if it
* shows up later it can be freed.
*/
mpt_prt(mpt, "read_cfg_header timed out\n");
return (ETIMEDOUT);
}

View file

@ -2393,14 +2393,17 @@ mpt_fc_els_reply_handler(struct mpt_softc *mpt, request_t *req,
TAILQ_REMOVE(&mpt->request_pending_list, req, links);
req->state &= ~REQ_STATE_QUEUED;
req->state |= REQ_STATE_DONE;
if ((req->state & REQ_STATE_NEED_WAKEUP) == 0) {
if (req->state & REQ_STATE_TIMEDOUT) {
mpt_lprt(mpt, MPT_PRT_DEBUG,
"Sync Primitive Send Completed After Timeout\n");
mpt_free_request(mpt, req);
} else if ((req->state & REQ_STATE_NEED_WAKEUP) == 0) {
mpt_lprt(mpt, MPT_PRT_DEBUG,
"Async Primitive Send Complete\n");
TAILQ_REMOVE(&mpt->request_pending_list, req, links);
mpt_free_request(mpt, req);
} else {
mpt_lprt(mpt, MPT_PRT_DEBUG,
"Sync Primitive Send Complete\n");
"Sync Primitive Send Complete- Waking Waiter\n");
wakeup(req);
}
return (TRUE);