aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSreekanth Reddy <sreekanth.reddy@avagotech.com>2014-09-12 06:05:23 -0400
committerChristoph Hellwig <hch@lst.de>2014-09-16 12:14:16 -0400
commita66dd970c7808f0a3453bbc38b39553f6eafd994 (patch)
tree11a252d3cff74101bee7d3c396e3e42431897e1d
parent5fb1bf8aaa832e1e9ca3198de7bbecb8eff7db9c (diff)
mpt2sas: 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: Sreekanth Reddy <Sreekanth.Reddy@avagotech.com> Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index fc9dfda72699..58e45216d1ec 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -95,6 +95,9 @@ MODULE_PARM_DESC(disable_discovery, " disable discovery ");
95static int 95static int
96_base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag); 96_base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag);
97 97
98static int
99_base_diag_reset(struct MPT2SAS_ADAPTER *ioc, int sleep_flag);
100
98/** 101/**
99 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug. 102 * _scsih_set_fwfault_debug - global setting of ioc->fwfault_debug.
100 * 103 *
@@ -3461,6 +3464,64 @@ _base_get_port_facts(struct MPT2SAS_ADAPTER *ioc, int port, int sleep_flag)
3461} 3464}
3462 3465
3463/** 3466/**
3467 * _base_wait_for_iocstate - Wait until the card is in READY or OPERATIONAL
3468 * @ioc: per adapter object
3469 * @timeout:
3470 * @sleep_flag: CAN_SLEEP or NO_SLEEP
3471 *
3472 * Returns 0 for success, non-zero for failure.
3473 */
3474static int
3475_base_wait_for_iocstate(struct MPT2SAS_ADAPTER *ioc, int timeout,
3476 int sleep_flag)
3477{
3478 u32 ioc_state, doorbell;
3479 int rc;
3480
3481 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3482 __func__));
3483
3484 if (ioc->pci_error_recovery)
3485 return 0;
3486
3487 doorbell = mpt2sas_base_get_iocstate(ioc, 0);
3488 ioc_state = doorbell & MPI2_IOC_STATE_MASK;
3489 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: ioc_state(0x%08x)\n",
3490 ioc->name, __func__, ioc_state));
3491
3492 switch (ioc_state) {
3493 case MPI2_IOC_STATE_READY:
3494 case MPI2_IOC_STATE_OPERATIONAL:
3495 return 0;
3496 }
3497
3498 if (doorbell & MPI2_DOORBELL_USED) {
3499 dhsprintk(ioc, printk(MPT2SAS_INFO_FMT
3500 "unexpected doorbell activ!e\n", ioc->name));
3501 goto issue_diag_reset;
3502 }
3503
3504 if (ioc_state == MPI2_IOC_STATE_FAULT) {
3505 mpt2sas_base_fault_info(ioc, doorbell &
3506 MPI2_DOORBELL_DATA_MASK);
3507 goto issue_diag_reset;
3508 }
3509
3510 ioc_state = _base_wait_on_iocstate(ioc, MPI2_IOC_STATE_READY,
3511 timeout, sleep_flag);
3512 if (ioc_state) {
3513 printk(MPT2SAS_ERR_FMT
3514 "%s: failed going to ready state (ioc_state=0x%x)\n",
3515 ioc->name, __func__, ioc_state);
3516 return -EFAULT;
3517 }
3518
3519 issue_diag_reset:
3520 rc = _base_diag_reset(ioc, sleep_flag);
3521 return rc;
3522}
3523
3524/**
3464 * _base_get_ioc_facts - obtain ioc facts reply and save in ioc 3525 * _base_get_ioc_facts - obtain ioc facts reply and save in ioc
3465 * @ioc: per adapter object 3526 * @ioc: per adapter object
3466 * @sleep_flag: CAN_SLEEP or NO_SLEEP 3527 * @sleep_flag: CAN_SLEEP or NO_SLEEP
@@ -3478,6 +3539,13 @@ _base_get_ioc_facts(struct MPT2SAS_ADAPTER *ioc, int sleep_flag)
3478 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name, 3539 dinitprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
3479 __func__)); 3540 __func__));
3480 3541
3542 r = _base_wait_for_iocstate(ioc, 10, sleep_flag);
3543 if (r) {
3544 printk(MPT2SAS_ERR_FMT "%s: failed getting to correct state\n",
3545 ioc->name, __func__);
3546 return r;
3547 }
3548
3481 mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t); 3549 mpi_reply_sz = sizeof(Mpi2IOCFactsReply_t);
3482 mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t); 3550 mpi_request_sz = sizeof(Mpi2IOCFactsRequest_t);
3483 memset(&mpi_request, 0, mpi_request_sz); 3551 memset(&mpi_request, 0, mpi_request_sz);