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:
parent
30b86e872b
commit
29ae59edff
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user