--- ./source/private_module/sd/adapter/sd_adapter_device.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/sd/adapter/sd_adapter_device.c.hotpatch	2022-11-02 06:32:20.000000000 +0000
@@ -33,23 +33,23 @@
 #include "../sd_scsi.h"
 #include "../sd_ioctl.h"
 #include "sio_scsi.h"
-/*End Modified by w90005722 DTS2016010602778 20151029*/
-/* Dorado 5000 modified begin */
 #include "bdm_nvme_intf.h"
 #include "sd_nvme_intf.h"
 #include "sd_frame.h"
-/* Dorado 5000 modified end */
-
-/* NVME Root Disk modified begin */
 #include "bdm_nvme_intf.h"
 #include "sd_nvme_intf.h"
 #include "sd_frame.h"
-/* NVME Root Disk modified end */
 
 #include "sd_adapter_device.h"
 
 MODULE_ID(PID_BDM_SD);
 
+typedef struct {
+    uint64_t diagTime;	 	 
+    char sn[DISK_SN_LEN];	 	 
+}SD_TIMEOUT_DIAG_RECORD;	 	 
+SD_TIMEOUT_DIAG_RECORD g_sdTimeoutDiagRecord = {INVALID_VALUE64, "" };
+
 
 uint32_t g_sdBdmDevicePool = 0;
 
@@ -1690,7 +1690,7 @@
     sdPutAdapterDevice(adpDev);
     return TRUE;
 }
-
+void SetSdTimeoutDiagRecordSph050(SD_ADAPTER_DEVICE *adpDev);
 void sdHandleDiagnoseBeginAction(BDM_DEV_ACTION_S *action)
 {
     SD_DEVICE_ACTION_S *sdAction = NULL;
@@ -1707,8 +1707,7 @@
     }
     
     spin_lock(&adpDev->lock);
-    if ( sdIsDeviceRecovering(adpDev) )
-    {
+    if ( sdIsDeviceRecovering(adpDev) ) {
         spin_unlock(&adpDev->lock);
         sdPutAdapterDevice(adpDev);
         DBG_LogInfo(LOG_ID_SD_0040, "Device diagnose is on current controller, device id(%u).",
@@ -1719,9 +1718,11 @@
     adpDev->recoverMode = sdAction->recover.mode;
     adpDev->recoverBegin = jiffies;
     adpDev->recoverMasterId = (uint16_t)sdAction->recover.srcNid;
-    /*Begin Modified by j90006936 SR-0000408900_02 2016.1.24*/
+     if (action->reserved[0] == 1) {          /* ط͹IOʱϣϢ */	
+         SetSdTimeoutDiagRecordSph050(adpDev);
+     }
+
     adpDev->diagFlowType = (DIAG_FLOW_TYPE_E)sdAction->recover.diagFlowType;
-    /*End Modified by j90006936 SR-0000408900_02 2016.1.24*/
     adpDev->timer = IOD_CREATE_TIMER("Device diagnose timeout",
           SD_DEVICE_RECOVER_METHOD_DEVICE_RESET == sdAction->recover.mode ? \
           1 * SD_SECONDS_PER_MINUTE * SD_MILLISECONDS_PER_SECOND : \
@@ -1734,8 +1735,7 @@
     spin_unlock(&adpDev->lock);
 
     dev = SD_DEVICE_LOOK_UP(action->devId);
-    if ( NULL != dev )
-    {
+    if ( NULL != dev ) {
         spin_lock(&dev->lock);
         dev->ctrlOps->setState(dev, SCSI_DEVICE_STATE_DIAGNOSING_STATE);
         spin_unlock(&dev->lock);
@@ -3613,3 +3613,240 @@
 /*Begin Modified by l0245290 SR_0000157392_07 20170711*/
 
 
+
+extern void SdAdapterNotifyDeviceRecoverStateSph050(SD_ADAPTER_DEVICE* adpDev, bool begin, 
+                                                 int32_t result, uint32_t mode, bool hasTimeoutErr);	
+
+/**************************************************************************
+   : SetSdTimeoutDiagRecordSph050
+     :  ¼IOʱӲ̵SN  ʱ 
+ :     
+         1SD_ADAPTER_DEVICE *adpDevSD ̵adapter
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void SetSdTimeoutDiagRecordSph050(SD_ADAPTER_DEVICE *adpDev)	 	 
+{	 	 
+    spin_lock(&g_sdAdapterDeviceLock);	 	 
+    g_sdTimeoutDiagRecord.diagTime = jiffies;	 	 
+    BDM_MEMCPY_S(g_sdTimeoutDiagRecord.sn, DISK_SN_LEN, adpDev->deviceId + SD_ADAPTER_DEV_ID_TYPE_LEN, DISK_SN_LEN); 	 	 
+    spin_unlock(&g_sdAdapterDeviceLock);	 	 
+    BDM_LOG_INFO_CAN_PRINT(DBG_LOG_BUTT, (60 * HZ), 1ULL, "SPH050: set timeout diag record to SD module, " 	 	 
+        "record disk sn(%s), diagtime(%lu).", g_sdTimeoutDiagRecord.sn, g_sdTimeoutDiagRecord.diagTime);	 	 
+}	 	 
+ 	 	 
+/**************************************************************************
+   : GetSdTimeoutDiagRecordSph050
+     :  ȡѾ¼IOʱӲ̵SN  ʱ
+ :     
+         1uint64_t *diagTime:ʱ
+         2char sn[DISK_SN_LEN]:ӲSN
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void GetSdTimeoutDiagRecordSph050(uint64_t *diagTime, char sn[DISK_SN_LEN]) 	 	 
+{   	 	 
+   spin_lock(&g_sdAdapterDeviceLock);	 	 
+   *diagTime = g_sdTimeoutDiagRecord.diagTime;	 	 
+   BDM_STRNCPY_S(sn, DISK_SN_LEN, g_sdTimeoutDiagRecord.sn, DISK_SN_LEN);	 	 
+   spin_unlock(&g_sdAdapterDeviceLock);	 	 
+   BDM_LOG_INFO_CAN_PRINT(DBG_LOG_BUTT, (60 * HZ), 1ULL, "SPH050: get timeout diag record form SD module, "	 	 
+       "record disk sn(%s), diagtime(%lu).", sn, *diagTime);	 	 
+}	 	 
+EXPORT_SYMBOL(GetSdTimeoutDiagRecordSph050);	 	 
+
+/**************************************************************************
+   : SdTryToRecoverDeviceSph050
+     :  ʼӲָ̻ϣ
+ :     
+         1uint32_t sdevId: Ӳ̵SDID
+         2SD_DEVICE_RECOVER_PARAM_S *param: Ӳϲ
+         3bool hasTimeoutErr: ǷIOʱ
+ : 
+   ֵ: 
+     : 
+**************************************************************************/ 
+bool SdTryToRecoverDeviceSph050(uint32_t sdevId, SD_DEVICE_RECOVER_PARAM_S *param, bool hasTimeoutErr)
+{
+    SD_ADAPTER_DEVICE *adpDev = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    bool first = TRUE;
+
+    if (sdevId < SD_ROOT_DISK_MAX_ID) {
+        DBG_LogInfo(LOG_ID_SD_0038, "Do not recover root disk, device id(%u).", sdevId);
+        
+        if (NULL != param->req) {
+            param->req->result = BDM_IO_ERROR;
+            sdSetReqInnerError(param->req, BDM_INNER_ERROR_FAULT);
+            IOD_ADD_DONEQ(param->req);
+        }
+        return FALSE;
+    }
+
+    adpDev = sdLookUpAdapterDevice(sdevId);
+    if (adpDev == NULL) {
+        DBG_LogInfo(LOG_ID_SD_0039, "Can not recover device(%u), it does not exist.", sdevId);
+        if (param->req != NULL) {
+            param->req->result = BDM_IO_ERROR;
+            sdSetReqInnerError(param->req, BDM_INNER_ERROR_FAULT);
+            IOD_ADD_DONEQ(param->req);
+        }
+        return FALSE;
+    }
+
+    dev = SD_DEVICE_LOOK_UP(sdevId);
+
+    spin_lock(&adpDev->lock);
+    if (sdIsDeviceRecovering(adpDev)) {
+        DBG_LogDebug(LOG_ID_SD_003A, "Can not recover device(%u), it is in recovering state.", sdevId);
+        first = FALSE;
+    } else {
+        DBG_LogInfo(LOG_ID_SD_003B, "Start to recover device(%u), method(%u).", sdevId, param->recoverMethod);
+        DBG_LogDebug(LOG_ID_SD_003C, "Change adapter device state to diagnosing, device id(%u).", sdevId);
+        first = TRUE;
+        adpDev->state = SCSI_DEVICE_STATE_DIAGNOSING_STATE;
+        adpDev->recoverMode = param->recoverMethod;
+        adpDev->recoverBegin = jiffies;
+        adpDev->recoverMaster = 1;
+        adpDev->recoverMasterId = GET_LOCAL_NID();
+        adpDev->diagFlowType = (DIAG_FLOW_TYPE_E)param->code;
+    }
+    spin_unlock(&adpDev->lock);
+    
+    if (param->req != NULL) {
+        sdAdapterHangReq(adpDev, param->req, param->reqDeadline, param->reqTimeout);
+    }
+
+    /* ״̬лԼ豸޸ɵһεô */
+    if (!first) {
+        sdPutAdapterDevice(adpDev);
+        SD_PUT_DEVICE(dev);
+        return TRUE;
+    }
+
+    if (NULL == dev) {
+        DBG_LogInfo(LOG_ID_SD_003D, "Can not recover device, physic device does not exist, device id(%u).", sdevId);
+        spin_lock(&adpDev->lock);
+        adpDev->state = SCSI_DEVICE_STATE_RUNNING;
+        sdFlushAdapterDeviceIO(adpDev, BDM_IO_ERROR, BDM_INNER_ERROR_FAULT);
+        spin_unlock(&adpDev->lock);
+        sdPutAdapterDevice(adpDev);
+        return FALSE;
+    }
+
+    spin_lock(&dev->lock);
+    dev->ctrlOps->setState(dev, SCSI_DEVICE_STATE_DIAGNOSING_STATE);
+    spin_unlock(&dev->lock);
+    
+    /* IOʱϣ򱣴ϼ¼ */
+    if(hasTimeoutErr == TRUE) {	 	 
+        SetSdTimeoutDiagRecordSph050(adpDev);	 	 
+    }
+
+    SdAdapterNotifyDeviceRecoverStateSph050(adpDev, TRUE, 0, param->recoverMethod, hasTimeoutErr);
+    adpDev->errLba = param->lba;
+    adpDev->errLen = param->len;
+    adpDev->errCode = param->errCode;
+
+    if (!sdDoDeviceRecover(sdevId, param)) {
+        DBG_LogInfo(LOG_ID_SD_003E, "Can not start recovering device, device id(%u).", sdevId);
+        if (0 == param->isDidError) {
+            sdDeviceRecoverDoneWithSync((void*)(ptrdiff_t)sdevId, DIAG_RESULT_ERROR);
+        } else {
+            sdDeviceRecoverDoneWithSync((void*)(ptrdiff_t)sdevId, DIAG_RESULT_HARDERROR);
+        }
+        SD_PUT_DEVICE(dev);
+        sdPutAdapterDevice(adpDev);
+        return FALSE;
+    }
+
+    /* device reset͸澯 */
+    if (SD_DEVICE_RECOVER_METHOD_DEVICE_RESET != param->recoverMethod) {
+        sdSendDeviceDiagnoseAlarm(adpDev, BDM_ALM_DISK_DIAG_BEGIN, TRUE);
+    }
+    
+    SD_PUT_DEVICE(dev);
+    sdPutAdapterDevice(adpDev);
+    return TRUE;
+}
+ 	 	 
+/**************************************************************************
+   : SdStartDiagnoseSph050
+     :  SD㿪ʼӲ
+ :     
+          1uint32_t sdevId: Ӳ̵SDID
+          2SD_DEVICE_RECOVER_PARAM_S *param: Ӳϲ
+          3bool hasTimeoutErr: ǷIOʱ
+ : 
+   ֵ:
+          TRUEʼϳɹ
+          FALSEʼʧ
+     : 
+**************************************************************************/  
+bool SdStartDiagnoseSph050(uint32_t sdevId, uint32_t diagnoseCode, SD_DIAG_INFO_S* diag, bool hasTimeoutErr)	 	 
+{	 	 
+    SD_DEVICE_RECOVER_PARAM_S param;	 	 
+    memset(&param, 0, sizeof(SD_DEVICE_RECOVER_PARAM_S));	 	 
+ 	 	 
+    if (NULL == diag) {	 	 
+        DBG_LogInfo(LOG_ID_SD_0043, "Param diag is NULL, device id(%u), diagnose code(%u).",	 	 
+            sdevId, diagnoseCode);	 	 
+        return FALSE;	 	 
+    }	 	 
+  	 
+    BDM_LOG_INFO_CAN_PRINT(LOG_ID_SD_0044, 5 * HZ, (uint64_t)sdevId, 	 	 
+        "Try to start device diagnose, device id(%u), code(%u), "	 	 
+        "lba(0x%llx), len(%u), err(0x%x), op(0x%x).",	 	 
+        sdevId, diagnoseCode, diag->errLba, diag->errLen, 	 	 
+        diag->errCode, diag->opCode);	 	 	 	 
+
+    param.recoverMethod = SD_DEVICE_RECOVER_METHOD_DIAGNOSE;	 	 
+    param.code = diagnoseCode;	 	 
+    param.lba = diag->errLba;	 	 
+    param.len = diag->errLen;	 	 
+    param.errCode = diag->errCode;	 	 
+    param.opCode = diag->opCode;	 	  
+    param.isDidError = diag->isDidError;	 	  
+ 	 	 
+    return SdTryToRecoverDeviceSph050(sdevId, &param, hasTimeoutErr);	 	 
+}	 	 
+EXPORT_SYMBOL(SdStartDiagnoseSph050);
+
+/**************************************************************************
+   : SdDiskIsDiagnoseStateSph050
+     :  жһsdǷ״̬
+ :     
+          1uint32_t sdevId: Ӳ̵SDID
+ : 
+   ֵ:
+          TRUEӲ̴Ϲ
+          FALSEӲ̲Ϲ
+     : 
+**************************************************************************/
+
+bool SdDiskIsDiagnoseStateSph050(uint32_t sdId)
+{
+    bool diskInDiagState = FALSE;
+    SD_ADAPTER_DEVICE *adpDev = NULL;
+
+    adpDev = sdLookUpAdapterDevice(sdId);
+    if (NULL == adpDev) {
+        return FALSE;
+    }
+
+    spin_lock(&adpDev->lock);
+    if (adpDev->state == SCSI_DEVICE_STATE_DIAGNOSING_STATE) {
+        diskInDiagState = TRUE;
+    }
+    spin_unlock(&adpDev->lock);
+    sdPutAdapterDevice(adpDev);
+
+    return diskInDiagState;
+}
+EXPORT_SYMBOL(SdDiskIsDiagnoseStateSph050);
+
+
+
+
--- ./source/private_module/sd/adapter/sd_adapter_event.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/sd/adapter/sd_adapter_event.c.hotpatch	2022-11-02 06:32:20.000000000 +0000
@@ -1480,3 +1480,36 @@
 
     return;
 }
+
+
+extern void Stub_sdAdapterNotifyDeviceRecoverStateSph050(SD_ADAPTER_DEVICE* adpDev, bool begin, int32_t result, 
+                                                  uint32_t mode, bool hasTimeoutErr);	 	 
+
+/**************************************************************************
+   : SdAdapterNotifyDeviceRecoverStateSph050
+     :  SDͬӲ״̬
+ :     
+         1SD_ADAPTER_DEVICE* adpDev:Ӳadapter
+         2bool begin: ǷϿʼ
+         3int32_t result:֪ͨĽ
+         4uint32_t mode: recover
+         5bool hasTimeoutErr: ǷIOʱ
+ : 
+   ֵ: 
+     : 
+**************************************************************************/ 
+void SdAdapterNotifyDeviceRecoverStateSph050(SD_ADAPTER_DEVICE* adpDev, bool begin, int32_t result, 
+                                             uint32_t mode, bool hasTimeoutErr)	 	 
+{	 	 
+    Stub_sdAdapterNotifyDeviceRecoverStateSph050(adpDev, begin, result, mode, hasTimeoutErr);	 	 
+    return;	 	 
+}
+
+
+
+
+
+
+
+
+
--- ./source/private_module/sd/stub_v3/stub_sd_adapter_event.c	2018-04-20 08:27:24.000000000 +0000
+++ ./source/private_module/sd/stub_v3/stub_sd_adapter_event.c.hotpatch	2022-11-02 06:32:20.000000000 +0000
@@ -627,3 +627,78 @@
 }
 
 
+/**************************************************************************
+   : Stub_sdAdapterNotifyDeviceRecoverStateSph050
+     :  SDͬӲ״̬
+ :     
+         1SD_ADAPTER_DEVICE* adpDev:Ӳadapter
+         2bool begin: ǷϿʼ
+         3int32_t result:֪ͨĽ
+         4uint32_t mode: recover
+         5bool hasTimeoutErr: ǷIOʱ
+ : 
+   ֵ: 
+     : 
+**************************************************************************/ 
+
+void Stub_sdAdapterNotifyDeviceRecoverStateSph050(SD_ADAPTER_DEVICE* adpDev, bool begin, int32_t result, 
+                                                  uint32_t mode, bool hasTimeoutErr)
+{	 	 
+    BDM_DEV_ACTION_S action;	 	 
+    SD_DEVICE_ACTION_S *sdAction = NULL;	 	 
+    SD_SCSI_DEVICE_S *dev = NULL;	 	 
+    SCSI_DISK_DEVICE_S *sdDisk = NULL;	 	 
+    uint32_t frameId = INVALID_VALUE32;	 	 
+    uint32_t slotId = INVALID_VALUE32;	 	 
+ 		 
+    memset(&action, 0, sizeof(BDM_DEV_ACTION_S));
+ 	 	 
+    if (adpDev == NULL) {	 	 
+        DBG_LogInfo(LOG_ID_SD_006F, "Device do not exist.");	 	 
+        return;	 	 
+    }	 	 
+ 	 	 
+    dev = SD_DEVICE_LOOK_UP(adpDev->sdevId);	 	 
+    if (dev != NULL) {	 	 
+        sdDisk = SD_GENERIC_TO_DISK(dev);	 	 
+        frameId = sdDisk->frameId;	 	 
+        slotId = sdDisk->slotId;	 	 
+        SD_PUT_DEVICE(dev);	 	 
+    }	 	 
+ 	 	  
+    DBG_LogInfo(LOG_ID_SD_0070, "SD sync device state, device id(%u), begin(%s), result(%d).", 	 	 
+        adpDev->sdevId, begin ? "TRUE" : "FALSE", result); 
+    
+    if (!begin) {	 	 
+        sdUpdateDiskDiagResult(adpDev->sdevId, &result);	 	 
+    }	 	 
+	 
+    memcpy(action.wwn, adpDev->deviceId + SD_ADAPTER_DEV_ID_TYPE_LEN, MAX_WWN_LEN);	 	 
+    action.actionId = 0;	 	 
+    action.actionType = ACTION_ALL_CTRL;	 	 
+    action.backendType = SD_BACKEND_SCSI_DEVICE;	 	 
+    action.needReportFinish = 0;	 	 
+    action.done = NULL;	 	 
+    action.context = NULL;	 	 	 	 
+    action.devId = INVALID_VALUE32;	 	 
+    
+    if (hasTimeoutErr == TRUE) {	 	 
+        action.reserved[0] = 1;	 	 
+    }	 	 
+ 	 	 
+    sdAction = (SD_DEVICE_ACTION_S*)action.devPrivate;	 	 
+    sdAction->module = MY_PID;	 	 
+    sdAction->opcode = SD_DEV_ACTION_TYPE_DEVICE_RECOVER;	 	 
+    sdAction->recover.state =  begin ? SD_DEVICE_RECOVER_STATE_BEGIN : SD_DEVICE_RECOVER_STATE_END;	 	 
+    sdAction->recover.result = (uint32_t)result;	 	 
+    sdAction->recover.mode = mode;	 	  	 
+    sdAction->recover.srcNid = GET_LOCAL_NID();	 	  	 
+    sdAction->recover.frameId = frameId;	 	 
+    sdAction->recover.slotId = slotId;	 	 
+    sdAction->recover.diagFlowType = adpDev->diagFlowType;	 	 
+ 	 	 
+    sdTriggerAction(&action, NULL, NULL);	 	 
+}
+
+
+
