aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptbase.c
diff options
context:
space:
mode:
authorKashyap, Desai <kashyap.desai@lsi.com>2010-03-18 09:42:17 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 10:24:04 -0400
commitd0f698c46141e1d179fb3a86a0ae668d2fd12916 (patch)
treea66e2ba2f34ea63d1568a46270c5414e842dad1d /drivers/message/fusion/mptbase.c
parent1a7d7eac6f651c00e954023dd2542f0c65ef66b7 (diff)
[SCSI] mptfusion: Added new less expensive RESET (Message Unit Reset)
Message Unit Reset - instructs the IOC to reset the Reply Post and Free FIFO's. All the Message Frames on Reply Free FIFO are discarded. All posted buffers are freed, and event notification is turned off. IOC doesnt reply to any outstanding request. This will transfer IOC to READY state. Message unit ready is less expensive operations than Hard Reset. soft reset will not force Firmware to reload again, it only do clean up of Message units. mpt_Soft_Hard_ResetHandler will first try for Soft Reset,if it fails then go for big hammer reset which is Hard Reset. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
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