aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion')
-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;