aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptbase.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion/mptbase.c')
-rw-r--r--drivers/message/fusion/mptbase.c170
1 files changed, 168 insertions, 2 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 5382b5a44aff..a4f023bd5d2b 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -5064,7 +5064,7 @@ mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5064 if (!timeleft) { 5064 if (!timeleft) {
5065 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n", 5065 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
5066 ioc->name, __func__); 5066 ioc->name, __func__);
5067 mpt_HardResetHandler(ioc, CAN_SLEEP); 5067 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5068 mpt_free_msg_frame(ioc, mf); 5068 mpt_free_msg_frame(ioc, mf);
5069 } 5069 }
5070 goto out; 5070 goto out;
@@ -6456,7 +6456,7 @@ out:
6456 issue_hard_reset = 0; 6456 issue_hard_reset = 0;
6457 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", 6457 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6458 ioc->name, __func__); 6458 ioc->name, __func__);
6459 mpt_HardResetHandler(ioc, CAN_SLEEP); 6459 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
6460 mpt_free_msg_frame(ioc, mf); 6460 mpt_free_msg_frame(ioc, mf);
6461 /* attempt one retry for a timed out command */ 6461 /* attempt one retry for a timed out command */
6462 if (!retry_count) { 6462 if (!retry_count) {
@@ -6904,6 +6904,172 @@ mpt_halt_firmware(MPT_ADAPTER *ioc)
6904} 6904}
6905EXPORT_SYMBOL(mpt_halt_firmware); 6905EXPORT_SYMBOL(mpt_halt_firmware);
6906 6906
6907/**
6908 * mpt_SoftResetHandler - Issues a less expensive reset
6909 * @ioc: Pointer to MPT_ADAPTER structure
6910 * @sleepFlag: Indicates if sleep or schedule must be called.
6911
6912 *
6913 * Returns 0 for SUCCESS or -1 if FAILED.
6914 *
6915 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6916 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6917 * All posted buffers are freed, and event notification is turned off.
6918 * IOC doesnt reply to any outstanding request. This will transfer IOC
6919 * to READY state.
6920 **/
6921int
6922mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6923{
6924 int rc;
6925 int ii;
6926 u8 cb_idx;
6927 unsigned long flags;
6928 u32 ioc_state;
6929 unsigned long time_count;
6930
6931 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
6932 ioc->name));
6933
6934 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6935
6936 if (mpt_fwfault_debug)
6937 mpt_halt_firmware(ioc);
6938
6939 if (ioc_state == MPI_IOC_STATE_FAULT ||
6940 ioc_state == MPI_IOC_STATE_RESET) {
6941 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6942 "skipping, either in FAULT or RESET state!\n", ioc->name));
6943 return -1;
6944 }
6945
6946 if (ioc->bus_type == FC) {
6947 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6948 "skipping, because the bus type is FC!\n", ioc->name));
6949 return -1;
6950 }
6951
6952 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6953 if (ioc->ioc_reset_in_progress) {
6954 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6955 return -1;
6956 }
6957 ioc->ioc_reset_in_progress = 1;
6958 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6959
6960 rc = -1;
6961
6962 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6963 if (MptResetHandlers[cb_idx])
6964 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6965 }
6966
6967 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6968 if (ioc->taskmgmt_in_progress) {
6969 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6970 return -1;
6971 }
6972 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6973 /* Disable reply interrupts (also blocks FreeQ) */
6974 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
6975 ioc->active = 0;
6976 time_count = jiffies;
6977
6978 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
6979
6980 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6981 if (MptResetHandlers[cb_idx])
6982 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
6983 }
6984
6985 if (rc)
6986 goto out;
6987
6988 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6989 if (ioc_state != MPI_IOC_STATE_READY)
6990 goto out;
6991
6992 for (ii = 0; ii < 5; ii++) {
6993 /* Get IOC facts! Allow 5 retries */
6994 rc = GetIocFacts(ioc, sleepFlag,
6995 MPT_HOSTEVENT_IOC_RECOVER);
6996 if (rc == 0)
6997 break;
6998 if (sleepFlag == CAN_SLEEP)
6999 msleep(100);
7000 else
7001 mdelay(100);
7002 }
7003 if (ii == 5)
7004 goto out;
7005
7006 rc = PrimeIocFifos(ioc);
7007 if (rc != 0)
7008 goto out;
7009
7010 rc = SendIocInit(ioc, sleepFlag);
7011 if (rc != 0)
7012 goto out;
7013
7014 rc = SendEventNotification(ioc, 1, sleepFlag);
7015 if (rc != 0)
7016 goto out;
7017
7018 if (ioc->hard_resets < -1)
7019 ioc->hard_resets++;
7020
7021 /*
7022 * At this point, we know soft reset succeeded.
7023 */
7024
7025 ioc->active = 1;
7026 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7027
7028 out:
7029 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7030 ioc->ioc_reset_in_progress = 0;
7031 ioc->taskmgmt_quiesce_io = 0;
7032 ioc->taskmgmt_in_progress = 0;
7033 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7034
7035 if (ioc->active) { /* otherwise, hard reset coming */
7036 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7037 if (MptResetHandlers[cb_idx])
7038 mpt_signal_reset(cb_idx, ioc,
7039 MPT_IOC_POST_RESET);
7040 }
7041 }
7042
7043 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7044 "SoftResetHandler: completed (%d seconds): %s\n",
7045 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7046 ((rc == 0) ? "SUCCESS" : "FAILED")));
7047
7048 return rc;
7049}
7050
7051/**
7052 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7053 * @ioc: Pointer to MPT_ADAPTER structure
7054 * @sleepFlag: Indicates if sleep or schedule must be called.
7055
7056 *
7057 * Returns 0 for SUCCESS or -1 if FAILED.
7058 * Try for softreset first, only if it fails go for expensive
7059 * HardReset.
7060 **/
7061int
7062mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7063 int ret = -1;
7064
7065 ret = mpt_SoftResetHandler(ioc, sleepFlag);
7066 if (ret == 0)
7067 return ret;
7068 ret = mpt_HardResetHandler(ioc, sleepFlag);
7069 return ret;
7070}
7071EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7072
6907/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7073/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6908/* 7074/*
6909 * Reset Handling 7075 * Reset Handling