Commit 4dc8c808 authored by Sreekanth Reddy's avatar Sreekanth Reddy Committed by James Bottomley

mpt3sas: Get IOC_FACTS information using handshake protocol only after HBA...

mpt3sas: Get IOC_FACTS information using handshake protocol only after HBA card gets into READY or Operational state.

Driver initialization fails if driver tries to send IOC facts request message
when the IOC is in reset or in a fault state.

This patch will make sure that

 1.Driver to send IOC facts request message only if HBA is in operational or
   ready state.

 2.If IOC is in fault state, a diagnostic reset would be issued.

 3.If IOC is in reset state then driver will wait for 10 seconds to exit out
   of reset state.  If the HBA continues to be in reset state, then the HBA
   wouldn't be claimed by the driver.
Signed-off-by: default avatarSreekanth Reddy <Sreekanth.Reddy@avagotech.com>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent fb77bb53
......@@ -3190,6 +3190,9 @@ _base_wait_on_iocstate(struct MPT3SAS_ADAPTER *ioc, u32 ioc_state, int timeout,
*
* Notes: MPI2_HIS_IOC2SYS_DB_STATUS - set to one when IOC writes to doorbell.
*/
static int
_base_diag_reset(struct MPT3SAS_ADAPTER *ioc, int sleep_flag);
static int
_base_wait_for_doorbell_int(struct MPT3SAS_ADAPTER *ioc, int timeout,
int sleep_flag)
......@@ -3732,6 +3735,64 @@ _base_get_port_facts(struct MPT3SAS_ADAPTER *ioc, int port, int sleep_flag)
return 0;
}
/**
* _base_wait_for_iocstate - Wait until the card is in READY or OPERATIONAL
* @ioc: per adapter object
* @timeout:
* @sleep_flag: CAN_SLEEP or NO_SLEEP
*
* Returns 0 for success, non-zero for failure.
*/
static int
_base_wait_for_iocstate(struct MPT3SAS_ADAPTER *ioc, int timeout,
int sleep_flag)
{
u32 ioc_state;
int rc;
dinitprintk(ioc, printk(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
if (ioc->pci_error_recovery) {
dfailprintk(ioc, printk(MPT3SAS_FMT
"%s: host in pci error recovery\n", ioc->name, __func__));
return -EFAULT;
}
ioc_state = mpt3sas_base_get_iocstate(ioc, 0);
dhsprintk(ioc, printk(MPT3SAS_FMT "%s: ioc_state(0x%08x)\n",
ioc->name, __func__, ioc_state));
if (((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_READY) ||
(ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_OPERATIONAL)
return 0;
if (ioc_state & MPI2_DOORBELL_USED) {
dhsprintk(ioc, printk(MPT3SAS_FMT
"unexpected doorbell active!\n", ioc->name));
goto issue_diag_reset;
}
if ((ioc_state & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) {
mpt3sas_base_fault_info(ioc, ioc_state &
MPI2_DOORBELL_DATA_MASK);
goto issue_diag_reset;
}
ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY,
timeout, sleep_flag);
if (ioc_state) {
dfailprintk(ioc, printk(MPT3SAS_FMT
"%s: failed going to ready state (ioc_state=0x%x)\n",
ioc->name, __func__, ioc_state));
return -EFAULT;
}
issue_diag_reset:
rc = _base_diag_reset(ioc, sleep_flag);
return rc;
}
/**
* _base_get_ioc_facts - obtain ioc facts reply and save in ioc
* @ioc: per adapter object
......@@ -3750,6 +3811,13 @@ _base_get_ioc_facts(struct MPT3SAS_ADAPTER *ioc, int sleep_flag)
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
r = _base_wait_for_iocstate(ioc, 10, sleep_flag);
if (r) {
dfailprintk(ioc, printk(MPT3SAS_FMT
"%s: failed getting to correct state\n",
ioc->name, __func__));
return r;
}
mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t);
mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t);
memset(&mpi_request, 0, mpi_request_sz);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment