diff options
author | Matt Jacob <mjacob@FreeBSD.org> | 2006-07-16 03:34:55 +0000 |
---|---|---|
committer | Matt Jacob <mjacob@FreeBSD.org> | 2006-07-16 03:34:55 +0000 |
commit | 6621d786eb1087e71cddd11719817bafd7c5f32c (patch) | |
tree | 297269a27f6b1d72f5be3394b1257609487d5db0 /sys/dev/mpt | |
parent | 784880db2536ae4c918029720036e4078c4fecc4 (diff) | |
download | src-6621d786eb1087e71cddd11719817bafd7c5f32c.tar.gz src-6621d786eb1087e71cddd11719817bafd7c5f32c.zip |
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
Notes
Notes:
svn path=/head/; revision=160396
Diffstat (limited to 'sys/dev/mpt')
-rw-r--r-- | sys/dev/mpt/mpt.c | 13 | ||||
-rw-r--r-- | sys/dev/mpt/mpt_cam.c | 9 |
2 files changed, 18 insertions, 4 deletions
diff --git a/sys/dev/mpt/mpt.c b/sys/dev/mpt/mpt.c index 24ef25430560..2b8028abc49e 100644 --- a/sys/dev/mpt/mpt.c +++ b/sys/dev/mpt/mpt.c @@ -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); } diff --git a/sys/dev/mpt/mpt_cam.c b/sys/dev/mpt/mpt_cam.c index c7803c7bd844..f7f6c8dd123d 100644 --- a/sys/dev/mpt/mpt_cam.c +++ b/sys/dev/mpt/mpt_cam.c @@ -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); |