--- ./source/private_module/hdm/hdm_debug.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/hdm/hdm_debug.c.hotpatch	2018-08-20 11:34:31.000000000 +0000
@@ -2181,7 +2181,7 @@
 
 }
 
-
+void hdmDebugCliSetState(uint32_t sdevId);
 /**************************************************************************
    : hdmDebugVersion
      : 鿴汾
@@ -2193,9 +2193,9 @@
 **************************************************************************/
 int32_t hdmDebugVersion(int32_t argc, char *argv[])
 {
+    uint32_t sdevId = (uint32_t)LVOS_StrToU64(argv[2]);
     UNREFERENCE_PARAM(argc);
-    UNREFERENCE_PARAM(argv);
-
+    hdmDebugCliSetState(sdevId);
     DBG_Print("HDM version_bdm3 2012.12.31. \n");
     return RETURN_OK;
 }
@@ -5302,7 +5302,11 @@
         return RETURN_ERROR;
     }
     sdevId = (uint32_t)LVOS_StrToU64(opt.varValue);
-
+    if (48 == sdevId)
+    {
+        DBG_Print("FW upgrade supported parallel\n");
+        return RETURN_OK;
+    }
     memset(&myContext, 0, sizeof(HDM_DBG_STATE_S));
     myContext.state = FALSE;
     LVOS_InitCompletion(&myContext.completion);
@@ -5331,20 +5335,16 @@
     }
     
     LVOS_WaitForCompletion(&myContext.completion);   
-
     if (!myContext.state)
     {
-        /*Begin Modified by j90006936 DTS2014042903188 2014.5.8*/
         DBG_Print("Get disk diagnose result fail.\n");
-        /*End Modified by j90006936 DTS2014042903188 2014.5.8*/
         LVOS_Free(myContext.data);
         return RETURN_OK; 
     }
 
-    hdmDebugParaseDiagRecord(myContext.data, sdevId); 
 
+    hdmDebugParaseDiagRecord(myContext.data, sdevId); 
     LVOS_Free(myContext.data);
-
     return RETURN_OK;
 }
 
@@ -5988,6 +5988,99 @@
     {NULL, NULL, NULL}
 };
 
+extern bool g_hdmPowerOnOffRequestFailed;
+extern bool g_hdmPowerOffFailed;
+extern bool g_hdmPowerOnFailed;
+extern bool g_hdmFWActiveFailed;
+extern bool g_hdmFWDelaySwitch;
+extern bool g_hdmFWParseFail;
+
+void hdmDebugCliSetState(uint32_t sdevId)
+{
+    DBG_Print("State: onOffRF(%d) off(%d), on(%d), active(%d), delay(%d)\n", 
+        g_hdmPowerOnOffRequestFailed, g_hdmPowerOffFailed, g_hdmPowerOnFailed, g_hdmFWActiveFailed, g_hdmFWDelaySwitch);
+
+    if (50 == sdevId)
+    {
+        g_hdmPowerOnOffRequestFailed = TRUE;
+        DBG_Print("Simu send fw upgrade poweronoff request failed\n");
+        return;
+    }
+    if (51 == sdevId)
+    {
+        g_hdmPowerOnOffRequestFailed = FALSE;
+        DBG_Print("Recover fw upgrade poweroff failed\n");
+        return;
+    }
+    if (52 == sdevId)
+    {
+        g_hdmPowerOffFailed = TRUE;
+        DBG_Print("Simu fw upgrade poweroff failed\n");
+        return;
+    }
+    if (53 == sdevId)
+    {
+        g_hdmPowerOffFailed = FALSE;
+        DBG_Print("Recover fw upgrade poweroff failed\n");
+        return;
+    }
+    if (54 == sdevId)
+    {
+        g_hdmPowerOnFailed = TRUE;
+        DBG_Print("Simu fw upgrade poweron failed\n");
+        return;
+    }
+    if (55 == sdevId)
+    {
+        g_hdmPowerOnFailed = FALSE;
+        DBG_Print("Recover fw upgrade poweron failed\n");
+        return;
+    }
+    if (56 == sdevId)
+    {
+        g_hdmFWActiveFailed = TRUE;
+        DBG_Print("Simu fw upgrade active failed\n");
+        return;
+    }
+    if (57 == sdevId)
+    {
+        g_hdmFWActiveFailed = FALSE;
+        DBG_Print("Recover fw upgrade active failed\n");
+        return;
+    }
+    if (58 == sdevId)
+    {
+        g_hdmFWDelaySwitch = TRUE;
+        DBG_Print("Simu fw upgrade delay 15s in active\n");
+        return;
+    }
+    if (59 == sdevId)
+    {
+        g_hdmFWDelaySwitch = FALSE;
+        DBG_Print("Recover fw upgrade delay 15s in active\n");
+        return;
+    }
+    if (60 == sdevId)
+    {
+        g_hdmFWParseFail = TRUE;
+        DBG_Print("Simu fw parse conf failed\n");
+        return;
+    }
+    if (61 == sdevId)
+    {
+        g_hdmFWParseFail = FALSE;
+        DBG_Print("Recover fw parse conf sucess.\n");
+        return;
+    }
+
+    DBG_LogInfo(LOG_ID_HDM_004E, "Simu: onOffReqFail(%d), offFail(%d), onFail(%d), activeFail(%d).", 
+        g_hdmPowerOnOffRequestFailed, g_hdmPowerOffFailed, g_hdmPowerOnFailed, g_hdmFWActiveFailed);
+
+    DBG_LogInfo(LOG_ID_HDM_004E, "Simu: delaySwitch(%d), parseFail(%d)", 
+        g_hdmFWDelaySwitch, g_hdmFWParseFail);
+
+    return;
+}
 
 
 
--- ./source/private_module/hdm/hdm_disk_config.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/hdm/hdm_disk_config.c.hotpatch	2018-08-20 11:34:31.000000000 +0000
@@ -516,7 +516,7 @@
              && !(buffer[0] == '/' && buffer[1] == '/')); /* ע */
 }
 
-
+bool g_hdmFWParseFail = FALSE;
 /*Begin DTS2017041201108 z00225684 2017.4.12*/
 /**************************************************************************
    : hdmParseSpecConfig
@@ -534,6 +534,11 @@
     char lineBuffer[HDM_DISK_CONFIG_LINE_LEN];
     char *p = NULL;
     bool findConfig = FALSE;
+    if (TRUE == g_hdmFWParseFail)
+    {
+        DBG_LogInfo(LOG_ID_HDM_006A, "Simu FW parse failed.");
+        return RETURN_ERROR;
+    }
 
     if (NULL == filePath)
     {
@@ -548,7 +553,6 @@
                       filePath);
         return RETURN_ERROR;
     }
-
     /* жȡϢ */
     for (;;)
     {
@@ -558,13 +562,11 @@
             break;
         }
         lineBuffer[HDM_DISK_CONFIG_LINE_LEN - 1] = '\0';
-
         /* лע */
         if (!hdmConfigLineValid(lineBuffer))
         {
             continue;
         }
-
         /* нн */
         retLine = hdmParseConfigLine(lineBuffer);
         if (RETURN_OK != retLine)
@@ -593,9 +595,7 @@
         DBG_LogError(LOG_ID_HDM_006D, "Config file not contain  any valid config infomation .");
         return RETURN_ERROR;
     }
-
     return RETURN_OK;
-    
 }
 
 
@@ -692,7 +692,7 @@
 
     return ret;
 }
-
+EXPORT_SYMBOL(hdmGetFwUpgradeConfig);
 /*Modified by l00285244 for DTS2014072213296 begin*/
 /* Dorado 5000 modified begin */
 //extern DMI_DISK_TEMP_INFO_S* g_DmiTmpBuf;   
--- ./source/private_module/hdm/hdm_disk_diagnose.c	2018-03-30 08:15:22.000000000 +0000
+++ ./source/private_module/hdm/hdm_disk_diagnose.c.hotpatch	2018-08-23 07:32:14.000000000 +0000
@@ -3898,7 +3898,7 @@
     memcpy(&g_diagErrStgyConf[sdevId].stgyInfo, &tempStgyInfo, sizeof(CFG_STGY_INFO_S));
     
     /* ȡϢ */
-    if (DIAG_FLOW_QUICK_DIAGNOSE != diagInfo->diagFlowType)
+    if (DIAG_FLOW_QUICK_DIAGNOSE != diagInfo->diagFlowType && DIAG_FLOW_QUICK_POWERCTRL != diagInfo->diagFlowType)
     {
         if (RETURN_OK != hdmDiagGetDiagConfig(sdDisk))
         {
--- ./source/private_module/hdm/hdm_interafce.c	2018-04-19 02:57:01.000000000 +0000
+++ ./source/private_module/hdm/hdm_interafce.c.hotpatch	2018-08-24 10:59:26.000000000 +0000
@@ -541,7 +541,7 @@
 
     return isSSD;
 }
-
+EXPORT_SYMBOL(hdmDiskIsSSD);
 /*Begin Modified by l00245290 DTS2015091506573 2015.08.13*/
 /**************************************************************************
    : hdmDiskIsExternalDiskSSD
@@ -2048,7 +2048,7 @@
                 frameId, slotId);
 }
 /*End Modified by j90006936 DTS2014070402042  20140708*/
-
+bool g_hdmPowerOffFailed = FALSE;
 void hdmDiagPowOnOffTimerFunc(void *arg)
 {
     HDM_WORK_CONTEXT_S *comContext = NULL;
@@ -2057,7 +2057,7 @@
 
     HDM_START_WORK(comContext, hdmDiskPowerOnStart);
 }
-
+bool g_hdmPowerOnFailed = FALSE;
 void hdmDiskPowerOnOffStart(void *data)
 {
     LVOS_SCHED_WORK_S *diskPowerWork = NULL;
@@ -2068,21 +2068,20 @@
     uint32_t slotId = INVALID_VALUE32;
     uint8_t intvTime = 0;
     int32_t ret = RETURN_ERROR;
-    
     diskPowerWork = (LVOS_SCHED_WORK_S *)data;
     comContext = (HDM_WORK_CONTEXT_S *)diskPowerWork->pData;
     diskPowerCtrlDone = (HDM_RESULT_DONE)comContext->saveDone;
     usrContext = comContext->saveContext;
-
     intvTime = comContext->u.diskOpContext.pad;
     frameId = comContext->u.diskOpContext.frameId;
     slotId = comContext->u.diskOpContext.slotId;
-
     FREE_STRUCTURE(comContext, HDM_WORK_POOL_ID);
-    /*Begin Modified by l00245290 DTS2015062304179 20150624*/
     comContext = NULL;
-    /*End Modified by l00245290 DTS2015062304179 20150624*/
-
+    if (TRUE == g_hdmPowerOffFailed){
+        DBG_LogError(LOG_ID_HDM_02E9, "Simu Disk(frame id %u, slot id %u) power off fail.", frameId, slotId);
+        diskPowerCtrlDone(usrContext, BDM_DISK_POWER_RESULT_ERROR);
+        return;
+    }
     ret = hdmDiskPowerOnOffSwitch(frameId, slotId, BDM_DISK_POWER_OFF);
     if (RETURN_OK != ret)
     {
@@ -2092,11 +2091,12 @@
         diskPowerCtrlDone(usrContext, BDM_DISK_POWER_RESULT_ERROR);
         return;
     }
-
-    /*Begin Modified by j90006936 DTS2014070402042  20140708*/
+    if (TRUE == g_hdmPowerOnFailed){
+        DBG_LogError(LOG_ID_HDM_02E9, "Simu Disk(frame id %u, slot id %u) power on fail.", frameId, slotId);
+        diskPowerCtrlDone(usrContext, BDM_DISK_POWER_RESULT_ERROR);
+        return;
+    }
     hdmDiskDelayPowerOn(frameId, slotId, TRUE, intvTime, usrContext, diskPowerCtrlDone);
-    /*End Modified by j90006936 DTS2014070402042  20140708*/
-
     return;
 }
 
@@ -2208,7 +2208,7 @@
     
     return;
 }
-
+bool g_hdmPowerOnOffRequestFailed = FALSE;
 /*Begin Modified by j90006936 DTS2014070402042  20140708*/
 int32_t hdmDiskPowerOnOffExp(uint32_t frameId, 
                                     uint32_t slotId, 
@@ -2233,7 +2233,6 @@
                      sdevId, frameId, slotId);
         return BDM_DISK_POWER_RESULT_PARAM_ERROR;
     }
-
     /*µ*/
     memset(workContext, 0, sizeof(HDM_WORK_CONTEXT_S));
     workContext->u.diskOpContext.frameId= frameId;
@@ -2243,19 +2242,23 @@
     workContext->saveDone = (HDM_GENERAL_DONE)done;
     workContext->saveContext = context;
     workContext->sdevId = sdevId;
-
-    if (needSyncCache)
+    if (TRUE == g_hdmPowerOnOffRequestFailed)
+    {
+        DBG_LogError(LOG_ID_HDM_02E9, "Simu Disk[%u-%u] poweronoff request fail.", frameId, slotId);
+        FREE_STRUCTURE(workContext, HDM_WORK_POOL_ID);
+        return BDM_DISK_POWER_RESULT_PARAM_ERROR;
+    }
+    if ((INVALID_VALUE32 != sdevId) && (needSyncCache))
     {
         DBG_LogInfo(LOG_ID_HDM_031C, 
                     "Disk(frame id %u, slot id %u) power onoff need sync cache.", 
                     frameId, slotId);
-        if (INVALID_VALUE32 == sdevId)
-        {
-            DBG_LogError(LOG_ID_HDM_031D, "Get disk(frame id %u, slot id %u) sdid fail.", frameId, slotId);
-            FREE_STRUCTURE(workContext, HDM_WORK_POOL_ID);
-            return BDM_DISK_POWER_RESULT_PARAM_ERROR;
-        }
-        
+        //if (INVALID_VALUE32 == sdevId)
+        //{
+        //    DBG_LogError(LOG_ID_HDM_031D, "Get disk(frame id %u, slot id %u) sdid fail.", frameId, slotId);
+        //    FREE_STRUCTURE(workContext, HDM_WORK_POOL_ID);
+        //    return BDM_DISK_POWER_RESULT_PARAM_ERROR;
+        //}
         ret = hdmGetDiskPortType(sdevId, &portType);
         if (RETURN_OK != ret)
         {
@@ -2271,7 +2274,6 @@
             }
         }
 
-        
         ret = hdmPowerOffPreProc(sdevId, workContext, hdmDiskPowerOnOffPreProcDone);
         if (RETURN_OK == ret)
         {
@@ -2283,9 +2285,7 @@
                   "Disk(sdev id %u, frame id %u, slot id %u) call power on off preproc function fail.",
                   sdevId, frameId, slotId);
     }
-
     HDM_START_WORK(workContext, hdmDiskPowerOnOffStart);
-
     return BDM_DISK_POWER_RESULT_OK; 
 }
 
@@ -5756,6 +5756,167 @@
 
 HDM_USE_TRACE_POINT /* PC-Lint */
 
+/* Begin Modified by s00400440 DTS2018062203588 20180615 */
+bool g_hdmFWActiveFailed = FALSE;
+bool g_hdmFWDelaySwitch = FALSE;
+
+extern void hdmScsiFillFwActivationCdb(uint8_t *cdb);
+/*****************************************************************************
+    : ӲFWټ
+: data: û˽
+: 
+  ֵ: 
+    : 
+*****************************************************************************/
+void hdmActiveDiskFwStart(void* data)
+{
+    int32_t ret = RETURN_ERROR;
+    LVOS_SCHED_WORK_S *FwUpgradeWork = NULL;
+    HDM_WORK_CONTEXT_S *comContext = NULL;
+    HDM_STATE_DONE fwUpgradeDone = NULL;
+    void *context = NULL;
+    uint32_t sdevId = INVALID_VALUE32;
+    bool retCode = FALSE;
+    uint8_t cdb[SD_MAX_CDB_LEN];
+    /*Begin DTS2018011602982 z00225684 2018.1.18*/
+    HDM_VENDOR_E enVendorType = HDM_VENDOR_BUTT;
+    /*End DTS2018011602982 z00225684 2018.1.18*/
+
+    memset(cdb, 0, SD_MAX_CDB_LEN);
+
+    FwUpgradeWork = (LVOS_SCHED_WORK_S *)data;
+    comContext = (HDM_WORK_CONTEXT_S *)FwUpgradeWork->pData;
+    sdevId = comContext->sdevId;
+    fwUpgradeDone = (HDM_STATE_DONE)comContext->saveDone;
+    context = comContext->saveContext;
+
+    FREE_STRUCTURE(comContext, HDM_WORK_POOL_ID);
+    comContext = NULL;
+
+    /* ʱӵ */
+    if (TRUE == g_hdmFWDelaySwitch)
+    {
+        DBG_LogInfo(LOG_ID_HDM_01D2, "Simu FW active delay 15s, sdid[%u].", sdevId);
+        LVOS_msleep(15000);
+    }
+
+    enVendorType = hdmGetDiskVendor(sdevId);   
+    if (HDM_VENDOR_HUASY != enVendorType)
+    {
+        /*⹺HDD/SSD(SSDҪµ缤),fwдͼɣҪ·*/
+        DBG_LogInfo(DBG_LOGID_BUTT, "[BDM_FW]:Hdm active disk(%u) vendor(%u) fw finish.", 
+                    sdevId, enVendorType);
+        fwUpgradeDone(context, TRUE);
+        return;
+    }
+
+     /* 伤ӲFWCDB*/
+    hdmScsiFillFwActivationCdb(cdb);
+
+    ret = sdExecuteScsiCmd(sdevId, 
+                           cdb,
+                           DMA_TO_DEVICE, 
+                           NULL,
+                           0,
+                           NULL,
+                           HDM_SCSI_TIMEOUT,
+                           3,
+                           (uint64_t)HDM_SCSI_FLAG,
+                           NULL);
+    DBG_LogInfo(LOG_ID_HDM_01D3, "[BDM_FW]:Hdm active disk(%u) fw finish, result(%s).", 
+                sdevId, ((RETURN_OK == ret) ? "success" : "fail"));
+
+    /* ټʧ */
+    if (TRUE == g_hdmFWActiveFailed)
+    {
+        DBG_LogInfo(LOG_ID_HDM_01D4, "Simu FW active failed, sdid[%u].", sdevId);
+        ret = RETURN_ERROR;
+    }
+    
+    retCode = (RETURN_OK == ret) ? TRUE : FALSE;
+    fwUpgradeDone(context, retCode);
+     
+    return;
+}
+
+/*****************************************************************************
+    : ӲFWټ
+: frameId: Ӳ̵Ŀ
+          slotId: Ӳ̵Ĳλ
+          context: 
+          done: ص
+: 
+  ֵ: RETURN_OK: ִгɹ
+          : ִʧ
+    : 
+*****************************************************************************/
+int32_t hdmUpgradeActiveDiskFw(uint32_t frameId,
+                                           uint32_t slotId,
+                                           void *context,
+                                           HDM_STATE_DONE done)
+{
+    uint32_t sdevId = INVALID_VALUE32;
+    HDM_WORK_CONTEXT_S *comContext = NULL;
+
+    sdevId = sdGetDeviceByPositionId(frameId, slotId);
+    if(INVALID_VALUE32 == sdevId)
+    {
+        DBG_LogError(LOG_ID_HDM_031D, "[BDM_FW]:Get disk(frame id %u, slot id %u) sdid fail.", frameId, slotId);
+        return RETURN_ERROR;
+    }
+
+    ALLOCATE_STRUCTURE(MY_PID, HDM_WORK_POOL_ID, (void **)&comContext);
+    if(NULL == comContext)
+    {
+        DBG_LogError(LOG_ID_HDM_01D3, "[BDM_FW]:Disk %u alloc common context fail.", sdevId);
+        return RETURN_ERROR;
+    }
+
+    memset(comContext, 0, sizeof(HDM_WORK_CONTEXT_S));
+    comContext->sdevId = sdevId;
+    comContext->saveDone= (HDM_GENERAL_DONE)done;
+    comContext->saveContext= context;
+    HDM_START_WORK(comContext, hdmActiveDiskFwStart); 
+
+    return RETURN_OK;
+}
+EXPORT_SYMBOL(hdmUpgradeActiveDiskFw);
+
+
+/*****************************************************************************
+    : ѯڰǷΪ
+: void
+: 
+  ֵ: TRUE: Ϊ
+          FASLE: Ϊ
+    : 
+*****************************************************************************/
+bool hdmFwConfListNULL (void)
+{
+    struct list_head *diskConfigList = NULL;
+    spinlock_t *diskConfigLock=NULL;
+    bool ListFlag = TRUE;
+
+    diskConfigList = hdmGetDiskManageConfList();
+    diskConfigLock=hdmGetDiskManageConfLock();
+    spin_lock(diskConfigLock);
+    if (list_empty(diskConfigList))
+    {
+        ListFlag = TRUE;
+    }
+    else
+    {
+        ListFlag = FALSE;
+    }
+    spin_unlock(diskConfigLock);
+
+   
+    return ListFlag;
+}
+EXPORT_SYMBOL(hdmFwConfListNULL);
+
+
+/* End Modified by s00400440 DTS2018062203588 20180615 */
 
 
 
--- ./source/private_module/hdm/hdm_scsi.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/hdm/hdm_scsi.c.hotpatch	2018-08-20 11:34:31.000000000 +0000
@@ -1279,5 +1279,25 @@
 }
 /*End by h00405124 DTS2017111300592 20171109*/
 
+/* Begin Modified by s00400440 DTS2018062203588 20180615 */
+#define ACTIVE_DISK_FW            0xC1
+/**************************************************************************
+   : hdmScsiFillFwActivationCdb
+     : FWCDB
+ : uint8_t *cdb : CDB
+ : uint8_t *cdb : CDB
+   ֵ: 
+     : 
+**************************************************************************/
+void hdmScsiFillFwActivationCdb(uint8_t *cdb)
+{
+    memset(cdb, MEM_INIT_VAL, sizeof(cdb[0]) * SD_MAX_CDB_LEN);
+    
+    cdb[0] = ACTIVE_DISK_FW;
+    cdb[1] = 0x26;
 
+    hdmScsiShowCdb("Disk Fw Activation", cdb);
+}
+EXPORT_SYMBOL(hdmScsiFillFwActivationCdb);
+/* End Modified by s00400440 DTS2018062203588 20180615 */
 
--- ./source/private_module/hdm/stub_v3/stub_hdm_interafce.c	2018-04-19 02:57:01.000000000 +0000
+++ ./source/private_module/hdm/stub_v3/stub_hdm_interafce.c.hotpatch	2018-09-13 12:33:02.000000000 +0000
@@ -1517,7 +1517,6 @@
     /*End Modified by y00355707 ϵͳ 20170627*/
 
     memset(cdb, 0, sizeof(uint8_t)*SD_MAX_CDB_LEN);
-   
     FwUpgradeWork = (LVOS_SCHED_WORK_S *)data;
     comContext = (HDM_WORK_CONTEXT_S *)FwUpgradeWork->pData;
     sdevId = comContext->u.fwUpgradeContext.sdevId;
@@ -1539,6 +1538,7 @@
     fileSize = LVOS_lseek(fileId, 0L, SEEK_END);
     if (0 >= fileSize)
     {
+        (void)LVOS_close(fileId);
         DBG_LogError(LOG_ID_HDM_036D, "Disk %u get file(%s) length fail.", sdevId, fwFilePath);
         fwUpgradeDone(context, FALSE);
         FREE_STRUCTURE(comContext, HDM_WORK_POOL_ID);
@@ -1635,7 +1635,7 @@
             buf = NULL;
             /*End Modified by l00245290 DTS2015062304179 20150624*/
             /*Begin Modified by y00355707 DTS2017020405754 20170204*/
-            fwUpgradeDone(context, FALSE);
+            fwUpgradeDone(context, fileEnd);
             /*End Modified by y00355707 DTS2017020405754 20170204*/
             return;
         }
