summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);