aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/message/fusion/mptbase.c170
-rw-r--r--drivers/message/fusion/mptbase.h1
-rw-r--r--drivers/message/fusion/mptctl.c2
-rw-r--r--drivers/message/fusion/mptsas.c8
-rw-r--r--drivers/message/fusion/mptscsih.c6
5 files changed, 177 insertions, 10 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
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index 9718c8f2e959..e25dbfbb8fdf 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -940,6 +940,7 @@ extern int mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp);
940extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked); 940extern u32 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked);
941extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan); 941extern void mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buf, int *size, int len, int showlan);
942extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); 942extern int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
943extern int mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
943extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg); 944extern int mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *cfg);
944extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size); 945extern int mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size);
945extern void mpt_free_fw_memory(MPT_ADAPTER *ioc); 946extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 80421d2cf049..e6d71e20fa09 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -311,7 +311,7 @@ mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
311 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n", 311 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
312 ioc->name)); 312 ioc->name));
313 CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status) 313 CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
314 mpt_HardResetHandler(ioc, CAN_SLEEP); 314 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
315 mpt_free_msg_frame(ioc, mf); 315 mpt_free_msg_frame(ioc, mf);
316} 316}
317 317
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 76687126b573..e5e9bf3487db 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -2041,7 +2041,7 @@ static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset)
2041 if (!timeleft) { 2041 if (!timeleft) {
2042 /* On timeout reset the board */ 2042 /* On timeout reset the board */
2043 mpt_free_msg_frame(ioc, mf); 2043 mpt_free_msg_frame(ioc, mf);
2044 mpt_HardResetHandler(ioc, CAN_SLEEP); 2044 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2045 error = -ETIMEDOUT; 2045 error = -ETIMEDOUT;
2046 goto out_unlock; 2046 goto out_unlock;
2047 } 2047 }
@@ -2226,7 +2226,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
2226 if (!timeleft) { 2226 if (!timeleft) {
2227 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__); 2227 printk(MYIOC_s_ERR_FMT "%s: smp timeout!\n", ioc->name, __func__);
2228 /* On timeout reset the board */ 2228 /* On timeout reset the board */
2229 mpt_HardResetHandler(ioc, CAN_SLEEP); 2229 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2230 ret = -ETIMEDOUT; 2230 ret = -ETIMEDOUT;
2231 goto unmap; 2231 goto unmap;
2232 } 2232 }
@@ -2833,7 +2833,7 @@ mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
2833 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET) 2833 if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
2834 goto out_free; 2834 goto out_free;
2835 if (!timeleft) 2835 if (!timeleft)
2836 mpt_HardResetHandler(ioc, CAN_SLEEP); 2836 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
2837 goto out_free; 2837 goto out_free;
2838 } 2838 }
2839 2839
@@ -4717,7 +4717,7 @@ mptsas_broadcast_primative_work(struct fw_event_work *fw_event)
4717 if (issue_reset) { 4717 if (issue_reset) {
4718 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", 4718 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
4719 ioc->name, __func__); 4719 ioc->name, __func__);
4720 mpt_HardResetHandler(ioc, CAN_SLEEP); 4720 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
4721 } 4721 }
4722 mptsas_free_fw_event(ioc, fw_event); 4722 mptsas_free_fw_event(ioc, fw_event);
4723} 4723}
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 6796597dcee0..929d584855d2 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1711,7 +1711,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun,
1711 if (issue_hard_reset) { 1711 if (issue_hard_reset) {
1712 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", 1712 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
1713 ioc->name, __func__); 1713 ioc->name, __func__);
1714 retval = mpt_HardResetHandler(ioc, CAN_SLEEP); 1714 retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1715 mpt_free_msg_frame(ioc, mf); 1715 mpt_free_msg_frame(ioc, mf);
1716 } 1716 }
1717 1717
@@ -1991,7 +1991,7 @@ mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1991 /* If our attempts to reset the host failed, then return a failed 1991 /* If our attempts to reset the host failed, then return a failed
1992 * status. The host will be taken off line by the SCSI mid-layer. 1992 * status. The host will be taken off line by the SCSI mid-layer.
1993 */ 1993 */
1994 retval = mpt_HardResetHandler(ioc, CAN_SLEEP); 1994 retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
1995 if (retval < 0) 1995 if (retval < 0)
1996 status = FAILED; 1996 status = FAILED;
1997 else 1997 else
@@ -3040,7 +3040,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3040 if (!timeleft) { 3040 if (!timeleft) {
3041 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n", 3041 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
3042 ioc->name, __func__); 3042 ioc->name, __func__);
3043 mpt_HardResetHandler(ioc, CAN_SLEEP); 3043 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
3044 mpt_free_msg_frame(ioc, mf); 3044 mpt_free_msg_frame(ioc, mf);
3045 } 3045 }
3046 goto out; 3046 goto out;