diff options
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 68 |
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 "); | |||
95 | static int | 95 | static 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 | ||
98 | static 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 | */ | ||
3474 | static 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); |