Fix mpt_reset to try mpt_hard_reset more than once, and to try

mpt_soft_reset more than once. And to wait for MPT_DB_STATE_READY
twice. I mean, this is crucial- give the IOC a chance to get
ready.

If mpt_reset is called to reinit things, and we succeed, make
sure to re-enable interrupts. This is what has mostly led to
system lockup after having to hard reset the chip. Also, if
we think that interrupts aren't function in mpt_cam_timeout,
for goodness sake, turn them on again.

In read_cfg_header, return distinguishing errnos so the caller
can decide what's an error. It's *not* an error to fail to
read a RAID page from a non-RAID capable device like the FC929X.

Some whitespace fixes (removing spaces from ends of lines).
This commit is contained in:
Matt Jacob 2006-02-28 07:44:50 +00:00
parent 30b86e872b
commit 29ae59edff
2 changed files with 87 additions and 44 deletions

View File

@ -935,18 +935,39 @@ mpt_reset(struct mpt_softc *mpt, int reinit)
{
struct mpt_personality *pers;
int ret;
int retry_cnt = 0;
/* Try a soft reset */
/*
* Try a soft reset. If that fails, get out the big hammer.
*/
again:
if ((ret = mpt_soft_reset(mpt)) != MPT_OK) {
int cnt;
for (cnt = 0; cnt < 5; cnt++) {
/* Failed; do a hard reset */
mpt_hard_reset(mpt);
/* Wait for the IOC to reload and come out of reset state */
/*
* Wait for the IOC to reload
* and come out of reset state
*/
ret = mpt_wait_state(mpt, MPT_DB_STATE_READY);
if (ret != MPT_OK)
mpt_prt(mpt, "failed to reset device\n");
if (ret == MPT_OK) {
break;
}
/*
* Okay- try to check again...
*/
ret = mpt_wait_state(mpt, MPT_DB_STATE_READY);
if (ret == MPT_OK) {
break;
}
mpt_prt(mpt, "mpt_reset: failed hard reset (%d:%d)\n",
retry_cnt, cnt);
}
}
if (retry_cnt == 0) {
/*
* Invoke reset handlers. We bump the reset count so
* that mpt_wait_req() understands that regardless of
@ -955,10 +976,17 @@ mpt_reset(struct mpt_softc *mpt, int reinit)
mpt->reset_cnt++;
MPT_PERS_FOREACH(mpt, pers)
pers->reset(mpt, ret);
}
if (reinit != 0)
mpt_enable_ioc(mpt);
if (reinit != 0) {
ret = mpt_enable_ioc(mpt);
if (ret == MPT_OK) {
mpt_enable_ints(mpt);
}
}
if (ret != MPT_OK && retry_cnt++ < 2) {
goto again;
}
return ret;
}
@ -1363,12 +1391,13 @@ mpt_read_cfg_header(struct mpt_softc *mpt, int PageType, int PageNumber,
int sleep_ok, int timeout_ms)
{
request_t *req;
MSG_CONFIG *cfgp;
int error;
req = mpt_get_request(mpt, sleep_ok);
if (req == NULL) {
mpt_prt(mpt, "mpt_read_cfg_header: Get request failed!\n");
return (-1);
return (ENOMEM);
}
error = mpt_issue_cfg_req(mpt, req, MPI_CONFIG_ACTION_PAGE_HEADER,
@ -1376,20 +1405,28 @@ 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);
mpt_prt(mpt, "read_cfg_header timed out\n");
return (-1);
return (ETIMEDOUT);
}
if ((req->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
mpt_prt(mpt, "mpt_read_cfg_header: Config Info Status %x\n",
req->IOCStatus);
error = -1;
} else {
MSG_CONFIG *cfgp;
switch (req->IOCStatus & MPI_IOCSTATUS_MASK) {
case MPI_IOCSTATUS_SUCCESS:
cfgp = req->req_vbuf;
bcopy(&cfgp->Header, rslt, sizeof(*rslt));
error = 0;
break;
case MPI_IOCSTATUS_CONFIG_INVALID_PAGE:
mpt_lprt(mpt, MPT_PRT_DEBUG,
"Invalid Page Type %d Number %d Addr 0x%0x\n",
PageType, PageNumber, PageAddress);
error = EINVAL;
break;
default:
mpt_prt(mpt, "mpt_read_cfg_header: Config Info Status %x\n",
req->IOCStatus);
error = EIO;
break;
}
mpt_free_request(mpt, req);
return (error);
@ -1495,8 +1532,13 @@ mpt_read_config_info_ioc(struct mpt_softc *mpt)
rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_IOC,
/*PageNumber*/2, /*PageAddress*/0, &hdr,
/*sleep_ok*/FALSE, /*timeout_ms*/5000);
/*
* If it's an invalid page, so what? Not a supported function....
*/
if (rv == EINVAL)
return (0);
if (rv)
return (EIO);
return (rv);
mpt_lprt(mpt, MPT_PRT_DEBUG, "IOC Page 2 Header: ver %x, len %x, "
"num %x, type %x\n", hdr.PageVersion,
@ -2465,5 +2507,5 @@ mpt_enable_ioc(struct mpt_softc *mpt)
mpt_lprt(mpt, MPT_PRT_DEBUG, "enabled port 0\n");
return (0);
return (MPT_OK);
}

View File

@ -2063,6 +2063,7 @@ mpt_recover_commands(struct mpt_softc *mpt)
*/
mpt_prt(mpt, "Timedout requests already complete. "
"Interrupts may not be functioning.\n");
mpt_enable_ints(mpt);
MPT_UNLOCK(mpt);
return;
}