--- ./source/private_module/bdm/protocol/nvme/sd/sd_nvme_upgrade.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/bdm/protocol/nvme/sd/sd_nvme_upgrade.c.hotpatch	2018-08-24 10:59:26.000000000 +0000
@@ -1,15 +1,5 @@
-/**************************************************************************
 
-                  Ȩ (C), 2012-2012, Ϊּ(ɶ)޹˾
 
-***************************************************************************
-    : sd_nvme_upgrade.c
-    : 
-      : m00355150
-  : 201736
-  : NVMe SD豸upgradeʵ
-      ע: 
-**************************************************************************/
 #include "lvos.h"
 #include "framework/cmm.h"
 #include "bdm_inner_intf.h"
@@ -35,18 +25,28 @@
 extern uint32_t g_sdUpgradeFwPoolId;
 
 /* Ҫʹõⲿ */
-extern void sdUpgradeFWResetCallback(void *context, int32_t state);
-extern void sdDiskUpgradeFreeRes(SD_SCSI_DEVICE_S *dev, SD_UPGRADE_FW_PARAM_S *param);
+typedef struct tagSD_UPGRADE_FW_NEW_PARAM_S
+{
+    struct list_head head;
+    uint32_t sdId;
+    uint16_t times;
+    CMD_S cmd;
+    char fw[DISK_FIRMWARE_LEN];
+    void *context;
+    SD_UPGRADE_TYPE_E upgradeType;
+    SD_UPGRADE_DONE callBack;
+    uint32_t frameId;
+    uint32_t slotId;
+    uint8_t getFwTimes;
+    uint8_t upgradeMode;
+    uint8_t wwn[MAX_WWN_LEN];
+    DISK_TYPE_E diskType;
+} SD_UPGRADE_FW_NEW_PARAM_S;
+
+extern void sdUpgradeFWResetNewCallback(void *context, int32_t state);
+extern void sdDiskUpgradeFreeNewRes(SD_SCSI_DEVICE_S *dev, SD_UPGRADE_FW_NEW_PARAM_S *param);
+extern void sdUpgradeFreeNewParam(SD_UPGRADE_FW_NEW_PARAM_S *param);
 
-/**************************************************************************
-   : sdNvmeUpgradeDoneBySdId
-     : 
- : sdId   id
-           result    
- : 
-   ֵ: 
-     : 
-**************************************************************************/
 void sdNvmeUpgradeDoneBySdId(uint32_t sdId, uint32_t result)
 {
     /* ֮Ҫָ״̬ǵ */
@@ -105,7 +105,7 @@
 
     return;
 }
-
+void sdNvmeDiskUpgradeNewFreeList(SD_UPGRADE_FW_NEW_PARAM_S *param);
 /**************************************************************************
 *     : ̡ͺš̼汾Ϣ
 * : identifyInfo
@@ -168,7 +168,7 @@
 void sdNvmeRootDiskFwBackUpd(uint32_t sdevId ,void *context, int32_t result)
 {
     SD_SYNC_CALL_PARAM_S *backContext = NULL;
-    SD_UPGRADE_FW_PARAM_S *param = context;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
     SD_UPGRADE_DONE callBack = NULL;
 
     backContext = param->context;
@@ -178,7 +178,7 @@
     /*ָ״̬ϱrecover¼*/
     sdRcvDeviceFWUpgradeDone(sdevId, RETURN_OK);
     /*ͷԴ*/
-    sdNvmeDiskUpgradeFreeList(param);
+    sdUpgradeFreeNewParam(param);
    
     callBack(result, (void *)backContext);
 
@@ -584,17 +584,17 @@
 *****************************************************************************/
 void sdDiskPowerResetOnline(SCSI_DISK_DEVICE_S *disk, SD_SCSI_DEVICE_S *dev, void *context)
 {
-    SD_UPGRADE_FW_PARAM_S *param = context;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
     int ret = RETURN_ERROR;
 
-    ret = HDM_POWER_CTRL_EX(disk->frameId, disk->slotId, 0, BDM_DISK_POWER_RESET, TRUE, context, sdUpgradeFWResetCallback);
+    ret = HDM_POWER_CTRL_EX(disk->frameId, disk->slotId, 0, BDM_DISK_POWER_RESET, TRUE, context, sdUpgradeFWResetNewCallback);
     if (RETURN_OK != ret)
     {
         DBG_LogError(LOG_ID_SD_05A2, NVME_UP_PREFIX"Upgrade disk(sd: %d, frame: %d, slot: %d) fw online reset failed(%d).",
                      dev->sdevId, disk->frameId, disk->slotId, ret);
         /*Begin Modified by s00400440 DTS2018010604350 20180106*/
         param->callBack(UPGRADE_DISK_FW_RESU_SUCCESS, param->context);
-        sdDiskUpgradeFreeRes(dev, param);
+        sdDiskUpgradeFreeNewRes(dev, param);
         /*End Modified by s00400440 DTS2018010604350 20180106*/
     }
 
@@ -615,12 +615,12 @@
 *****************************************************************************/
 void sdDiskPowerResetOffline(SCSI_DISK_DEVICE_S *disk, SD_SCSI_DEVICE_S *dev, void *context)
 {
-    SD_UPGRADE_FW_PARAM_S *param = context;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
     int ret = RETURN_ERROR;
 
     UNREFERENCE_PARAM(dev);
     
-    ret = HDM_POWER_CTRL_EX(disk->frameId, disk->slotId, 0, BDM_DISK_POWER_RESET, TRUE, NULL, sdUpgradeFWResetCallback);
+    ret = HDM_POWER_CTRL_EX(disk->frameId, disk->slotId, 0, BDM_DISK_POWER_RESET, TRUE, NULL, sdUpgradeFWResetNewCallback);
     if (RETURN_OK != ret)
     {
         DBG_LogError(LOG_ID_SD_05A2, NVME_UP_PREFIX"Upgrade disk(sd: %d, frame: %d, slot: %d) fw offline reset failed(%d).",
@@ -747,7 +747,7 @@
 *****************************************************************************/
 void sdNvmeDiskUpgrade(SCSI_DISK_DEVICE_S *disk, SD_SCSI_DEVICE_S *dev, void *context, bool online)
 {
-    SD_UPGRADE_FW_PARAM_S *param = context;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
     int32_t ret = RETURN_ERROR;
     uint32_t sdId = param->sdId;
     UPDATE_FW_VERSION_CTX_S ctx;
@@ -809,7 +809,7 @@
         DBG_LogInfo(LOG_ID_SD_059D, "Upgrade %s, nvme disk(sd: %u frame: %d, slot: %d) end.",
                     "online", sdId, ctx.frameId, ctx.slotId);
 
-        sdNvmeDiskUpgradeFreeList(param);
+        sdNvmeDiskUpgradeNewFreeList(param);
         return;
         /*End Modified by s00400440 DTS2018010604350 20180106*/
     }
@@ -823,3 +823,45 @@
     return;
 }
 
+
+/*Begin Modified by s00400440 DTS2018081310126 20180808*/
+/*****************************************************************************
+    : NVMeӲFWȫֶȡڵ㲢ͷ
+: param
+: 
+  ֵ: 
+    : 
+*****************************************************************************/
+void sdNvmeDiskUpgradeNewFreeList(SD_UPGRADE_FW_NEW_PARAM_S *param)
+{
+    if (NULL == param)
+    {
+        return;
+    }
+
+    UNREFERENCE_PARAM(param->sdId);
+    UNREFERENCE_PARAM(param->times);
+    UNREFERENCE_PARAM(param->cmd);
+    UNREFERENCE_PARAM(param->fw);
+    UNREFERENCE_PARAM(param->context);
+    UNREFERENCE_PARAM(param->upgradeType);
+    UNREFERENCE_PARAM(param->callBack);
+    UNREFERENCE_PARAM(param->frameId);
+    UNREFERENCE_PARAM(param->slotId);
+    UNREFERENCE_PARAM(param->getFwTimes);
+    UNREFERENCE_PARAM(param->upgradeMode);
+    UNREFERENCE_PARAM(param->wwn);
+    UNREFERENCE_PARAM(param->diskType);
+
+    /*ȫֶȡ²ͷ*/
+    spin_lock(&g_sdUpgradeFwListLock);
+    list_del(&param->head);
+    FREE_STRUCTURE(param, g_sdUpgradeFwPoolId);
+    param = NULL;
+    spin_unlock(&g_sdUpgradeFwListLock);
+
+    return;
+}
+/*End Modified by s00400440 DTS2018081310126 20180808*/
+
+
--- ./source/private_module/bdm/sdm/sd/adapter/sd_adapter_device.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/bdm/sdm/sd/adapter/sd_adapter_device.c.hotpatch	2018-08-23 07:32:14.000000000 +0000
@@ -1991,7 +1991,7 @@
     adpDev = sdLookUpAdapterDevice(sdId);
     if (NULL == adpDev)
     {
-        DBG_LogInfo(LOG_ID_SD_037D, "Adp device may be offline, device id(%u).", sdId);
+        DBG_LogInfo(LOG_ID_SD_037D, "[BDM_FW]:Adp device may be offline, device id(%u).", sdId);
         return;
     }
 
@@ -2003,7 +2003,7 @@
     dev = SD_DEVICE_LOOK_UP(sdId);
     if (NULL == dev)
     {
-        DBG_LogError(LOG_ID_SD_037B, "Device may be offline, device id(%u).", sdId);
+        DBG_LogError(LOG_ID_SD_037B, "[BDM_FW]:Device may be offline, device id(%u).", sdId);
         sdPutAdapterDevice(adpDev);
         return;
     }
@@ -2013,7 +2013,7 @@
     if (SCSI_DEVICE_STATE_UPGRADING_STATE != state)
     {
         spin_unlock(&dev->lock);
-        DBG_LogInfo(LOG_ID_SD_037C, "Device state is not upgrading, device id(%u).", sdId);
+        DBG_LogInfo(LOG_ID_SD_037C, "[BDM_FW]:Device state is not upgrading, device id(%u).", sdId);
         SD_PUT_DEVICE(dev);
         sdPutAdapterDevice(adpDev);
         return;
@@ -2039,7 +2039,7 @@
     return;
 }
 /*End Modified by j00279123 DTS2016112205583 2016.12.28*/
-
+uint32_t sdGetDevIdBySn(uint8_t *sn);
 /*Begin Modified by j00279123 DTS2016112205583 2016.12.28*/
 /**************************************************************************
 *     : SDյӲ̹̼ͬϢ
@@ -2051,23 +2051,23 @@
 void sdReceiveDeviceFWUpgradeAction(BDM_DEV_ACTION_S *action)
 {
     SD_DEVICE_ACTION_S *sdAction = (SD_DEVICE_ACTION_S*)action->devPrivate;
-
+    if (INVALID_VALUE32 == action->devId)
+    {
+        action->devId = sdGetDevIdBySn(action->wwn);
+    }
     /**ĿǰֻӲµʧܲŻᴥ*/
     switch (sdAction->recover.state)
     {
         case SD_DEVICE_FW_UPGRADE_STATE_BEGIN:
-            DBG_LogInfo(LOG_ID_SD_037E, "Receive one disk firmware upgrade begin, device id(%u).", 
-                        action->devId);
+            DBG_LogInfo(LOG_ID_SD_037E, "[BDM_FW]:Receive one disk firmware upgrade begin, device id(%u).", action->devId);
             sdRcvDeviceFWUpgradeBegin(action->devId, sdAction);
             break;
         case SD_DEVICE_FW_UPGRADE_STATE_END:
-            DBG_LogInfo(LOG_ID_SD_037F, "Receive one disk firmware upgrade done, device id(%u), result(%u).", 
-                            action->devId, sdAction->recover.result);
+            DBG_LogInfo(LOG_ID_SD_037F, "[BDM_FW]:Receive one disk firmware upgrade done, device id(%u), result(%u).", action->devId, sdAction->recover.result);
             sdRcvDeviceFWUpgradeDone(action->devId, sdAction->recover.result);
             break;
         default:
-            DBG_LogError(LOG_ID_SD_0380, "Unknown action, device id(%u), state(%u).",
-                            action->devId, sdAction->recover.state);
+            DBG_LogError(LOG_ID_SD_0380, "[BDM_FW]:Unknown action, device id(%u), state(%u).", action->devId, sdAction->recover.state);
             break;
     }
 }
@@ -3612,4 +3612,80 @@
 EXPORT_SYMBOL(sdGetDiskDiagState);
 /*Begin Modified by l0245290 SR_0000157392_07 20170711*/
 
+uint32_t sdGetDevIdBySn(uint8_t *sn)
+{
+    uint32_t index = 0;
+    uint32_t sdevId = INVALID_VALUE32;
+ 
+    spin_lock(&g_sdAdapterDeviceLock);
+    for (index = 0; index < SD_MAX_DEVICE_NUM; index++)
+    {
+        if(NULL == g_sdAdapaterDevices[index])
+        {
+            continue;
+        }
+
+        if (0 == memcmp(g_sdAdapaterDevices[index]->deviceId + SD_ADAPTER_DEV_ID_TYPE_LEN, sn, MAX_WWN_LEN))
+        {
+            sdevId = g_sdAdapaterDevices[index]->sdevId;
+            spin_unlock(&g_sdAdapterDeviceLock);
+
+            return sdevId;
+        }
+    }
+    spin_unlock(&g_sdAdapterDeviceLock);
+ 
+    return sdevId;
+}
+EXPORT_SYMBOL(sdGetDevIdBySn);
+
+bool sdDeviceRecoverDevPowerCtrl(uint32_t sdevId, REQ_S* req, uint32_t reqDeadline, uint32_t timeout, SD_DIAG_INFO_S* diag)
+{
+    SD_DEVICE_RECOVER_PARAM_S param;
+    memset(&param, 0, sizeof(SD_DEVICE_RECOVER_PARAM_S));
+
+    DBG_LogInfo(DBG_LOGID_BUTT, 
+        "Try to power reset device, device id(%u), req(%p), deadline(%u), "
+        "timeout(%u), lba(0x%llx), len(%u), err(0x%x), op(0x%x).",
+        sdevId, req, reqDeadline, timeout, diag->errLba, diag->errLen, 
+        diag->errCode, diag->opCode);
+
+    param.recoverMethod = SD_DEVICE_RECOVER_METHOD_POWER_CYCLE;
+    param.pad = 0;
+    param.req = req;
+    param.reqDeadline = reqDeadline;
+    param.reqTimeout = timeout;
+    param.code = DIAG_FLOW_QUICK_POWERCTRL;
+    param.lba = diag->errLba;
+    param.len = diag->errLen;
+    param.errCode = diag->errCode;
+    param.opCode = diag->opCode;
+    param.isDidError = diag->isDidError;
+
+    return sdTryToRecoverDevice(sdevId, &param);
+}
+EXPORT_SYMBOL(sdDeviceRecoverDevPowerCtrl);
+
+bool sdDiskIsDiagnoseState(uint32_t sdId)
+{
+    bool diskisdiagstate = FALSE;
+    SD_ADAPTER_DEVICE *adpDev = NULL;
+
+    adpDev = sdLookUpAdapterDevice(sdId);
+    if (NULL == adpDev)
+    {
+        return FALSE;
+    }
+
+    spin_lock(&adpDev->lock);
+    if (SCSI_DEVICE_STATE_DIAGNOSING_STATE == adpDev->state)
+    {
+        diskisdiagstate = TRUE;
+    }
+    spin_unlock(&adpDev->lock);
+    sdPutAdapterDevice(adpDev);
+
+    return diskisdiagstate;
+}
+EXPORT_SYMBOL(sdDiskIsDiagnoseState);
 
--- ./source/private_module/bdm/sdm/sd/adapter/sd_adapter_event.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/bdm/sdm/sd/adapter/sd_adapter_event.c.hotpatch	2018-08-20 11:34:31.000000000 +0000
@@ -415,7 +415,7 @@
     action.actionType = ACTION_ALL_CTRL;
     action.backendType = SD_BACKEND_SCSI_DEVICE;
     action.needReportFinish = 0;
-    action.devId = adpDev->sdevId;
+    action.devId = INVALID_VALUE32;
     action.done = callBack;
     action.context = context;
 
--- ./source/private_module/bdm/sdm/sd/sd_debug.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/bdm/sdm/sd/sd_debug.c.hotpatch	2018-09-17 02:30:46.000000000 +0000
@@ -823,7 +823,7 @@
     DBG_Print("[BDM SD]Change simu root disk speed state to: %s\n", 
         0 == g_sdDebugSimuSSDSpeed ? "OFF" : "ON");
 }
-
+void sdFWtest(uint32_t id);
 /* ΪsdIoGenӡƵʿ,ô */
 void sdDoDebugTestA(int32_t argc, char *argv[])
 {
@@ -838,7 +838,7 @@
         num = (uint32_t)LVOS_StrToU64(argv[2]);
     }
     DBG_Print("[BDM SD]Call sdIoGen for device %u for %u times.\n", sdevId, num);
-
+    sdFWtest(num);
     memset(&genIo, 0, sizeof(genIo));
     genIo.objectId = sdevId;
     genIo.parent = NULL;
@@ -4922,4 +4922,177 @@
 /* PC-Lint */
 SD_USE_TRACE_POINT
 
+extern int32_t g_sdFWDelayTime;
+extern bool g_sdFWVersionGetError;
+extern bool g_sdSendFWFailed;
+extern bool g_sdSetDiskParamFailed;
+extern bool g_sdUpNodeVerFailed;
+extern bool g_sdSendRequestDevNull;
+extern bool g_sdIONumResponseDevNull;
+extern bool g_sdIONumCheckFailed;
+extern bool g_sdActiveCheckDiskFailed;
+extern bool g_sdUpdateFWConfFailed;
+extern bool g_sdUpgradeParallelFlag;
+extern bool g_sdDownFWFinishDevNull;
+
+
+void sdFWTestOther(uint32_t id)
+{
+    if (112 == id)
+    {
+        g_sdIONumResponseDevNull = TRUE;
+        DBG_Print("Simu disk is not exist when IO Num response, (id:%d)\n", id);
+    }
+    else if (113 == id)
+    {
+        g_sdIONumResponseDevNull = FALSE;
+        DBG_Print("recover disk is not exist when IO Num response, (id:%d)\n", id);
+    }
+    else if (114 == id)
+    {
+        g_sdIONumCheckFailed = TRUE;
+        DBG_Print("Simu check io num is not zero, (id:%d)\n", id);
+    }
+    else if (115 == id)
+    {
+        g_sdIONumCheckFailed = FALSE;
+        DBG_Print("recover check io num is not zero, (id:%d)\n", id);
+    }
+    else if (116 == id)
+    {
+        g_sdActiveCheckDiskFailed = TRUE;
+        DBG_Print("Simu active check disk failed, (id:%d)\n", id);
+    }
+    else if (117 == id)
+    {
+        g_sdActiveCheckDiskFailed = FALSE;
+        DBG_Print("recover active check disk failed, (id:%d)\n", id);
+    }
+    else if (118 == id)
+    {
+        g_sdUpdateFWConfFailed = TRUE;
+        DBG_Print("Simu update FW conf failed, (id:%d)\n", id);
+    }
+    else if (119 == id)
+    {
+        g_sdUpdateFWConfFailed = FALSE;
+        DBG_Print("recover update FW conf failed, (id:%d)\n", id);
+    }
+    else if (120 == id)
+    {
+        g_sdUpgradeParallelFlag = TRUE;
+        DBG_Print("Simu Parallel flag true, (id:%d)\n", id);
+    }
+    else if (121 == id)
+    {
+        g_sdUpgradeParallelFlag = FALSE;
+        DBG_Print("recover Parallel flag false, (id:%d)\n", id);
+    }
+    else if (122 == id)
+    {
+        g_sdDownFWFinishDevNull = TRUE;
+        DBG_Print("Simu Down FW finish get DEV NULL, (id:%d)\n", id);
+    }
+    else if (123 == id)
+    {
+        g_sdDownFWFinishDevNull = FALSE;
+        DBG_Print("recover Down FW finish get DEV NULL, (id:%d)\n", id);
+    }
+    else
+    {
+        //donothing
+    }
+
+    return;
+}
+
+
+void sdFWtest(uint32_t id)
+{
+    DBG_Print("State: delay(%d), getVer(%d), Send(%d), setPar(%d)\n", 
+        g_sdFWDelayTime, g_sdFWVersionGetError, g_sdSendFWFailed, g_sdSetDiskParamFailed);
+
+    DBG_Print("State: upVer(%d), sendDN(%d), numRN(%d), numCF(%d), activeCF(%d)\n", 
+        g_sdUpNodeVerFailed, g_sdSendRequestDevNull, g_sdIONumResponseDevNull, g_sdIONumCheckFailed, g_sdActiveCheckDiskFailed);
+
+    DBG_Print("State: updateConf(%d), ParallelFlag(%d), DownFWFinishDN(%d)\n", 
+        g_sdUpdateFWConfFailed, g_sdUpgradeParallelFlag, g_sdDownFWFinishDevNull);
+
+    /* IOʱʱԳʱʱ */
+    if (100 == id)
+    {
+        g_sdFWDelayTime = 2000;
+        DBG_Print("set inquiry 2000ms delay time, (id:%d)\n", id);
+    }
+    else if (101 == id)
+    {
+        g_sdFWDelayTime = 1000;
+        DBG_Print("set inquiry 1000ms delay time, (id:%d)\n", id);
+    }
+    else if (102 == id)
+    {
+        g_sdFWVersionGetError = TRUE;
+        DBG_Print("Simu get FW version failed, (id:%d)\n", id);
+    }
+    else if (103 == id)
+    {
+        g_sdFWVersionGetError = FALSE;
+        DBG_Print("recover Get FW version state, (id:%d)\n", id);
+    }
+    else if (104 == id)
+    {
+        g_sdSendFWFailed = TRUE;
+        DBG_Print("Simu send FW version failed, (id:%d)\n", id);
+    }
+    else if (105 == id)
+    {
+        g_sdSendFWFailed = FALSE;
+        DBG_Print("recover Send FW version state, (id:%d)\n", id);
+    }
+    else if (106 == id)
+    {
+        g_sdSetDiskParamFailed = TRUE;
+        DBG_Print("Simu set disk param failed, (id:%d)\n", id);
+    }
+    else if (107 == id)
+    {
+        g_sdSetDiskParamFailed = FALSE;
+        DBG_Print("recover set disk param failed, (id:%d)\n", id);
+    }
+    else if (108 == id)
+    {
+        g_sdUpNodeVerFailed = TRUE;
+        DBG_Print("Simu up node version failed, (id:%d)\n", id);
+    }
+    else if (109 == id)
+    {
+        g_sdUpNodeVerFailed = FALSE;
+        DBG_Print("recover up node version failed, (id:%d)\n", id);
+    }
+    else if (110 == id)
+    {
+        g_sdSendRequestDevNull = TRUE;
+        DBG_Print("Simu disk is not exist when send Request, (id:%d)\n", id);
+    }
+    else if (111 == id)
+    {
+        g_sdSendRequestDevNull = FALSE;
+        DBG_Print("recover disk is not exist when send Request, (id:%d)\n", id);
+    }
+    else
+    {
+        sdFWTestOther(id);
+    }
+
+    DBG_LogInfo(LOG_ID_SD_011C, "Simu: delayTime(%d), getVerErr(%d), SendFWFailed(%d), setParFailed(%d).", 
+        g_sdFWDelayTime, g_sdFWVersionGetError, g_sdSendFWFailed, g_sdSetDiskParamFailed);
+
+    DBG_LogInfo(LOG_ID_SD_011D, "Simu: upNodeVerFail(%d), sendDevNull(%d), numResNull(%d), numCheckFail(%d).", 
+        g_sdUpNodeVerFailed, g_sdSendRequestDevNull, g_sdIONumResponseDevNull, g_sdIONumCheckFailed);
+
+    DBG_LogInfo(LOG_ID_SD_011E, "Simu: activeCheckFail(%d), updateConfFail(%d), ParallelFlag(%d), DownFWFinishDN(%d).", 
+        g_sdActiveCheckDiskFailed, g_sdUpdateFWConfFailed, g_sdUpgradeParallelFlag, g_sdDownFWFinishDevNull);
+
+    return;
+}
 
--- ./source/private_module/bdm/sdm/sd/sd_generic.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/bdm/sdm/sd/sd_generic.c.hotpatch	2018-08-20 11:34:31.000000000 +0000
@@ -710,7 +710,7 @@
             || (ATA_16 == scsiOpCode)
             || (MODE_SENSE_10 == scsiOpCode));
 }
-
+bool sdIsCdbValidForNewUpgrading(uint8_t scsiOpCode);
 /**************************************************************************
 *     : firmwareʱSIOֻ·ضCDB
 * : 豸ָdev
@@ -739,13 +739,13 @@
     }
     else
     {
-        if ( sdIsCdbValidForUpgrading(cmnd->cdb[0]) )
+        //if ( sdIsCdbValidForUpgrading(cmnd->cdb[0]) )
+        if ( sdIsCdbValidForNewUpgrading(cmnd->cdb[0]) )
         {
             return RETURN_OK;
         }
     }
-    /* Dorado 5000 modified end */
-    
+    /* Dorado 5000 modified end */   
     req->result = BDM_IO_ERROR;
     sdSetReqInnerError(req, BDM_INNER_ERROR_UPGRADING);
     return req->result;
@@ -762,7 +762,6 @@
 int32_t sdSubmitReqWhenUpgrading(SD_SCSI_DEVICE_S* dev, REQ_S* req)
 {
     int32_t ret = RETURN_OK;
-    
     if ( SD_IO_OPCODE_PC != req->opCode )
     {
         ret = RETURN_ERROR;
@@ -776,7 +775,8 @@
         }
         else
         {
-            ret = sdIsCdbValidForUpgrading(SIO_GET_REQ_CDB_CODE(req)) ? RETURN_OK : RETURN_ERROR;
+            //ret = sdIsCdbValidForUpgrading(SIO_GET_REQ_CDB_CODE(req)) ? RETURN_OK : RETURN_ERROR;
+            ret = sdIsCdbValidForNewUpgrading(SIO_GET_REQ_CDB_CODE(req)) ? RETURN_OK : RETURN_ERROR;
         }
         /* Dorado 5000 modified end */
     }
@@ -1900,3 +1900,25 @@
 /* PC-Lint */
 SD_USE_TRACE_POINT
 
+#define ACTIVE_DISK_FW            0xC1
+/**************************************************************************
+*     : жscsi cmndfirmware״̬Ƿ·
+* : scsiOpCode scsi
+* : 
+*   ֵ: TRUE·,FALSE·
+*     : ֻwrite bufferread buffer·
+**************************************************************************/
+bool sdIsCdbValidForNewUpgrading(uint8_t scsiOpCode)
+{
+    return ((WRITE_BUFFER == scsiOpCode) 
+            || (READ_BUFFER == scsiOpCode) 
+            || (ATA_16 == scsiOpCode)
+            || (MODE_SENSE_10 == scsiOpCode)
+            || (ACTIVE_DISK_FW == scsiOpCode)
+            || (INQUIRY == scsiOpCode)
+            || (MODE_SELECT_10 == scsiOpCode)
+            || (LOG_SENSE == scsiOpCode));
+}
+
+
+
--- ./source/private_module/bdm/sdm/sd/stub_v3/stub_sd_adapter_event.c	2018-04-20 08:27:24.000000000 +0000
+++ ./source/private_module/bdm/sdm/sd/stub_v3/stub_sd_adapter_event.c.hotpatch	2018-08-24 10:59:26.000000000 +0000
@@ -47,8 +47,8 @@
 /* Dorado 5000 modified end */
 
 MODULE_ID(PID_BDM_SD);
-
-
+#define SD_DEV_ACTION_TYPE_UPDATE_DISK_FW (14)
+#define SD_DEV_ACTION_TYPE_UPDATE_FW_CONF (30)
 /*Begin Modified by c00271321 DTS2015123110890 20160203*/
 /**************************************************************************
 *     : ӲǷλ
@@ -106,7 +106,7 @@
     *result = diagResult;
 }
 /*End Modified by c00271321 DTS2016021603015 20160217*/
-
+int32_t sdUpdateDiskFwVersion(BDM_DEV_ACTION_S *action);
 /*Begin Modified by j90006936 SR-0000408900_02 2016.1.24*/
 void stub_sdAdapterNotifyDeviceRecoverState(SD_ADAPTER_DEVICE* adpDev, bool begin, int32_t result, uint32_t mode)
 {
@@ -169,16 +169,16 @@
 
     sdTriggerAction(&action, NULL, NULL);
 }
-/*End Modified by j90006936 SR-0000408900_02 2016.1.24*/
-
+extern int32_t sdUpdateFWConfAndSetFlag(BDM_DEV_ACTION_S *action);
 #define SD_DEV_ACTION_TYPE_EFUSE_OP_FOO   \
-        /*Begin Modified by m00381520 SR-0000416591_03 20170319*/    \
         case SD_DEV_ACTION_TYPE_EFUSE_OP:                             \
             sdSyncEfuseFlagOpDone(action);                                \
             break;                                                      \
-        /*End Modified by m00381520 SR-0000416591_03 20170319*/
+        case SD_DEV_ACTION_TYPE_UPDATE_DISK_FW:                     \
+            return sdUpdateDiskFwVersion(action);                   \
+        case SD_DEV_ACTION_TYPE_UPDATE_FW_CONF:                     \
+            return sdUpdateFWConfAndSetFlag(action);                
 
-/* Dorado 5000 modified begin */
 int32_t stub_sdProcessActionOther(BDM_DEV_ACTION_S *action)
 {
     SD_DEVICE_ACTION_S *sdAction = NULL;
@@ -213,7 +213,7 @@
         sdSyncBomListOpDone(action);                                \
         break;                                                      \
     /*End Modified by m00381520 SR-0000416591_03 20170319*/
-
+int32_t sdRcvDeviceSetUpgradeState(BDM_DEV_ACTION_S *action);
 int32_t stub_sdProcessAction(BDM_DEV_ACTION_S *action)
 {
     SD_DEVICE_ACTION_S *sdAction = NULL;
@@ -234,7 +234,7 @@
             sdReceiveDeviceRecoverAction(action);
             break;
         case SD_DEV_ACTION_TYPE_REQUEST_IONUM:
-            return sdUpgradeFWProcRequest(action->devId);
+            return sdRcvDeviceSetUpgradeState(action);
         case SD_DEV_ACTION_TYPE_DISK_POS_LED_ON:
             /*Begin Modified by y00355707 DTS2017102405113 20171031*/
             BDM_PRINT_LIMIT_PERIOD((30*HZ), 1, DBG_LOG_INFO, LOG_ID_SD_0073,
@@ -627,3 +627,178 @@
 }
 
 
+/* Begin Modified by s00400440 DTS2018062203588 20180615 */
+typedef struct tagSD_ACT_UPDATE_DISK_FW_S
+{
+    char firmware[DISK_FIRMWARE_LEN];   /*FW汾*/
+} SD_ACT_UPDATE_DISK_FW_S;
+
+typedef struct tagSD_DEVICE_NEW_ACTION_S
+{
+    uint32_t module;
+    uint32_t opcode;
+    uint32_t specialband;
+    uint32_t reserved[1];
+    union
+    {
+        SD_ACT_UPDATE_DISK_FW_S updateFw;
+    };
+} SD_DEVICE_NEW_ACTION_S;
+uint32_t sdGetDevIdBySn(uint8_t *sn);
+/**************************************************************************
+   : sdUpdateDiskFwVersion
+     : requestϢ
+ : 
+ : 
+   ֵ:  
+     : 
+**************************************************************************/
+int32_t sdUpdateDiskFwVersion(BDM_DEV_ACTION_S *action)
+{
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    SD_DEVICE_NEW_ACTION_S *sdAction = NULL;
+
+    if (INVALID_VALUE32 == action->devId)
+    {
+        action->devId = sdGetDevIdBySn(action->wwn);
+    }
+
+    dev = SD_DEVICE_LOOK_UP(action->devId);
+    if (NULL == dev)
+    {
+        DBG_LogInfo(LOG_ID_SD_026E, "[BDM_FW]:SD update disk(sdid:%u sn:%s) fw version success, dev is NULL.",
+                     action->devId, action->wwn);
+        /*Begin DTS2018012208184 z00225684 2018.1.24*/
+        return RETURN_OK;
+        /*End DTS2018012208184 z00225684 2018.1.24*/
+    }
+    /*End DTS2018012208184 z00225684 2018.1.24*/
+    
+    disk = SD_GENERIC_TO_DISK(dev);
+
+    sdAction = (SD_DEVICE_NEW_ACTION_S *)action->devPrivate;
+    /*End Modified by y00355707 DTS2017121408756 20171215*/
+    UNREFERENCE_PARAM(sdAction->module);
+    UNREFERENCE_PARAM(sdAction->opcode);
+    UNREFERENCE_PARAM(sdAction->specialband);
+    UNREFERENCE_PARAM(sdAction->reserved);
+    /*̵fw汾*/
+    memcpy(disk->firmware, (void *)sdAction->updateFw.firmware, sizeof(disk->firmware));
+    DBG_LogInfo(LOG_ID_SD_026E, "[BDM_FW]:SD update disk(%u,%u) fw version success, fw(%s).",
+                disk->frameId, disk->slotId, disk->firmware);
+    
+    
+    SD_PUT_DEVICE(dev);
+    return RETURN_OK;
+}
+
+/**************************************************************************
+   : sdRcvDeviceSetUpgradeState
+     : requestϢ
+ : 
+ : 
+   ֵ:  
+     : 
+**************************************************************************/
+int32_t sdRcvDeviceSetUpgradeState(BDM_DEV_ACTION_S *action)
+{
+    SD_ADAPTER_DEVICE *adpDev = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SD_DEVICE_ACTION_S *sdAction = NULL;
+    uint32_t ioNum = 0;
+
+    if (INVALID_VALUE32 == action->devId)
+    {
+        action->devId = sdGetDevIdBySn(action->wwn);
+    }
+    sdAction = (SD_DEVICE_ACTION_S*)action->devPrivate;
+
+    adpDev = sdLookUpAdapterDevice(action->devId);
+    if (NULL == adpDev)
+    {
+        DBG_LogInfo(LOG_ID_SD_037D, "[BDM_FW]:Adp device may be offline, device id(%u).", action->devId);
+        return RETURN_OK;
+    }
+
+    /* adpDev״ִ̬ĿִĿ
+       λ̿Ըݸ״̬ͿIDSD̵״̬ */
+    spin_lock(&adpDev->lock);
+    adpDev->isInUpgradingFwState = 1;
+    adpDev->procUpgradeFwNid = (uint16_t)sdAction->recover.srcNid;
+    spin_unlock(&adpDev->lock);
+    sdPutAdapterDevice(adpDev);
+
+    dev = SD_DEVICE_LOOK_UP(action->devId);
+    if (NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_0062, "[BDM_FW]:dev(%u) is not exist.", action->devId);
+        return RETURN_OK;
+    }
+
+    /*״̬ΪUpgradeState*/
+    spin_lock(&dev->lock);
+    dev->ctrlOps->setState(dev, SCSI_DEVICE_STATE_UPGRADING_STATE);
+    ioNum = (uint32_t)atomic_read(&dev->busy);
+    spin_unlock(&dev->lock);
+    SD_PUT_DEVICE(dev);
+
+    if (0 == ioNum)
+    {
+        return RETURN_OK;
+    }
+    else
+    {
+        return RETURN_ERROR;
+    }
+}
+
+//ñڴ¸λִж,ɸλִж水FW
+bool g_sdUpdateFWConfFailed = FALSE;
+bool g_sdUpgradeParallelFlag = FALSE;
+
+extern int32_t hdmGetFwUpgradeConfig(void);
+/**************************************************************************
+   : sdUpgradeUpdateFWconf
+     : hddfw.confºڰԼòб
+ : void
+ : 
+   ֵ: RETURN_OK:ִгɹRETURN_ERROR:ʧ
+     : 
+**************************************************************************/
+int32_t sdUpdateFWConfAndSetFlag(BDM_DEV_ACTION_S *action)
+{
+    int32_t ret = RETURN_ERROR;
+
+    if (NULL == action)
+    {
+        DBG_LogError(LOG_ID_SD_0276, "[BDM_FW]:action is NULL.");
+        return ret;
+    }
+
+    DBG_LogInfo(LOG_ID_SD_0276, "[BDM_FW]:Update FW conf and Set Parallel flag start.");
+
+    /* ģʧ */
+    if (TRUE == g_sdUpdateFWConfFailed)
+    {
+        g_sdUpgradeParallelFlag = FALSE;
+        DBG_LogInfo(LOG_ID_SD_0276, "[BDM_FW]:Simu Update FW conf and Set Parallel failed.");
+        return RETURN_ERROR;
+    }
+
+    /* ºڰ */
+    ret = hdmGetFwUpgradeConfig();
+    if(RETURN_OK != ret)
+    {
+        g_sdUpgradeParallelFlag = FALSE;
+        DBG_LogError(LOG_ID_SD_0276, "[BDM_FW]:Update FW conf failed, ret(%d).", ret);
+        return ret;
+    }
+
+    /* ñز */
+    g_sdUpgradeParallelFlag = TRUE;
+
+    return ret;
+}
+/* End Modified by s00400440 DTS2018062203588 20180615 */
+
--- ./source/private_module/bdm/sdm/sd/stub_v3/stub_sd_upgrade.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/bdm/sdm/sd/stub_v3/stub_sd_upgrade.c.hotpatch	2018-09-17 07:24:50.000000000 +0000
@@ -1,17 +1,8 @@
-/**************************************************************************
 
-                  Ȩ (C), 2012-2012, Ϊּ(ɶ)޹˾
 
-***************************************************************************
-    : sd_ioctl.c
-    : 
-      : l90005843
-  : 2012520
-  : SD豸upgradeʵ
-      ע: 
-**************************************************************************/
 #include "lvos.h"
 #include "framework/cmm.h"
+
 #include "bdm_inner_intf.h"
 #include "sd_internal.h"
 #include "sd_upgrade.h"
@@ -29,7 +20,7 @@
 #include "../sd_trace_point.h"
 #include "../../../lib/stub_v3/stub_smart_tp.h"
 /*End Modified by y00355707 ϵͳ 20170627*/
-
+#include "sio_scsi.h"
 
 MODULE_ID(PID_BDM_SD);
 
@@ -44,15 +35,24 @@
 /*End Modified by j00285232 CR-01770370 20150408*/
 
 void sdUpgradeFWSendRequest(SD_UPGRADE_FW_PARAM_S *param);
-
-/**************************************************************************
-   : sdUpgradeFWFindParamByDevId
-     : sdidparam
- : sdevId  : sdid
- : 
-   ֵ:  paramָ
-     : 
-**************************************************************************/
+typedef struct tagSD_UPGRADE_FW_NEW_PARAM_S
+{
+    struct list_head head;
+    uint32_t sdId;
+    uint16_t times;
+    CMD_S cmd;
+    char fw[DISK_FIRMWARE_LEN];
+    void *context;
+    SD_UPGRADE_TYPE_E upgradeType;
+    SD_UPGRADE_DONE callBack;
+    uint32_t frameId;
+    uint32_t slotId;
+    uint8_t getFwTimes;
+    uint8_t upgradeMode;
+    uint8_t wwn[MAX_WWN_LEN];
+    DISK_TYPE_E diskType;
+} SD_UPGRADE_FW_NEW_PARAM_S;
+void sdUpgradeNewFWSendRequest(SD_UPGRADE_FW_NEW_PARAM_S *param);
 SD_UPGRADE_FW_PARAM_S* sdUpgradeFWFindParamByDevId(uint32_t sdevId)
 {
     struct list_head *node = NULL;
@@ -660,7 +660,7 @@
     return RETURN_OK;
 }
 
-
+bool g_sdFWVersionGetError = FALSE;
 /*****************************************************************************
     : FW̼֮汾Ƿ
 : disk
@@ -672,20 +672,20 @@
 int32_t sdCheckFwVersion(SCSI_DISK_DEVICE_S *disk)
 {
     uint8_t fwState = DEV_DISKFW_STAT_BUFF;
-    
-    if(NULL == disk)
-    {
+    if(NULL == disk){
         DBG_LogInfo(LOG_ID_SD_026A, "SD check fw version fail, disk is NULL");
         return RETURN_ERROR;
     }
-
-    /* FW汾 */
     HDM_GET_DISK_FW_STATE(disk->model, disk->firmware, &fwState);
+    /*м汾ǷʧTP */
+    if (TRUE == g_sdFWVersionGetError){
+        fwState = DEV_DISKFW_STAT_OTHER;
+        BDM_LOG_INFO_CAN_PRINT(LOG_ID_SD_026A, 60 * HZ, (uint64_t)disk->slotId, "[BDM_FW]:Simu get FW failed, disk(%u-%u).", disk->frameId, disk->slotId);
+    }
     if(DEV_DISKFW_STAT_NORMAL == fwState)
     {
         return RETURN_OK;    
     } 
-    
     return RETURN_ERROR;    
 }
 
@@ -710,7 +710,7 @@
     return;
 }
 
-
+void sdUpgradeFreeNewParam(SD_UPGRADE_FW_NEW_PARAM_S *param);
 /**************************************************************************
    : sdRootDiskFwBackUpd
      : BDMָ״̬ͷԴصģ
@@ -724,7 +724,7 @@
 void sdRootDiskFwBackUpd(uint32_t sdevId ,void *context, int32_t result)
 {
     SD_SYNC_CALL_PARAM_S *backContext = NULL;
-    SD_UPGRADE_FW_PARAM_S *param = context;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
     SD_UPGRADE_DONE callBack = NULL;
 
     backContext = param->context;
@@ -735,7 +735,7 @@
     /*ָ״̬*/
     sdRcvDeviceFWUpgradeDone(sdevId, RETURN_OK);;
     /*ͷԴ*/
-    sdUpgradeFreeParam(param);
+    sdUpgradeFreeNewParam(param);
     callBack(result, (void *)backContext);
 
     return;
@@ -753,20 +753,20 @@
 **************************************************************************/
 void sdGetRootDiskFwBack(int32_t result, void *context)
 {
-    SD_UPGRADE_FW_PARAM_S *param = context;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
     SD_SCSI_DEVICE_S *dev = NULL;
     SCSI_DISK_DEVICE_S *disk = NULL;
 
     if(NULL == param)
     {
-        DBG_LogInfo(LOG_ID_SD_026A, "SD upgrade fw fail, param is NULL");
+        DBG_LogInfo(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw fail, param is NULL");
         return;
     }   
 
     dev = SD_DEVICE_LOOK_UP(param->sdId);
     if(NULL == dev)
     {
-        DBG_LogInfo(LOG_ID_SD_026A, "SD upgrade fw fail, dev is NULL");
+        DBG_LogInfo(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw fail, dev is NULL");
         /*ָ״̬ϱrecover¼صʧ*/
         sdRootDiskFwBackUpd(param->sdId, context, RETURN_ERROR);
         return;
@@ -775,14 +775,14 @@
 
     if((RETURN_OK == result) && (RETURN_OK == sdCheckFwVersion(disk)))
     {
-        DBG_LogInfo(LOG_ID_SD_026A, "SD disk(%u) upgrade fw success!",
+        DBG_LogInfo(LOG_ID_SD_026A, "[BDM_FW]:SD disk(%u) upgrade fw success!",
                     dev->sdevId);
         
         sdRootDiskFwBackUpd(dev->sdevId, context, RETURN_OK);
     }
     else
     {
-        DBG_LogInfo(LOG_ID_SD_026A, "SD disk(%u) upgrade fw fail, fw is old!",
+        DBG_LogInfo(LOG_ID_SD_026A, "[BDM_FW]:SD disk(%u) upgrade fw fail, fw is old!",
                     dev->sdevId);
         
         sdRootDiskFwBackUpd(dev->sdevId, context, RETURN_ERROR);
@@ -843,7 +843,7 @@
 **************************************************************************/
 void sdUpgradeRootDiskResetCallBack(void *context, int32_t result)
 {
-    SD_UPGRADE_FW_PARAM_S *param = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
     SD_SCSI_DEVICE_S *dev = NULL;
     int ret = RETURN_ERROR;
 
@@ -852,7 +852,7 @@
         DBG_LogError(LOG_ID_SD_026A, "SD upgrade fw fail, context is NULL.");
         return;
     }
-    param = (SD_UPGRADE_FW_PARAM_S *)context;
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
 
     SMART_TP_CALL(RESET_ROOT_DISK, &result); 
     /*λϵͳʧ*/
@@ -900,7 +900,7 @@
 **************************************************************************/
 void sdUpgradeRootDiskFWCallback(void *context, bool state)
 {
-    SD_UPGRADE_FW_PARAM_S *param = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
     SD_SCSI_DEVICE_S *dev = NULL;
     SCSI_DISK_DEVICE_S *disk = NULL;
     int ret = RETURN_ERROR;
@@ -909,15 +909,15 @@
 
     if(NULL == context)
     {
-        DBG_LogError(LOG_ID_SD_026A, "SD RootDisk upgrade fw fail, context is NULL.");
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD RootDisk upgrade fw fail, context is NULL.");
         return;
     }
-    param = (SD_UPGRADE_FW_PARAM_S *)context;
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
 
     dev = SD_DEVICE_LOOK_UP(param->sdId);
     if(NULL == dev)
     {
-        DBG_LogError(LOG_ID_SD_026A, "SD RootDisk upgrade fw fail, device(id %u) does not exist.", param->sdId);
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD RootDisk upgrade fw fail, device(%u) does not exist.", param->sdId);
         
         /*ָ״̬ϱrecover¼, ͷԴص*/
         sdRootDiskFwBackUpd(param->sdId, context, RETURN_ERROR);
@@ -935,8 +935,8 @@
         if(INVALID_VALUE32 == phySlotId || INVALID_VALUE64 == wwn)
         {
             ret = RETURN_ERROR;
-            DBG_LogError(LOG_ID_SD_026A, "SD RootDisk upgrade fw fail, phySlotId(%u).",
-                         phySlotId);
+            DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD RootDisk upgrade fw fail, device(%u), phySlotId(%u).",
+                         param->sdId, phySlotId);
         }
         else
         {
@@ -946,7 +946,7 @@
         
         if(RETURN_OK != ret)
         {
-            DBG_LogError(LOG_ID_SD_026C, "Root disk upgrade fw power reset failed(ret %d).", ret);
+            DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:Root disk upgrade fw power reset failed(ret %d).", ret);
             
             sdRootDiskFwBackUpd(dev->sdevId, context, RETURN_ERROR);
         }
@@ -954,7 +954,7 @@
     else
     {
         /*ӲȷдFWʧ֮󣬲Ҫ·µ!*/
-        DBG_LogError(LOG_ID_SD_026C, "Root disk(%u) upgrade write fw fail.", dev->sdevId);
+        DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:Root disk(%u) upgrade write fw fail.", dev->sdevId);
         sdRootDiskFwBackUpd(dev->sdevId, context, RETURN_ERROR);
     }
     
@@ -1043,7 +1043,7 @@
     return;
 }
 /*End Modified by j00285232 CR-01770370 20150408*/
-
+void sdUpgradeNewFWRootDiskRequest(SD_UPGRADE_FW_NEW_PARAM_S *param);
 /*Begin Modified by y00355707 ϵͳ 20170627*/
 /**************************************************************************
    : sdUpgradeFWDelaySendRequest
@@ -1055,11 +1055,11 @@
 **************************************************************************/
 void sdUpgradeFWDelaySendRequest(CMD_S *cmd)
 {
-    SD_UPGRADE_FW_PARAM_S *param = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
     SD_SCSI_DEVICE_S *dev = NULL;
     SCSI_DISK_DEVICE_S *disk = NULL;
 
-    param = *(SD_UPGRADE_FW_PARAM_S**)(cmd->privateData);
+    param = *(SD_UPGRADE_FW_NEW_PARAM_S**)(cmd->privateData);
     dev = SD_DEVICE_LOOK_UP(param->sdId);
     if(NULL == dev)
     {
@@ -1070,12 +1070,12 @@
 
     if(disk->isRootDisk)
     {
-        sdUpgradeFWRootDiskRequest(param);
+        sdUpgradeNewFWRootDiskRequest(param);
         SD_PUT_DEVICE(dev);
         return;  
     }
     
-    sdUpgradeFWSendRequest(param);
+    sdUpgradeNewFWSendRequest(param);
     SD_PUT_DEVICE(dev);
     return;
 }
@@ -1258,7 +1258,7 @@
     return;
 }
 /*End Modified by y00355707 ϵͳ 20170627*/
-
+extern bool g_sdUpgradeParallelFlag;
 /**************************************************************************
    : sdUpgradeFWProcRequest
      : requestϢ
@@ -1282,7 +1282,7 @@
     /*ѱó״̬*/
     spin_lock(&dev->lock);
     /*Begin Modified by j00279123 DTS2016112205583 2016.12.28*/
-    // UPGRADING״̬sdReceiveDeviceFWUpgradeActionУڴ
+    dev->ctrlOps->setState(dev, SCSI_DEVICE_STATE_UPGRADING_STATE);
     /*End Modified by j00279123 DTS2016112205583 2016.12.28*/
     ioNum = (uint32_t)atomic_read(&dev->busy);
     spin_unlock(&dev->lock);
@@ -1297,7 +1297,7 @@
         return RETURN_ERROR;
     }
 }
-
+extern bool hdmFwConfListNULL(void);
 /*Begin Modified by j00285232 CR-01770370 20150408*/
 int32_t sdCheckDiskFwCanBeUpgraded(uint32_t sdId)
 {
@@ -1309,29 +1309,29 @@
     dev = SD_DEVICE_LOOK_UP(sdId);
     if (NULL == dev)
     {
-        DBG_LogError(LOG_ID_SD_026F, "SD upgrade fw failed: device(id %u) does not exist.", sdId);
+        DBG_LogError(LOG_ID_SD_026F, "[BDM_FW]:SD upgrade fw failed: device(id %u) does not exist.", sdId);
         return UPGRADE_DISK_NOT_EXIST;
     }
 
     /*豸Ƿ*/
     if (SCSI_DEVICE_TYPE_DISK != dev->type)
     {
-        DBG_LogError(LOG_ID_SD_0270, "SD upgrade fw failed: device(id %u) is not disk.", sdId);
+        DBG_LogError(LOG_ID_SD_0270, "[BDM_FW]:SD upgrade fw failed: device(id %u) is not disk.", sdId);
         SD_PUT_DEVICE(dev);
         return UPGRADE_DISK_NOT_EXIST;
     }
     if (SCSI_DEVICE_STATE_RUNNING != dev->state)
     {
-        DBG_LogError(LOG_ID_SD_0271, "SD upgrade fw failed: device(id %u) state is not running.", sdId);
+        DBG_LogError(LOG_ID_SD_0271, "[BDM_FW]:SD upgrade fw failed: device(id %u) state is not running.", sdId);
         SD_PUT_DEVICE(dev);
         return UPGRADE_DISK_STATE_IS_ABNOMAL;
     }
     disk = SD_GENERIC_TO_DISK(dev);
 
     /*ױ*/
-    if (RETURN_OK != HDM_DISK_FW_UPGRAGE_CONF())
+    if ((TRUE == hdmFwConfListNULL()) || (FALSE == g_sdUpgradeParallelFlag))
     {
-        DBG_LogError(LOG_ID_SD_0273, "SD upgrade fw failed: update fw conf failed.");
+        DBG_LogError(LOG_ID_SD_0273, "[BDM_FW]:SD upgrade fw failed: device(id %u) update fw conf failed, flag(%d).", sdId, g_sdUpgradeParallelFlag);
         SD_PUT_DEVICE(dev);
         return UPGRADE_UPDATE_FW_FILE_FAILED;
     }
@@ -1339,25 +1339,25 @@
     HDM_GET_DISK_FW_STATE(disk->model, disk->firmware, &fwState);
     if (DEV_DISKFW_STAT_NORMAL == fwState)
     {
-        DBG_LogError(LOG_ID_SD_0274, "SD upgrade fw failed: fw(%s) is normal.", disk->firmware);
+        DBG_LogError(LOG_ID_SD_0274, "[BDM_FW]:SD upgrade fw failed: fw(%s) is normal.", disk->firmware);
         SD_PUT_DEVICE(dev);
         return UPGRADE_DISK_FW_NONEED_UPGRADE;
     }
 
-    spin_lock(&g_sdUpgradeFwListLock);
-    if (NULL != sdUpgradeFWFindParamByDevId(sdId))
-    {
-        DBG_LogError(LOG_ID_SD_0276, "SD upgrade fw failed: device(id %u) is already upgrading.", sdId);
-        spin_unlock(&g_sdUpgradeFwListLock);
-        SD_PUT_DEVICE(dev);
-        return UPGRADE_DISK_FW_RESU_UPGRADE;
-    }
-    spin_unlock(&g_sdUpgradeFwListLock);
+    //spin_lock(&g_sdUpgradeFwListLock);
+    //if (NULL != sdUpgradeFWFindParamByDevId(sdId))
+    //{
+    //    DBG_LogError(LOG_ID_SD_0276, "[BDM_FW]:SD upgrade fw failed: device(id %u) is already upgrading.", sdId);
+    //    spin_unlock(&g_sdUpgradeFwListLock);
+    //    SD_PUT_DEVICE(dev);
+    //    return UPGRADE_DISK_FW_RESU_UPGRADE;
+    //}
+    //spin_unlock(&g_sdUpgradeFwListLock);
 
     SD_PUT_DEVICE(dev);
     return UPGRADE_DISK_FW_RESU_BUTT;
 }
-
+SD_UPGRADE_FW_NEW_PARAM_S *sdUpgradeFWFindNewParamByDevId(uint32_t sdevId);
 int32_t sdCheckDiskConverterFwCanBeUpgraded(uint32_t sdId)
 {
     SD_SCSI_DEVICE_S *dev = NULL;
@@ -1413,7 +1413,7 @@
 
     /*ӲfirmwareӲתӿfirmwareΪ⶯һ¼*/
     spin_lock(&g_sdUpgradeFwListLock);
-    if (NULL != sdUpgradeFWFindParamByDevId(sdId))
+    if (NULL != sdUpgradeFWFindNewParamByDevId(sdId))
     {
         DBG_LogError(LOG_ID_SD_0358, "SD upgrade disk converter fw failed: device(id %u) is already upgrading.", sdId);
         spin_unlock(&g_sdUpgradeFwListLock);
@@ -1516,11 +1516,10 @@
     return;
 }
 /*End Modified by y00355707 DTS2017071202361 20170810*/
-
+int32_t sdUpgradeFWparamInit(uint32_t sdId, void * context, int32_t type, void(* callBack)(int32_t result, void * context), void * * param);
 int32_t sdUpgradeFWAsync(uint32_t sdId, void *context, int32_t type,void (*callBack)(int32_t result, void *context))
 {
-    SD_UPGRADE_FW_PARAM_S *param = NULL;
-    SD_SCSI_DEVICE_S *dev = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *newParam = NULL;
     int32_t failResult = 0;
     int32_t buttResult = 0;
     int ret = RETURN_ERROR;
@@ -1554,39 +1553,40 @@
         return failResult;
     }
 
-    ALLOCATE_STRUCTURE(MY_PID, g_sdUpgradeFwPoolId, (void**)&param);
-    if (NULL == param)
+    ret = sdUpgradeFWparamInit(sdId, context, type, callBack, (void**)&newParam);
+    if (UPGRADE_DISK_FW_RESU_BUTT != ret)
     {
-        DBG_LogError(LOG_ID_SD_0275, "SD upgrade fw failed: alloc structure failed.");
-        return failResult;
+        DBG_LogError(LOG_ID_SD_0359, "[BDM_FW]:Init param failed, ret(%d), param(%p).", ret, newParam);
+        return ret;
     }
-    memset(param, 0, sizeof(SD_UPGRADE_FW_PARAM_S));
-    param->sdId = sdId;
-    param->context = context;
-    param->callBack = callBack;
-    param->upgradeType = (SD_UPGRADE_TYPE_E)type;
-    spin_lock(&g_sdUpgradeFwListLock);
-    list_add_tail(&param->head, &g_sdUpgradeFwList);
-    spin_unlock(&g_sdUpgradeFwListLock);
 
-    dev = SD_DEVICE_LOOK_UP(sdId);
-    if (NULL == dev)
+    DBG_LogInfo(LOG_ID_SD_0362, "[BDM_FW]:Start to send FW request, sdid(%u), mode(%d), type(%d)", sdId, newParam->upgradeMode, newParam->upgradeType);
+    
+    if(TRUE == sdDiskIsRootDisk(sdId))
     {
-        DBG_LogError(LOG_ID_SD_026F, "SD upgrade fw failed: device(id %u) does not exist,type(%u).", sdId, type);
-        spin_lock(&g_sdUpgradeFwListLock);
-        list_del(&param->head);
-        FREE_STRUCTURE(param, g_sdUpgradeFwPoolId);
-        spin_unlock(&g_sdUpgradeFwListLock);
-        return failResult;
+        sdUpgradeNewFWRootDiskRequest(newParam);
+    }
+    else
+    {
+        /*״̬*///һactionϲ
+        //sdUpgradeAdapterNotifyDiskFWStateByWwn(newParam, TRUE, RETURN_OK, NULL, NULL);
+        /*òѯԶ*/
+        sdUpgradeNewFWSendRequest(newParam);
     }
+    
+
     /*Begin Modified by y00355707 DTS2017071202361 20170810*/
     /*Begin Modified by j00279123 DTS2016112205583 2016.12.28*/
-    sdAdapterNotifyDiskFWUpgradeState(dev->sdevId, TRUE, RETURN_OK, (void *)param,
-                                      sdNotifyDiskFWUpgradeStateDone);
+    //sdAdapterNotifyDiskFWUpgradeState(dev->sdevId, TRUE, RETURN_OK, (void *)param,
+    //                                  sdNotifyDiskFWUpgradeStateDone);
     /*End Modified by j00279123 DTS2016112205583 2016.12.28*/
     /*End Modified by y00355707 DTS2017071202361 20170810*/
+
+
+
+
+
     
-    SD_PUT_DEVICE(dev);
     return buttResult;
 }
 /*End Modified by j00285232 CR-01770370 20150408*/
@@ -1813,3 +1813,2127 @@
     spin_lock_destroy(&g_sdUpgradeFwListLock);
 }
 
+/* Begin Modified by s00400440 DTS2018062203588 20180615 */
+#define SD_DEV_ACTION_TYPE_UPDATE_DISK_FW (14)
+#define SD_DEV_ACTION_TYPE_UPDATE_FW_CONF (30)
+
+
+#define UP_FW_DELAY_GET_DISK_FW_VERSION (5000)
+#define UP_FW_VERSION_CHECK_INTERVAL (1000)
+#define UP_ACTIVE_FW_VERSION_CHECK_CYCLES   (175)
+#define UP_AFTER_CHECK_CYCLES_TIMES   (60)  /* δϵ汾δ仯 */
+#define UP_POWER_ON_OFF_INTERVAL_TIME   (30) /* ʱ䵥λs */
+
+
+uint32_t g_sdFWDelayTime = 1000;
+bool g_sdSendFWFailed = FALSE;
+
+typedef struct tagSD_QUERY_PARAM_S
+{
+    uint32_t sdId;
+    uint32_t retryTimes;
+    void *context;
+    SD_UPGRADE_DONE callBack;
+    uint64_t startJiffies;       /*յREQʼjiffies*/
+    int64_t  timeout;            /*ѯIOʱʱ*/
+} SD_QUERY_PARAM_S;
+
+typedef struct tagSD_ACT_UPDATE_DISK_FW_S
+{
+    char firmware[DISK_FIRMWARE_LEN];   /*FW汾*/
+} SD_ACT_UPDATE_DISK_FW_S;
+
+typedef struct tagSD_DEVICE_NEW_ACTION_S
+{
+    uint32_t module;
+    uint32_t opcode;
+    uint32_t specialband;
+    uint32_t reserved[1];
+    union
+    {
+        SD_ACT_UPDATE_DISK_FW_S updateFw;
+    };
+} SD_DEVICE_NEW_ACTION_S;
+
+typedef enum tagHDM_VENDOR_E
+{
+    HDM_VENDOR_HITACHI = 0,
+    HDM_VENDOR_SEAGATE,
+    HDM_VENDOR_WD,
+    HDM_VENDOR_HUASY,
+    HDM_VENDOR_DELL,
+    HDM_VENDOR_STEC,
+    HDM_VENDOR_ATA,
+/* Dorado 5000 modified begin */
+    HDM_VENDOR_INTEL,
+/* Dorado 5000 modified end */
+    HDM_VENDOR_BUTT
+} HDM_VENDOR_E;
+
+
+/**************************************************************************
+   : sdUpgradeFreeParam
+     : HSSDӲ֮ͷԴ
+ : param: ͷŵĽṹָ
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdUpgradeFreeNewParam(SD_UPGRADE_FW_NEW_PARAM_S *param)
+{
+    if (NULL != param)
+    {
+        /*ȫֶȡ²ͷ*/
+        spin_lock(&g_sdUpgradeFwListLock);
+        list_del(&param->head);
+        FREE_PUB_STRUCTURE(param);
+        param = NULL;
+        spin_unlock(&g_sdUpgradeFwListLock);
+    }
+
+    return;
+}
+EXPORT_SYMBOL(sdUpgradeFreeNewParam);
+
+/*****************************************************************************
+    : ״ָ̬Ӳ״̬Ϊ״̬
+: sdId  ҪõӲ
+: 
+  ֵ: 
+    : 
+*****************************************************************************/
+void sdUpgradeRecoverState(uint32_t sdId)
+{
+    SCSI_DEVICE_STATE_E state = SCSI_DEVICE_STATE_BUTT;
+    SD_SCSI_DEVICE_S *dev = NULL;
+
+    dev = SD_DEVICE_LOOK_UP(sdId);
+    if (NULL == dev)
+    {
+        return;
+    }
+    
+    spin_lock(&dev->lock);
+    state = dev->ctrlOps->getState(dev);
+    if (SCSI_DEVICE_STATE_UPGRADING_STATE == state)
+    {
+        dev->ctrlOps->setState(dev, SCSI_DEVICE_STATE_RUNNING);  
+    }          
+    spin_unlock(&dev->lock);
+    
+    SD_PUT_DEVICE(dev);
+}
+
+void sdDiskUpgradeFreeNewRes(SD_SCSI_DEVICE_S *dev, SD_UPGRADE_FW_NEW_PARAM_S *param)
+{
+    SCSI_DEVICE_STATE_E state = SCSI_DEVICE_STATE_BUTT;
+    
+    if (NULL != param)
+    {
+        /*ȫֶȡ²ͷ*/
+        spin_lock(&g_sdUpgradeFwListLock);
+        list_del(&param->head);
+        FREE_PUB_STRUCTURE(param);
+        param = NULL;
+        spin_unlock(&g_sdUpgradeFwListLock);
+    }
+
+    if (NULL != dev)
+    {
+        spin_lock(&dev->lock);
+        state = dev->ctrlOps->getState(dev);
+        if (SCSI_DEVICE_STATE_UPGRADING_STATE != state)
+        {
+            spin_unlock(&dev->lock);
+            DBG_LogInfo(LOG_ID_SD_0065, "[BDM_FW]:Device state is not upgrading, dev(%u), state(%d).", dev->sdevId, state);
+            return;
+        }
+        
+        dev->ctrlOps->setState(dev, SCSI_DEVICE_STATE_RUNNING);
+        spin_unlock(&dev->lock);
+    }
+
+    return;
+}
+EXPORT_SYMBOL(sdDiskUpgradeFreeNewRes);
+
+/**************************************************************************
+   : sdHandleNotifyDiskUpgradeStateOver
+     : sd֪ͨϵͳ״̬ɺ
+ : context:
+                         result:
+ : 
+   ֵ:  
+     : 
+**************************************************************************/
+void sdHandleNotifyDiskUpgradeStateOver(int32_t result, void *context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_UPGRADE_DONE callBack = NULL;
+    SD_SYNC_CALL_PARAM_S *backContext = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+    callBack = param->callBack;
+    backContext = param->context;
+   
+    dev = SD_DEVICE_LOOK_UP(param->sdId);        
+    if (NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw failed: device(id %u) does not exist.",
+                     param->sdId);
+        sdUpgradeFreeNewParam(param);
+        callBack(UPGRADE_DISK_FW_RESU_FAIL, (void *)backContext);
+        return;
+    }
+    
+    DBG_LogInfo(LOG_ID_SD_026B,
+            "[BDM_FW]:Start report disk firmware upgrade result, sdId(%u), result(%d).", 
+            dev->sdevId, result);
+    
+    sdDiskUpgradeFreeNewRes(dev, param);
+
+    callBack(UPGRADE_DISK_FW_RESU_FAIL, (void *)backContext);
+
+    SD_PUT_DEVICE(dev);
+}
+
+
+/* Begin Modified by s00400440 DTS2018070908746 20180615 */
+/**************************************************************************
+   : sdHandleOutDiskOver
+     : sdȡdevΪɺ
+ : context:
+                         result:
+ : 
+   ֵ:  
+     : 
+**************************************************************************/
+void sdHandleOutDiskOver(int32_t result, void *context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_UPGRADE_DONE callBack = NULL;
+    SD_SYNC_CALL_PARAM_S *backContext = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+    callBack = param->callBack;
+    backContext = param->context;
+   
+    dev = SD_DEVICE_LOOK_UP(param->sdId);        
+    if (NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw failed: device(id %u) does not exist.",
+                     param->sdId);
+        if (0 == param->upgradeMode)
+        {
+            callBack(UPGRADE_DISK_FW_RESU_FAIL, (void *)backContext);
+        }
+        sdUpgradeFreeNewParam(param);
+        return;
+    }
+    
+    DBG_LogInfo(LOG_ID_SD_026B,
+            "[BDM_FW]:handle disk out result, sdId(%u), result(%d).", 
+            dev->sdevId, result);
+    
+    if (0 == param->upgradeMode)
+    {
+        callBack(UPGRADE_DISK_FW_RESU_FAIL, (void *)backContext);
+    }
+
+    sdDiskUpgradeFreeNewRes(dev, param);
+    
+    SD_PUT_DEVICE(dev);
+}
+/* End Modified by s00400440 DTS2018070908746 20180615 */
+
+/**************************************************************************
+*     : SDģ̼µdoneӿ
+* : context:
+*           state:RETURN_OKʾɹRETURN_ERRORʾʧ
+* : 
+*   ֵ: 
+*     : 
+**************************************************************************/
+void sdUpgradeFWResetNewCallback(void *context, int32_t state)
+{
+    
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
+    SD_UPGRADE_DONE callBack = NULL;
+    SD_SYNC_CALL_PARAM_S *backContext = NULL;
+    
+    BDM_ADJUSTABLE_LOG(LOG_ID_SD_0269, "[BDM_FW]:SD upgrade fw power reset result %d.", state);
+
+    if (NULL == param)
+    {
+        DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:context is NULL.");
+        return;
+    }
+
+    /**ֵת*/
+    state = (RETURN_OK == state) ? UPGRADE_DISK_FW_RESU_SUCCESS : UPGRADE_DISK_FW_RESU_FAIL;
+    
+    callBack = param->callBack;
+    backContext = param->context;
+
+    if (UPGRADE_DISK_FW_RESU_SUCCESS != state)
+    {
+        sdAdapterNotifyDiskFWUpgradeState(param->sdId, FALSE, RETURN_OK, NULL, NULL);
+    }
+    
+    /*ϵص*/
+    /*ȫֶȡ²ͷ*/
+    if (0 == param->upgradeMode)
+    {
+        callBack(state, (void *)backContext);
+    }
+    
+    sdUpgradeFreeNewParam(param);
+    
+    return;   
+}
+EXPORT_SYMBOL(sdUpgradeFWResetNewCallback);
+
+/**************************************************************************
+*     : SDģ̼µdoneӿ
+* : context:
+*           state:RETURN_OKʾɹRETURN_ERRORʾʧ
+* : 
+*   ֵ: 
+*     : 
+**************************************************************************/
+void sdUpgradeFWDownFailedCallback(void *context, int32_t state)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
+    SD_UPGRADE_DONE callBack = NULL;
+    SD_SYNC_CALL_PARAM_S *backContext = NULL;
+
+    if (NULL == param)
+    {
+        DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:context is NULL.");
+        return;
+    }
+    
+    DBG_LogInfo(LOG_ID_SD_026C, "[BDM_FW]:disk(%u) down failed, result[%d].", param->sdId, state);
+
+    callBack = param->callBack;
+    backContext = param->context;
+
+    if (RETURN_OK != state)
+    {
+        sdAdapterNotifyDiskFWUpgradeState(param->sdId, FALSE, RETURN_OK, NULL, NULL);
+    }
+    sdUpgradeFreeNewParam(param);
+    callBack(UPGRADE_DISK_FW_RESU_FAIL, (void *)backContext);
+    
+    return;   
+}
+
+/**************************************************************************
+*     : SDģµ̼ͬ¼Ľӿ
+* : sdId:sd豸id
+*           begin:ʾʼ
+*           result:RETURN_OKʾɹRETURN_ERRORʾʧ
+* : 
+*   ֵ: 
+*     : 
+**************************************************************************/
+void sdUpgradeAdapterNotifyDiskFWStateByWwn(SD_UPGRADE_FW_NEW_PARAM_S *param, bool begin, int32_t result,
+                                                     void *context, void(*callBack)(int32_t ret, void* context))
+{
+    BDM_DEV_ACTION_S action;
+    SD_DEVICE_ACTION_S *sdAction = NULL;
+
+    if (NULL == param)
+    {
+        DBG_LogError(LOG_ID_SD_0275, "[BDM_FW]:SD upgrade fw failed: alloc structure failed.");
+        return;
+    }
+    
+    DBG_LogInfo(LOG_ID_SD_0269,
+                "[BDM_FW]:Start report disk firmware upgrade result, sdId(%u), begin(%s), result(%d).", 
+                param->sdId, begin ? "TRUE" : "FALSE", result);
+
+    memset(&action, 0, sizeof(BDM_DEV_ACTION_S));
+    memcpy(action.wwn, param->wwn, MAX_WWN_LEN);
+    action.actionId = 0;
+    action.actionType = ACTION_ALL_CTRL;
+    action.backendType = SD_BACKEND_SCSI_DEVICE;
+    action.needReportFinish = 0;
+    action.devId = INVALID_VALUE32;
+    action.done = callBack;
+    action.context = context;
+
+    sdAction = (SD_DEVICE_ACTION_S*)action.devPrivate;
+    sdAction->module = MY_PID;
+    sdAction->opcode = SD_DEV_ACTION_TYPE_DISK_FW_UPGRADE;
+    sdAction->recover.state =  begin ? SD_DEVICE_FW_UPGRADE_STATE_BEGIN: SD_DEVICE_FW_UPGRADE_STATE_END;
+    sdAction->recover.result = (uint32_t)result;
+    sdAction->recover.mode = 0;
+    sdAction->recover.srcNid = GET_LOCAL_NID();
+
+    sdTriggerAction(&action, context, callBack);
+    return;
+}
+
+void sdUpgradeNewConverterFWCallback(void *context, bool state)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SD_UPGRADE_DONE callBack = NULL;
+    void *backContext = NULL;
+    int32_t result = 0;
+    
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+    callBack = param->callBack;
+    backContext = param->context;
+    result = (TRUE == state ? UPGRADE_DISK_CONVERTER_FW_SUCCESS : UPGRADE_DISK_CONVERTER_FW_FAIL);
+
+    dev = SD_DEVICE_LOOK_UP(param->sdId);
+    if (NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "SD upgrade fw failed: device(id %u) does not exist.", param->sdId);
+        spin_lock(&g_sdUpgradeFwListLock);
+        list_del(&param->head);
+        FREE_STRUCTURE(param, g_sdUpgradeFwPoolId);
+        param = NULL;
+        spin_unlock(&g_sdUpgradeFwListLock);
+        callBack(UPGRADE_DISK_CONVERTER_FW_FAIL, backContext);
+        return;
+    }
+    
+    sdDiskUpgradeFreeNewRes(dev, param);
+    /*Ӳ̲µ磬öԶӲ״̬*/
+    sdAdapterSyncDeviceState(dev->sdevId, SCSI_DEVICE_STATE_RUNNING);
+    callBack(result, backContext);
+    SD_PUT_DEVICE(dev);
+
+    return;
+}
+void sdDiskUpgrade(SD_SCSI_DEVICE_S *dev, void *context);
+bool g_sdDownFWFinishDevNull = FALSE;
+void sdUpgradeFwActivateSuccess(void *context);
+void sdUpgradeNewDiskFWCallback(void *context, bool state)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    int32_t ret = RETURN_ERROR;
+
+    if (NULL == context)
+    {
+        SYS_BUG(SYS_BUG_NORM, MODULE_FUNC_HANG, "[BDM_FW]:The context is NULL.");
+        return;
+    }
+
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+
+    dev = SD_DEVICE_LOOK_UP(param->sdId);
+    //FW·ɺDEVȡΪ
+    if (TRUE == g_sdDownFWFinishDevNull)
+    {
+        DBG_LogInfo(LOG_ID_SD_0358, "Simu dev is NULL, sdid(%u).", param->sdId);
+        if (NULL != dev)
+        {
+            SD_PUT_DEVICE(dev);
+        }
+
+        dev = NULL;
+    }
+    
+    if (NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:device(id %u) does not exist.", param->sdId);
+    }    
+
+    //FW·ʧܳ
+    if (TRUE == g_sdSendFWFailed)
+    {
+        state = FALSE;
+    }
+
+    /*Begin Modified by s00400440 DTS2018071501041 20180715*/
+    /* SATAһƬabortϱOUT,ʧ,ʵɹ */
+    if ((NULL == dev)
+         && (TRUE == state)
+         && ((DISK_TYPE_SATA == param->diskType) || (DISK_TYPE_SATA_SED == param->diskType)))
+    {           
+        /* SATA輤,ɹ̴ */
+        sdUpgradeFwActivateSuccess(context);
+        return;
+    }
+    /*End Modified by s00400440 DTS2018071501041 20180715*/
+    
+    if ((NULL != dev) && (TRUE == state))
+    {           
+        /*HDMɹ*/
+        sdDiskUpgrade(dev, context);
+    }
+    else
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:device(%u) send FW file failed.", param->sdId);
+
+        ret = HDM_DISK_POWER_ONOFF(param->frameId, param->slotId, 30, TRUE, context, sdUpgradeFWDownFailedCallback);
+        if (RETURN_OK != ret)
+        {
+            DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:Disk[%u-%u] offline upgrade fw power off failed(ret %d).", 
+                    param->frameId, param->slotId, ret);        
+            sdUpgradeFWDownFailedCallback(context, RETURN_ERROR);
+        }
+    }
+    
+    SD_PUT_DEVICE(dev);
+    return;
+}
+
+
+/**************************************************************************
+   : sdUpgradeNewFWCallback
+     : HDM
+ : context:
+                        state:
+ : 
+   ֵ:  
+     : 
+**************************************************************************/
+void sdUpgradeNewFWCallback(void *context, bool state)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    
+    /*Begin Modified by l00245290 DTS2015031103947 20150312*/
+    //DBG_ASSERT(NULL != context);
+    if (NULL == context)
+    {
+        SYS_BUG(SYS_BUG_NORM, MODULE_FUNC_HANG, " The context is NULL.");
+        return;
+    }
+    /*End Modified by l00245290 DTS2015031103947 20150312*/
+    
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;    
+    BDM_ADJUSTABLE_LOG(LOG_ID_SD_026B, "[BDM_FW]:SD upgrade fw result: device(%u), type(%d), ret(%d).", 
+        param->sdId, param->upgradeType, state);   
+
+    /*Begin Modified by y00355707 ϵͳ 20170627*/
+    SMART_TP_CALL(DISK_WRITE_FW, &state);
+
+    if(sdDiskIsRootDisk(param->sdId))
+    {
+        /*ϵͳ̵µ*/
+        sdUpgradeRootDiskFWCallback(context, state);
+        return;
+    }
+    /*End Modified by y00355707 ϵͳ 20170627*/
+
+    if(SD_UPGRADE_DISK_FW == param->upgradeType)
+    {
+        sdUpgradeNewDiskFWCallback(context, state);
+    }
+    else
+    {
+        sdUpgradeNewConverterFWCallback(context, state);
+    }
+    
+    return;
+}
+
+bool g_sdIONumResponseDevNull = FALSE;
+bool g_sdIONumCheckFailed = FALSE;
+/**************************************************************************
+   : sdPrepareUpgradeFWRecvResponse
+     : ӦϢ
+ : action  : յaction
+ : 
+   ֵ:  
+     : 
+**************************************************************************/
+void sdUpgradeNewFWProcResponse(int32_t result, void *context)
+{
+    int32_t ret = RETURN_ERROR;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    CMD_S *cmd = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_FW_UPGRADE upgradeHandle = NULL;
+
+    /*Begin Modified by l00245290 DTS2015062304179 20150624*/
+    if (NULL == context)
+    {
+        SYS_BUG(SYS_BUG_NORM, MODULE_FUNC_HANG, " The context is NULL.");
+        return;
+    }
+    /*End Modified by l00245290 DTS2015062304179 20150624*/
+    param = (SD_UPGRADE_FW_NEW_PARAM_S*)context;
+    /*Begin Modified by j00285232 CR-01770370 20150408*/
+    if(SD_UPGRADE_DISK_FW == param->upgradeType)
+    {
+        upgradeHandle = HDM_FW_UPDATE;
+    }
+    else
+    {
+        upgradeHandle = HDM_DISK_CONVERTOR_FW_UPGRADE;
+    }
+    /*End Modified by j00285232 CR-01770370 20150408*/
+
+    dev = SD_DEVICE_LOOK_UP(param->sdId);
+    if (TRUE == g_sdIONumResponseDevNull)
+    {
+        DBG_LogInfo(LOG_ID_SD_0358, "Simu dev is NULL, sdid(%u).", param->sdId);
+        if (NULL != dev)
+        {
+            SD_PUT_DEVICE(dev);
+        }
+
+        dev = NULL;
+    }
+    
+    if (NULL == dev)
+    {
+        DBG_LogWarning(LOG_ID_SD_0359, "[BDM_FW]:dev is NULL, sdid(%u).", param->sdId);
+
+        sdUpgradeAdapterNotifyDiskFWStateByWwn(param, FALSE, RETURN_OK, 
+                                      (void*)param, sdHandleNotifyDiskUpgradeStateOver); 
+        return;
+    }
+    
+    /*ǰòԶ״̬ʧTP */
+    if (TRUE == g_sdIONumCheckFailed)
+    {
+        DBG_LogInfo(LOG_ID_SD_0360, "Simu check io num failed, sdid(%u).", param->sdId);
+        result = RETURN_ERROR;
+    }
+
+    if (RETURN_OK == result)
+    {
+        /*Begin Modified by j00285232 CR-01770370 20150408*/
+        ret = upgradeHandle(param->sdId, (void*)param, sdUpgradeNewFWCallback);
+        /*End Modified by j00285232 CR-01770370 20150408*/
+        if (RETURN_OK == ret)
+        {
+            SD_PUT_DEVICE(dev);
+            return;
+        }
+    }
+    else if (param->times < 15)
+    {
+        param->times++;
+        cmd = &param->cmd;
+        (void)IOD_INIT_CMD(MY_PID, cmd);
+        cmd->execute = sdUpgradeFWDelaySendRequest;
+        *(SD_UPGRADE_FW_NEW_PARAM_S**)(cmd->privateData) = param;
+        IOD_ADD_DELAY_LOW_PRI_CMDQ(5000, cmd);
+        SD_PUT_DEVICE(dev);
+        return;
+    }
+
+    /*ʧܣórunning״̬*/
+    DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw failed: device(id %u).", param->sdId);
+    sdUpgradeAdapterNotifyDiskFWStateByWwn(param, FALSE, RETURN_OK, 
+                                        context, sdHandleNotifyDiskUpgradeStateOver);
+
+    SD_PUT_DEVICE(dev);
+}
+
+bool g_sdSendRequestDevNull = FALSE;
+
+/**************************************************************************
+   : sdUpgradeFWSendRequest
+     : Զ˷request
+ : dev  : sd豸
+ : 
+   ֵ:  
+     : 
+**************************************************************************/
+void sdUpgradeNewFWSendRequest(SD_UPGRADE_FW_NEW_PARAM_S *param)
+{
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    SD_DEVICE_ACTION_S *sdAction = NULL;
+    BDM_DEV_ACTION_S action;
+
+    dev = SD_DEVICE_LOOK_UP(param->sdId);
+    if (TRUE == g_sdSendRequestDevNull)
+    {
+        DBG_LogInfo(LOG_ID_SD_0358, "Simu dev is NULL, sdid(%u).", param->sdId);
+        if (NULL != dev)
+        {
+            SD_PUT_DEVICE(dev);
+        }
+
+        dev = NULL;
+    }
+
+    if (NULL == dev)
+    {
+        DBG_LogWarning(LOG_ID_SD_0359, "[BDM_FW]:dev is NULL, sdid(%u).", param->sdId);
+        param->callBack(UPGRADE_DISK_FW_RESU_FAIL, param->context);
+        sdUpgradeFreeNewParam(param);
+        return;
+    }
+    
+    disk = SD_GENERIC_TO_DISK(dev);
+    memset(&action, 0, sizeof(BDM_DEV_ACTION_S));
+    memcpy(action.wwn, disk->sn, DISK_SN_LEN);
+    action.actionId = 0;
+    action.actionType = ACTION_ALL_CTRL;
+    action.backendType = SD_BACKEND_SCSI_DEVICE;
+    action.needReportFinish = 0;
+    action.devId = INVALID_VALUE32;
+    action.done = sdUpgradeNewFWProcResponse;
+    action.context = (void*)param;
+
+    sdAction = (SD_DEVICE_ACTION_S*)action.devPrivate;
+    sdAction->module = MY_PID;
+    sdAction->opcode = SD_DEV_ACTION_TYPE_REQUEST_IONUM;
+    sdAction->recover.srcNid = GET_LOCAL_NID();
+    sdTriggerAction(&action, NULL, NULL);
+    SD_PUT_DEVICE(dev);
+}
+
+void sdDiskNormalOnlineUpgrade(void *context)
+{
+    SD_UPGRADE_DONE callBack = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
+    SD_SYNC_CALL_PARAM_S *backContext = NULL;
+    int ret = RETURN_ERROR;
+
+    callBack = param->callBack;
+    backContext = param->context;
+
+    DBG_LogWarning(LOG_ID_SD_0359, "[BDM_FW]:start disk[%u-%u] online upgrade power onoff.", 
+        param->frameId, param->slotId);
+
+    ret = HDM_DISK_POWER_ONOFF(param->frameId, param->slotId, 30, TRUE, context, sdUpgradeFWResetNewCallback);
+    if (RETURN_OK != ret)
+    {
+        DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:Disk %u online upgrade fw power off failed(ret %d).", param->sdId, ret);        
+        sdAdapterNotifyDiskFWUpgradeState(param->sdId, FALSE, RETURN_OK, NULL, NULL);
+        sdUpgradeFreeNewParam(param);
+        
+        callBack(UPGRADE_DISK_FW_RESU_FAIL, backContext);
+    }
+
+    return;
+}
+
+void sdDiskNormalOfflineUpgrade(void *context)
+{
+    SD_UPGRADE_DONE callBack = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+    SD_SYNC_CALL_PARAM_S *backContext = NULL;
+    int ret = RETURN_ERROR;
+
+    callBack = param->callBack;
+    backContext = param->context;
+
+    ret = HDM_DISK_POWER_ONOFF(param->frameId, param->slotId, 30, TRUE, context, sdUpgradeFWResetNewCallback);
+    if (RETURN_OK != ret)
+    {
+        DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:Disk[%u-%u] offline upgrade fw power off failed(ret %d).", param->frameId, param->slotId, ret);        
+        sdAdapterNotifyDiskFWUpgradeState(param->sdId, FALSE, RETURN_OK, NULL, NULL);
+        sdUpgradeFreeNewParam(param);
+        callBack(UPGRADE_DISK_FW_RESU_FAIL, backContext);
+    }
+    else
+    {
+        DBG_LogInfo(LOG_ID_SD_026C, "[BDM_FW]:dev(%u) offline end, ret(%d).", param->sdId, ret);
+        callBack(UPGRADE_DISK_FW_RESU_SUCCESS, backContext);
+    }
+    
+    return;
+}
+
+/**************************************************************************
+   : sdHssdUpFwGetDiskFwFail
+     : HSSDӲдϻȡfw汾ʧܴ
+ : context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdUpgradeFwGetDiskFwFail(void *context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    int32_t ret = RETURN_ERROR;
+
+    if(NULL == context)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw fail, context is NULL.");
+        return;
+    }
+
+    /*ע:ѾǰصвʹparamcallBackcontext*/
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+        
+    if(0 == param->upgradeMode)
+    {
+        sdDiskNormalOnlineUpgrade(context);
+    }
+    else
+    {
+        /*ͷԴµӲ*/
+        ret = HDM_DISK_POWER_ONOFF(param->frameId, param->slotId,
+                                   30, TRUE, context, sdUpgradeFWResetNewCallback);
+        if(RETURN_OK != ret)
+        {
+            DBG_LogWarning(LOG_ID_SD_026A, "[BDM_FW]:power onoff failed, sdid(%u).", param->sdId);
+
+            sdAdapterNotifyDiskFWUpgradeState(param->sdId, FALSE, RETURN_OK, NULL, NULL);
+            sdUpgradeFreeNewParam(param);
+        }
+    }
+
+    return;    
+}
+
+bool g_sdSetDiskParamFailed = FALSE;
+
+/**************************************************************************
+   : sdUpFwSetDiskParamDone
+     : HSSDӲɹ֮ò֮Ĵ
+ : result: ͬ
+           action: յaction
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdUpFwSetDiskParamDone(void *context, bool state)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_SYNC_CALL_PARAM_S *syncParam = NULL;
+    SD_UPGRADE_DONE callBack = NULL;
+
+    if(NULL == context)
+    {
+        DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:SD upgrade fw fail, context is NULL.");
+        return;
+    }
+
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+    syncParam = (SD_SYNC_CALL_PARAM_S *)param->context;
+    callBack = param->callBack;
+    
+    /*̲֮ʧTP */
+    if (TRUE == g_sdSetDiskParamFailed)
+    {
+        DBG_LogInfo(LOG_ID_SD_026D, "Simu sd set disk param failed, sdid[%u].", param->sdId);
+        state = FALSE;
+    }
+    
+    if(FALSE == state)
+    {
+        DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:SD upgrade fw set disk(%d) param fail.", param->sdId);
+        sdUpgradeFwGetDiskFwFail((void *)param);
+        return;
+    }
+    else
+    {
+        //sdUpdateDieFaultSwitch(param->sdId);/*DieʧЧ*/
+        
+        /*ָ״̬ͷԴ*/
+        /* Begin Modified by s00400440 DTS2018071300948 20180615 */
+        sdUpgradeAdapterNotifyDiskFWStateByWwn(param, FALSE, RETURN_OK, NULL, NULL);
+        if (0 == param->upgradeMode)
+        {
+            callBack(UPGRADE_DISK_FW_RESU_SUCCESS, (void *)syncParam);
+        }
+        
+        sdUpgradeFreeNewParam(param);
+        /* End Modified by s00400440 DTS2018071300948 20180615 */
+    }
+    
+    return;
+}
+
+bool g_sdUpNodeVerFailed = FALSE;
+
+/**************************************************************************
+   : sdUpDiskFwSyncFwResponse
+     : ͬFW汾ӦϢ
+ : result: ͬ
+           action: յaction
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdUpDiskFwSyncFwResponse(int32_t result, void *context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+
+    if(NULL == context)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade disk fw sync Response context is NULL.");
+        return;
+    }
+    param = (SD_UPGRADE_FW_NEW_PARAM_S*)context;
+
+    /*FWʧTP */
+    if (TRUE == g_sdUpNodeVerFailed)
+    {
+        DBG_LogInfo(LOG_ID_SD_026B, "Simu up all node version failed.");
+        result = RETURN_ERROR;
+    }
+
+    if (RETURN_OK == result)
+    {
+        if(RETURN_OK != HDM_DISK_IN(param->sdId, (void*)param, sdUpFwSetDiskParamDone))
+        {
+            /*̲ʧܣս̣⴦*/
+            DBG_LogWarning(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw set disk(%u) param fail.", param->sdId);
+            sdUpFwSetDiskParamDone(param, FALSE);
+        }
+    }
+    else
+    {
+        DBG_LogWarning(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade disk(%u) fw sync fw version to other node fail.", param->sdId);
+        
+        /*ƵFW汾ʧܣԭµ*/
+        sdUpgradeFwGetDiskFwFail((void *)param);
+    }
+
+    return;  
+}
+
+/**************************************************************************
+   : sdUpdateAllNodeFwVersion
+     : HSSDӲɹ֮fw汾ͬп
+ : sdId:ID
+           context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdUpdateAllNodeFwVersion(SCSI_DISK_DEVICE_S *disk, SD_UPGRADE_FW_NEW_PARAM_S *param)
+{
+    SD_DEVICE_NEW_ACTION_S *sdAction = NULL;
+    BDM_DEV_ACTION_S action;
+
+    if(NULL == param || NULL == disk)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD update all node fw version param is NULL.");
+        return;
+    }
+
+    memset(&action, 0, sizeof(BDM_DEV_ACTION_S));
+    memcpy(action.wwn, disk->sn, DISK_SN_LEN);
+    action.actionId = 0;
+    action.actionType = ACTION_DIRECT_BROADCAST;
+    action.backendType = SD_BACKEND_SCSI_DEVICE;
+    action.needReportFinish = 0;
+    /*Begin Modified by y00355707 DTS2017121408756 20171215*/
+    action.devId = INVALID_VALUE32;
+    /*End Modified by y00355707 DTS2017121408756 20171215*/
+    action.context = (void*)param;
+    action.done = sdUpDiskFwSyncFwResponse;
+
+    sdAction = (SD_DEVICE_NEW_ACTION_S *)action.devPrivate;
+    sdAction->module = MY_PID;
+    sdAction->specialband = 0;
+    memset(sdAction->reserved, 0x0, sizeof(uint32_t));
+    memcpy(sdAction->updateFw.firmware, (void *)disk->firmware, sizeof(sdAction->updateFw.firmware));
+    sdAction->opcode = SD_DEV_ACTION_TYPE_UPDATE_DISK_FW;
+
+    sdTriggerAction(&action, (void*)param, sdUpDiskFwSyncFwResponse);
+    return;
+}
+
+/**************************************************************************
+*     : жӲǷHSSD 1811
+* : disk: Ӳ̶
+* : 
+*   ֵ: TRUE: HSSD 1811
+            FALSE: HSSD 1811
+*     : 1811֧Trim
+**************************************************************************/
+bool sdIsHssd1811Disk(SCSI_DISK_DEVICE_S *disk)
+{
+    if(0 != strncmp(disk->model, "HSSD-D3", strlen("HSSD-D3")))
+    {
+         return FALSE;
+    }
+    return TRUE;
+}
+
+extern bool hdmDiskIsSSD(uint32_t sdevId);
+extern HDM_VENDOR_E hdmGetDiskVendor(uint32_t sdevId);
+/**************************************************************************
+   : sdCheckDiskCanFastActiveFW
+     : жǷʹÿټfw
+ : disk:̶
+ : 
+   ֵ: true-ʹÿټfalseʹÿټ
+     : 
+**************************************************************************/
+bool sdCheckDiskCanFastActiveFW(SD_SCSI_DEVICE_S *dev)
+{
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    HDM_VENDOR_E vendor = HDM_VENDOR_BUTT;
+    
+    if (NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:disk is NULL.");
+        return FALSE;
+    }
+    disk = SD_GENERIC_TO_DISK(dev);
+
+    /* ⹺HDDֿ֧ټ· */
+    if (hdmDiskIsSSD(disk->device.sdevId))
+    {
+        vendor = hdmGetDiskVendor(disk->device.sdevId);
+        /*⹺SSDboot code,ҪµЧ */
+        switch (vendor)
+        {
+            case HDM_VENDOR_HUASY:
+            {
+                if (sdIsHssd1811Disk(disk))
+                {
+                    if((0 == strcmp(disk->model, "HSSD-D3J2JAM5400"))
+                        || (0 == strcmp(disk->model, "HSSD-D3J2LAM5400"))
+                        || (0 == strcmp(disk->model, "HSSD-D3J2JAM5600"))
+                        || (0 == strcmp(disk->model, "HSSD-D3J2LAM5600")))
+                    {
+                        return TRUE;//ĸmodel֧
+                    }
+                    else
+                    {
+                        return FALSE;//1811ĸⲻ֧
+                    }
+                }
+                else
+                {
+                    return TRUE;//1812Ժ֧
+                }
+            }
+            case HDM_VENDOR_HITACHI:
+            case HDM_VENDOR_SEAGATE:
+            case HDM_VENDOR_WD:
+            case HDM_VENDOR_DELL:
+            case HDM_VENDOR_STEC:
+            case HDM_VENDOR_ATA:
+            case HDM_VENDOR_INTEL:
+            case HDM_VENDOR_BUTT:
+            default:
+                return FALSE;//⹺SSD֧
+        }
+    }
+    else
+    {
+        return TRUE;//⹺HDD֧
+    }
+}
+
+/**************************************************************************
+   : sdDiskUpgradeFw
+     : ӲдFW̳ɹ֮µִк
+ : context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdDiskUpgradeFw(void *context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;    
+
+    //ͷԴµ磬һͷԴŵsdDiskOfflineUpgrade
+    if (0 == param->upgradeMode)
+    {
+        sdDiskNormalOnlineUpgrade(context);
+    }
+    else
+    {
+        sdDiskNormalOfflineUpgrade(context);
+    }
+    
+    return;
+}
+
+/**************************************************************************
+   : sdNvmeDiskUpgradeFw
+     : ӲдFW̳ɹ֮µִк
+ : context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdNvmeDiskUpgradeFw(SD_SCSI_DEVICE_S *dev, void *context)
+{
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;    
+
+    disk = SD_GENERIC_TO_DISK(dev);
+
+    if (0 == param->upgradeMode)
+    {
+        sdNvmeDiskUpgrade(disk, dev, context, TRUE);
+    }
+    else
+    {
+        sdNvmeDiskUpgrade(disk, dev, context, FALSE);
+    }
+    
+    return;
+}
+
+
+/**************************************************************************
+   : sdIdentifyReqStart
+     : ·IdentifySGLɹִ֮к
+ : SGL_S *sgl
+           void *context
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdAllocInquiryPageDone(SGL_S *sgl, void *context)
+{
+    uint32_t index = 0;
+    REQ_S *req = NULL;
+
+    req = (REQ_S *)context;
+    if (NULL == sgl)
+    {
+        DBG_LogError(LOG_ID_SD_0260, "[BDM_FW]:Alloc page failed.");
+        req->result = RETURN_ERROR;
+        IOD_ADD_DONEQ(req);
+        return;
+    }
+    
+    for ( index = 0; index < sgl->entrySumInSgl; ++index )
+    {
+        memset(sgl->entrys[index].buf, 0, sgl->entrys[index].len);
+    }
+    sgl->entrys[0].len = SD_SCSI_DEFAULT_BUFF_LEN;
+       
+    req->sgl = sgl;
+    IOD_ADD_STARTQ(req);
+
+    return;
+}
+
+/**************************************************************************
+   : sdInquiryInner
+     : ·Inquiry
+ : REQ_S *req
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdInquiryInner(REQ_S *req, uint8_t page)
+{
+    uint8_t cdb[SD_MAX_CDB_LEN];
+
+    memset(cdb, 0, SD_MAX_CDB_LEN);
+    req->opCode = SD_IO_OPCODE_PC;
+    req->bufOffsetNByte = 0;
+
+    cdb[0] = INQUIRY;
+    cdb[1] = 0;
+    cdb[2] = page;
+    cdb[5] = 0;
+    if ( 0 == page )
+    {
+        cdb[3] = 0x00;
+        cdb[4] = 0x24;
+    }
+    else
+    {
+        cdb[1] = 1;
+        cdb[3] = 0;
+        cdb[4] = 32;
+    }
+    
+    sioFillCmd2Req(req, cdb, DMA_FROM_DEVICE, SD_SCSI_DEFAULT_BUFF_LEN,
+                   1, SD_SCSI_TIMEOUT, SD_SCSI_FLAG);
+
+    SET_INNER_IO_PRIORITY_BY_IO_TYPE(INVALID_VALUE64, DISK_IO, &req->priority);
+    ALLOC_MULTI_PAGES(INVALID_VOLUME_ID, INVALID_VOLUME_ID, 1,PAGE_USAGE_BDM_PC, 
+                      req->priority, sdAllocInquiryPageDone, req);
+    
+}
+
+/**************************************************************************
+   : sdInquiryChildReqFree
+     : ·InquiryChild Reqִ֮ͷԴ
+ : REQ_S *req
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdInquiryChildReqFree(REQ_S *req)
+{
+    REQ_S *parent = NULL;
+
+    if ( NULL != req->sgl )
+    {
+        FREE_PAGES_AND_SGL(INVALID_VOLUME_ID, INVALID_VOLUME_ID, req->sgl, PAGE_USAGE_BDM_PC);
+    }
+
+    parent = req->parent;
+    parent->result = req->result;
+
+    REQ_DELETE(req);
+
+    IOD_ADD_DONEQ(parent);
+}
+
+
+/**************************************************************************
+   : sdIdentifyResultGetFw
+     : Identifyִгɹsglнfw汾
+ : SD_SCSI_DEVICE_S *dev
+           SGL_S *sgl
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdInquiryResultGetFw(SCSI_DISK_DEVICE_S *disk, SGL_S *sgl)
+{ 
+    if(NULL == disk)
+    {
+        DBG_LogError(LOG_ID_SD_0260, "[BDM_FW]:Get disk fw fail, dev is NULL.");
+        return;
+    }
+    
+    /*SCSI inquiryЭƫ32ֽڿʼ4ֽΪfw汾*/
+    LVOS_strncpy(disk->firmware, sgl->entrys[0].buf + 32, 5);
+    sdStrStrip(disk->firmware);
+    
+    BDM_LOG_INFO_CAN_PRINT(LOG_ID_SD_016A, 60 * HZ, (uint64_t)disk->slotId, 
+        "[BDM_FW]:SD identify disk(%u,%u) fw=(%s).", disk->frameId, disk->slotId, disk->firmware);
+    return;
+}
+
+void fillScsiAtaIdentifyCdb(uint8_t cdb[])
+{    
+    /**cdb*/
+    cdb[0] = ATA_16;    //0x85
+    cdb[1] = 0x09;
+    cdb[2] = 0x0e;
+    
+    cdb[3] = 0xff;
+    cdb[4] = 0x00;
+    
+    cdb[5] = 0x00;
+    cdb[6] = 0x01;
+    
+    cdb[7] = 0x00;
+    cdb[8] = 0x01;
+    
+    cdb[9] = 0x00;
+    cdb[10] = 0x00;
+    
+    cdb[11] = 0x00;
+    cdb[12] = 0x00;
+    
+    cdb[13] = 0xa0;
+    cdb[14] = 0xec;
+    cdb[15] = 0x00;
+}
+
+/**************************************************************************
+   : sdHddIdentifyResultGetFw
+     : Identifyִгɹsglнfw汾
+ : SD_SCSI_DEVICE_S *dev
+           SGL_S *sgl
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdSataIdentifyResultGetFw(SCSI_DISK_DEVICE_S *disk, SGL_S *sgl)
+{ 
+    uint32_t idx = 0;
+    char *fw = NULL;
+    char *buf = NULL;
+    char temp = 0;
+    
+    if ((NULL == disk) || (NULL == sgl))
+    {
+        DBG_LogError(LOG_ID_SD_0260, "[BDM_FW]:disk or sgl is NULL.");
+        return;
+    }
+
+    fw = disk->firmware;
+    buf = sgl->entrys[0].buf;
+
+    /* SATA identifyЭÿ2ֽ˳ߵҪתֽ */
+    /* M: 46ֽڿʼ8ֽΪfw汾 */
+    memcpy(fw, buf + 46, 8);
+    for (idx = 0; idx < 4; idx++)
+    {
+        temp = fw[2 * idx];
+        fw[2 * idx] = fw[2 * idx + 1];
+        fw[2 * idx + 1] = temp;
+    }
+    fw[8] = '\0';
+
+    sdStrStrip(fw);
+    
+    BDM_LOG_INFO_CAN_PRINT(LOG_ID_SD_016A, 60 * HZ, (uint64_t)disk->slotId, 
+        "[BDM_FW]:SD identify disk(%u,%u) fw=(%s).", disk->frameId, disk->slotId, disk->firmware);
+    return;
+}
+
+/**************************************************************************
+   : sdHddInquiryInner
+     : ·Inquiry
+ : REQ_S *req
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdSataIdentifyInner(REQ_S *req)
+{
+    uint8_t cdb[SD_MAX_CDB_LEN];
+
+    memset(cdb, 0, SD_MAX_CDB_LEN);
+    fillScsiAtaIdentifyCdb(cdb);
+
+    req->opCode = SD_IO_OPCODE_PC;
+    req->bufOffsetNByte = 0;
+
+    sioFillCmd2Req(req, cdb, DMA_FROM_DEVICE, SD_SCSI_DEFAULT_BUFF_LEN,
+                   1, SD_SCSI_TIMEOUT, SD_SCSI_FLAG);
+
+    SET_INNER_IO_PRIORITY_BY_IO_TYPE(INVALID_VALUE64, DISK_IO, &req->priority);
+    ALLOC_MULTI_PAGES(INVALID_VOLUME_ID, INVALID_VOLUME_ID, 1,PAGE_USAGE_BDM_PC, 
+                      req->priority, sdAllocInquiryPageDone, req);
+    
+}
+
+/**************************************************************************
+   : sdInquiryReqStart
+     : ·InquiryREQstart
+ : REQ_S *req
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+int32_t sdQueryFWReqStart(REQ_S *req)
+{
+    REQ_S *childReq = NULL;
+    SD_QUERY_PARAM_S *data = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    GENIO_S genIo;
+
+    memset(&genIo, 0, sizeof(GENIO_S));
+
+    data = (SD_QUERY_PARAM_S*)(void*)(req->producerPrivate);
+    dev = SD_DEVICE_LOOK_UP(data->sdId);
+    if(NULL == dev)
+    {
+        req->result = RETURN_ERROR;
+        IOD_ADD_DONEQ(req);
+        return RETURN_ERROR;
+    }
+    disk = SD_GENERIC_TO_DISK(dev);
+
+    copyReq2Genio(&genIo, req);
+
+    childReq = sdIoGen(&genIo);
+    if(NULL == childReq)
+    {
+        req->result = RETURN_ERROR;
+        IOD_ADD_DONEQ(req);
+        SD_PUT_DEVICE(dev);
+        return RETURN_ERROR;
+    }
+
+    childReq->ctrlFlag = SD_CLEAR_FLAG;
+    sioSetReqFlag(childReq, BDM_REQ_FLAG_SINGLE_CTRL);
+
+    if (DISK_TYPE_SATA == disk->type)
+    {
+        sdSataIdentifyInner(childReq);
+    }
+    else
+    {
+        sdInquiryInner(childReq, SD_INQUIRY_STANDARD);
+    }
+
+    SD_PUT_DEVICE(dev);
+    return RETURN_OK;
+}
+
+/**************************************************************************
+   : sdInquiryReqDone
+     : ·InquiryREQDone
+ : REQ_S *req
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+int32_t sdQueryFWReqDone(REQ_S *req)
+{
+    SD_QUERY_PARAM_S *data = NULL;
+    SD_UPGRADE_DONE callBack = NULL;
+    int32_t result = RETURN_ERROR;
+
+    data = (SD_QUERY_PARAM_S*)(void*)(req->producerPrivate);
+    callBack = data->callBack;
+
+    result = (RETURN_OK == req->result ? RETURN_OK : RETURN_ERROR);
+    
+    /*صѯ̵FW֮Ĵ*/
+    callBack(result, data->context);
+
+    REQ_DELETE(req);
+
+    return RETURN_OK;   
+}
+
+/**************************************************************************
+   : sdInquiryReqChildDone
+     : ·InquiryREQChild Done
+ : REQ_S *selfReq
+           REQ_S *childReq
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdQueryFWReqChildDone(REQ_S *selfReq, REQ_S *childReq)
+{
+    SD_QUERY_PARAM_S *data = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    int32_t result = RETURN_ERROR;
+
+    if(NULL == selfReq || NULL == childReq)
+    {
+        DBG_LogError(LOG_ID_SD_0260, "[BDM_FW]:Inquiry cmd fail, selfReq or childReq is NULL.");
+        return;
+    }
+
+    data = (SD_QUERY_PARAM_S*)(void*)(selfReq->producerPrivate);
+    data->retryTimes++;
+
+    DBG_LogDebug(LOG_ID_SD_0260, "[BDM_FW]:inquiry child done, times[%u], opcode[%u], result[%d].", 
+        data->retryTimes, childReq->opCode, childReq->result);
+
+    /* жǷﵽʱʱ */
+    if (data->timeout < (int64_t)(jiffies - data->startJiffies))
+    {
+        //ͷreqreq Done
+        sdInquiryChildReqFree(childReq);
+
+        DBG_LogInfo(LOG_ID_SD_0260, "[BDM_FW]:inquiry timeout, times[%u], opcode[%u], result[%d].", 
+            data->retryTimes, childReq->opCode, childReq->result);
+        return;
+    }
+
+    if(RETURN_OK != childReq->result)
+    {
+        if(data->retryTimes >= UP_ACTIVE_FW_VERSION_CHECK_CYCLES)
+        {
+            //ͷreqreq Done
+            sdInquiryChildReqFree(childReq);
+        }
+        else
+        {
+            /*ӳ*/
+            IOD_ADD_DELAY_STARTQ(g_sdFWDelayTime, childReq);
+        }
+        return;
+    }
+
+    dev = SD_DEVICE_LOOK_UP(data->sdId);
+    if(NULL == dev)
+    {
+        if(data->retryTimes >= UP_ACTIVE_FW_VERSION_CHECK_CYCLES)
+        {
+            //ͷreqreq Done
+            sdInquiryChildReqFree(childReq);
+        }
+        else
+        {
+            /*ӳ*/
+            IOD_ADD_DELAY_STARTQ(g_sdFWDelayTime, childReq);
+        }
+        return;
+    }
+    disk = SD_GENERIC_TO_DISK(dev);
+    
+    /*sglнfw*/
+    if (DISK_TYPE_SATA == disk->type)
+    {
+        sdSataIdentifyResultGetFw(disk, childReq->sgl);
+    }
+    else
+    {
+        sdInquiryResultGetFw(disk, childReq->sgl);
+    }
+
+    /*汾ǷѾ£Ѹ»ԴﵽʮΣѯ̽*/
+    result = sdCheckFwVersion(disk);
+    if(RETURN_OK == result || (data->retryTimes >= UP_ACTIVE_FW_VERSION_CHECK_CYCLES))
+    {
+        sdInquiryChildReqFree(childReq);
+    }
+    else
+    {
+        IOD_ADD_DELAY_STARTQ(g_sdFWDelayTime, childReq);
+    }
+    
+    SD_PUT_DEVICE(dev);
+    return;
+}
+
+
+/**************************************************************************
+   : sdIdentifyReqDelete
+     : ·IdentifyREQDelete
+ : REQ_S *req
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdQueryFWReqDelete(REQ_S *req)
+{
+    FREE_REQ(req);
+
+    return;
+}
+
+REQ_OPS_S s_sdInquiryFWOps = 
+{
+    "SD_INQUIRY_FW_CMD",
+    sdQueryFWReqStart,
+    sdQueryFWReqDone,
+    sdQueryFWReqChildDone,
+    sdQueryFWReqDelete
+};
+
+/**************************************************************************
+   : sdInquiryCmdIoGen
+     : ·InquiryREQ
+ : GENIO_S *genIo
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+REQ_S* sdInquiryCmdIoGen(GENIO_S *genIo)
+{
+    REQ_S *req = NULL;
+
+    ALLOCATE_REQ(&req);
+
+    if(NULL == req)
+    {
+        DBG_LogError(LOG_ID_SD_0169, "[BDM_FW]:Alloc REQ failed.");
+        return NULL;
+    }
+
+    copyGenio2Req(req, genIo);
+    req->ops = &s_sdInquiryFWOps;
+    
+    return req;
+}
+
+/**************************************************************************
+   : sdGetDiskFwBack
+     : HSSDӲ̼Ӳ̰汾Ƿ֮Ļص
+ : result:ȡ汾Ž
+           context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdGetDiskFwBack(int32_t result, void * context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+
+    if(NULL == context)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw fail, context is NULL.");
+        return;
+    }
+
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+
+    dev = SD_DEVICE_LOOK_UP(param->sdId);
+    if(NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw fail, dev(%u) is NULL.", param->sdId);
+        /* Begin Modified by s00400440 DTS2018070908746 20180615 */
+        sdUpgradeAdapterNotifyDiskFWStateByWwn(param, FALSE, RETURN_OK, 
+                                      (void*)param, sdHandleOutDiskOver); 
+        /* End Modified by s00400440 DTS2018070908746 20180615 */
+        return;
+    }
+    disk = SD_GENERIC_TO_DISK(dev);
+
+    if((RETURN_OK == result) && (RETURN_OK == sdCheckFwVersion(disk)))
+    {
+        DBG_LogInfo(LOG_ID_SD_026A, "[BDM_FW]:SD get fw success, disk(%u) new fw(%s), mode(%d), type(%d).",
+                    dev->sdevId, disk->firmware, param->upgradeMode, param->upgradeType);
+        /*µfw汾ͬ*/
+        sdUpdateAllNodeFwVersion(disk, param);         
+    }
+    else
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD get disk fw fail(result:%d), disk(%u) new fw(%s), mode(%d), type(%d).",
+                    result, dev->sdevId, disk->firmware, param->upgradeMode, param->upgradeType);
+        sdUpgradeFwGetDiskFwFail((void *)param);
+    }
+
+    SD_PUT_DEVICE(dev);
+    return;
+}
+
+/**************************************************************************
+   : sdSendInquiryCmd
+     : ·Inquiryȡ(SAS)FW汾
+ : sdevId: ̵ID
+           context: 
+           callBack: ȡFW֮Ļص
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+int32_t sdSendInquiryCmd(SD_SCSI_DEVICE_S *dev, void *context, SD_UPGRADE_DONE callBack)
+{
+    REQ_S *req = NULL;
+    GENIO_S genIo;
+    SD_QUERY_PARAM_S *data = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = context;
+
+    memset(&genIo, 0, sizeof(GENIO_S));
+    genIo.objectId = dev->sdevId;
+
+    req = sdInquiryCmdIoGen(&genIo);
+    if(NULL == req)
+    {
+        DBG_LogError(LOG_ID_SD_026A,
+            "[BDM_FW]:SD disk(%u) upgrade fw fail, alloc req fail.", dev->sdevId);
+        return RETURN_ERROR;
+    }
+
+    data = (SD_QUERY_PARAM_S*)(void*)(req->producerPrivate);
+    data->sdId = dev->sdevId;
+    data->retryTimes = param->getFwTimes;
+    data->context = context;
+    data->callBack = callBack;
+    data->startJiffies = jiffies;
+    data->timeout = (UP_ACTIVE_FW_VERSION_CHECK_CYCLES - param->getFwTimes) * HZ;
+
+    IOD_ADD_STARTQ(req);
+
+    return RETURN_OK;
+}
+
+/**************************************************************************
+   : sdUpgradeFwGetDiskFw
+     : HSSDӲмӲ̵FW汾ִк
+ : sdId:ID
+           context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+int32_t sdUpgradeFwGetDiskFw(uint32_t sdId, SD_UPGRADE_FW_NEW_PARAM_S *param)
+{
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    int32_t result = RETURN_ERROR;
+    int32_t ret = RETURN_ERROR;    
+
+    dev = SD_DEVICE_LOOK_UP(sdId);
+    if(NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw failed, dev is NULL.");
+        return RETURN_ERROR;
+    }
+
+    disk = SD_GENERIC_TO_DISK(dev);
+
+    ret = sdCheckFwVersion(disk);
+    if(RETURN_OK == ret)
+    {
+        /*û̼汾ţ̵İ汾žѾµģ˵ѾϱOUTIN¼ߺ*/
+        DBG_LogInfo(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw, disk(%u) fw is new, no need to check fw version.", sdId);
+        sdGetDiskFwBack(RETURN_OK, (void *)param);
+        SD_PUT_DEVICE(dev);
+        return RETURN_OK; 
+    }
+        
+    /*Ӳ̵FW汾ǷѾ*/
+    DBG_LogInfo(LOG_ID_SD_026A, "[BDM_FW]:dev(%u) inquiry FW cmd start.", dev->sdevId);
+    result = sdSendInquiryCmd(dev, (void*)param, sdGetDiskFwBack);
+
+    SD_PUT_DEVICE(dev);
+    return result;       
+}
+
+/**************************************************************************
+   : sdUpgradeReleaseBackByResult
+     : Ӳµ汾ص
+ : param:
+           result:
+ : 
+   ֵ: 
+     : resultΪRETURN_OKɹʧ
+**************************************************************************/
+void sdUpgradeReleaseBackByResult(SD_UPGRADE_FW_NEW_PARAM_S *param, int32_t result)
+{
+    SD_SYNC_CALL_PARAM_S *backContext = NULL;
+    SD_UPGRADE_DONE callBack = NULL;
+
+    /*  */
+    if((NULL == param) || (NULL == param->context) || (NULL == param->callBack))
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:param is invalid, param(%p).",
+            param);
+        return;
+    }
+    callBack = param->callBack;
+    backContext = param->context;
+
+    sdUpgradeAdapterNotifyDiskFWStateByWwn(param, FALSE, RETURN_OK, NULL, NULL);
+    /* 0ΪҪص */
+    if (0 == param->upgradeMode)
+    {
+        if (RETURN_OK == result)
+        {
+            callBack(UPGRADE_DISK_FW_RESU_SUCCESS, backContext);
+        }
+        else
+        {
+            callBack(UPGRADE_DISK_FW_RESU_FAIL, backContext);
+        }
+    }
+    sdUpgradeFreeNewParam(param);
+}
+
+bool g_sdActiveCheckDiskFailed = FALSE;
+/**************************************************************************
+   : sdHssdGetDiskFwFunc
+     : HSSDӲмӲ̵FW汾ִк
+ : context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdUpgradeGetDiskFwFunc(void *context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_SCSI_DEVICE_S *dev = NULL;
+    int32_t timerId = 0;
+    int result = RETURN_ERROR;
+    uint32_t sdId = INVALID_VALUE32;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+
+    if(NULL == context)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw fail, context is NULL.");
+        return;
+    }
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+
+    sdId = sdGetDeviceByPositionId(param->frameId, param->slotId);
+    
+    /*еȴ̽ʧTP*/
+    if(TRUE == g_sdActiveCheckDiskFailed)
+    {
+        BDM_LOG_INFO_CAN_PRINT(LOG_ID_SD_026B, 60 * HZ, (uint64_t)param->sdId, 
+            "[BDM_FW]: Simu check disk(%u-%u) failed.", param->frameId, param->slotId);
+        sdId = INVALID_VALUE32;
+    }
+    
+    dev = SD_DEVICE_LOOK_UP(sdId);
+
+    if(param->getFwTimes < UP_ACTIVE_FW_VERSION_CHECK_CYCLES)
+    {
+        if(NULL != dev)
+        {
+            result = sdUpgradeFwGetDiskFw(sdId, (void *)param);
+            if(RETURN_OK == result)
+            {
+                SD_PUT_DEVICE(dev);
+                return;
+            }
+        }
+    }
+    else if (UP_ACTIVE_FW_VERSION_CHECK_CYCLES == param->getFwTimes)
+    {
+        /*ʱʱһֱδFWһֱδ仯ִµ糢Խ򼤻*/
+        DBG_LogWarning(LOG_ID_SD_026A, "[BDM_FW]:disk[%u] is not in or unactivate, try to poweronoff.", 
+            param->slotId);
+        result = HDM_DISK_POWER_ONOFF(param->frameId, param->slotId, UP_POWER_ON_OFF_INTERVAL_TIME, TRUE, NULL, sdUpgradeFWResetCallback);
+        if (RETURN_OK != result)
+        {
+            DBG_LogError(LOG_ID_SD_026C, "[BDM_FW]:Disk %u check version failed(times %u).", param->sdId, param->getFwTimes);        
+            sdUpgradeReleaseBackByResult(param, RETURN_ERROR);
+            SD_PUT_DEVICE(dev);
+            return;
+        }
+    }
+    else if (param->getFwTimes <= UP_ACTIVE_FW_VERSION_CHECK_CYCLES + UP_AFTER_CHECK_CYCLES_TIMES)
+    {
+        /*ִµֻһFW汾*/
+        if (NULL != dev)
+        {
+            disk = SD_GENERIC_TO_DISK(dev);
+            result = sdCheckFwVersion(disk);
+            DBG_LogInfo(LOG_ID_SD_026C, "[BDM_FW]:Disk %u check version %s after poweronoff.", 
+                param->sdId, (RETURN_OK == result) ? "success" : "fail");        
+            sdUpgradeReleaseBackByResult(param, result);
+            SD_PUT_DEVICE(dev);
+            return;
+        }
+    }
+    else
+    {
+        DBG_LogError(LOG_ID_SD_026B, "[BDM_FW]:Disk %u check version end(times %u).", param->sdId, param->getFwTimes);        
+        sdUpgradeReleaseBackByResult(param, RETURN_ERROR);
+        SD_PUT_DEVICE(dev);
+        return;
+    }
+
+    param->getFwTimes++;
+    
+    /*´ʱ*/
+    timerId = IOD_CREATE_TIMER("GET_DISK_FW_VERSION.",
+                               UP_FW_VERSION_CHECK_INTERVAL, 
+                               sdUpgradeGetDiskFwFunc, 
+                               (void *)param, 
+                               IOD_TIMER_TYPE_ONE);
+    if(timerId <= 0)
+    {
+        /*ʱʧܣԭ*/
+        DBG_LogWarning(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw, create disk[%u] timer check fw fail.", param->slotId);
+        sdUpgradeFwGetDiskFwFail((void *)param);
+    }
+
+    SD_PUT_DEVICE(dev);
+    return;
+}
+
+/**************************************************************************
+   : sdHssdGetDiskFW
+     : HSSDӲмӲ̵FW汾Ƿ
+ : context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+int32_t sdUpgradeGetDiskFW(void *context)
+{
+    int32_t timerId = 0;
+
+    timerId = IOD_CREATE_TIMER("GET_DISK_FW_VERSION.",
+                               UP_FW_DELAY_GET_DISK_FW_VERSION, 
+                               sdUpgradeGetDiskFwFunc, 
+                               context, 
+                               IOD_TIMER_TYPE_ONE);
+    if(timerId <= 0)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw, get disk fw create timer fail.");
+        return RETURN_ERROR;
+    }
+
+    return RETURN_OK;
+}
+
+/**************************************************************************
+   : sdHssdUpFwActivaSuccess
+     : HSSDӲ̼ټ·ɹ֮Ĵ
+ : state:ټ·
+           context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdUpgradeFwActivateSuccess(void *context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SD_SYNC_CALL_PARAM_S *backContext = NULL;
+    SD_UPGRADE_DONE callBack = NULL;
+    int ret = RETURN_ERROR;
+
+    if(NULL == context)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:context is NULL.");
+        return;
+    }
+
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+    backContext = (SD_SYNC_CALL_PARAM_S *)param->context;
+    callBack = param->callBack;
+
+    if(0 != param->upgradeMode)
+    {
+        /*ȻصɹԴݲͷ*/
+        callBack(UPGRADE_DISK_FW_RESU_SUCCESS, (void *)backContext);
+    }
+        
+    //̼FW汾
+    ret = sdUpgradeGetDiskFW(context);
+    if(RETURN_OK != ret)
+    {
+        sdUpgradeFwGetDiskFwFail(context);
+    }
+
+    return;    
+}
+
+/**************************************************************************
+   : sdUpgradeFWActivateCallback
+     : HSSDӲ̼ټ·ִ֮к
+ : state:ټ·
+           context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdUpgradeFWActivateCallback( void *context, bool state)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+
+    if(NULL == context)
+    {
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw failed: context is NULL.");
+        return;
+    }
+  
+    if(TRUE == state)
+    {
+        sdUpgradeFwActivateSuccess(context);
+    }
+    else
+    {
+        /*·ټʧܣԭµ*/
+        DBG_LogError(LOG_ID_SD_026A, "[BDM_FW]:SD upgrade fw, activate dev(%u) fw fail.", param->sdId);
+        sdDiskUpgradeFw(context);
+    }
+       
+    return;
+    
+}
+
+extern int32_t hdmUpgradeActiveDiskFw(uint32_t frameId, uint32_t slotId, void *context, HDM_STATE_DONE done);
+/**************************************************************************
+   : sdFastActiveFw
+     : HSSDӲдFW̳ɹִ֮к
+ : context:
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdFastActivateFw(SD_SCSI_DEVICE_S *dev, void *context)
+{
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    int ret = RETURN_ERROR;
+
+    if((NULL == dev) || (NULL == context))
+    {
+        DBG_LogError(LOG_ID_SD_026A, "SD upgrade fw failed: invalid param, dev(%p), context(%p).",
+            dev, context);
+        return;
+    }
+
+    param = (SD_UPGRADE_FW_NEW_PARAM_S *)context;
+    disk = SD_GENERIC_TO_DISK(dev);
+
+    DBG_LogInfo(LOG_ID_SD_0359, "[BDM_FW]:disk[%u-%u] activate FW start, model(%s), vendor(%s), mode(%u).", 
+        disk->frameId, disk->slotId, disk->model, disk->vendor, param->upgradeMode);
+
+    /*ÿټӿʧܣԭµ*/
+    ret = hdmUpgradeActiveDiskFw(disk->frameId, disk->slotId, context, sdUpgradeFWActivateCallback);
+    if(RETURN_OK != ret)
+    {
+        DBG_LogWarning(LOG_ID_SD_0360, "[BDM_FW]:activate FW failed, disk(%u-%u) need power onoff.", 
+            disk->frameId, disk->slotId);
+
+        sdDiskUpgradeFw(context);
+    }
+
+    return;
+    
+}
+
+/**************************************************************************
+   : sdDiskUpgrade
+     : ӲдFW̳ɹִ֮к
+ : context:
+           disk:̶
+ : 
+   ֵ: 
+     : 
+**************************************************************************/
+void sdDiskUpgrade(SD_SCSI_DEVICE_S *dev, void *context)
+{
+    if (sdIsNvmeDev(dev))
+    {
+        sdNvmeDiskUpgradeFw(dev, context);
+    }
+    else
+    {
+        if (sdCheckDiskCanFastActiveFW(dev))
+        {
+            sdFastActivateFw(dev, context);
+        }
+        else
+        {
+            sdDiskUpgradeFw(context);
+        }
+    }
+    
+    return;  
+}
+
+SD_UPGRADE_FW_NEW_PARAM_S* sdUpgradeFWFindNewParamByDevId(uint32_t sdevId)
+{
+    struct list_head *node = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *param = NULL;
+    
+    list_for_each(node, &g_sdUpgradeFwList)
+    {
+        param = list_entry(node, SD_UPGRADE_FW_NEW_PARAM_S, head);
+        if (param->sdId == sdevId)
+        {
+            return param;
+        }
+    }
+
+    return NULL;
+}
+
+int32_t sdUpgradeFWparamInit(uint32_t sdId, void *context, int32_t type,
+                                    void (*callBack)(int32_t result, void *context), void **param)
+{
+    SD_SCSI_DEVICE_S *dev = NULL;
+    SCSI_DISK_DEVICE_S *disk = NULL;
+    SD_UPGRADE_FW_NEW_PARAM_S *newParam = NULL;
+    SD_SYNC_CALL_PARAM_S *syncParam = NULL;
+    int32_t ret = RETURN_ERROR;
+
+    /*豸Ƿ*/
+    dev = SD_DEVICE_LOOK_UP(sdId);
+    if (NULL == dev)
+    {
+        DBG_LogError(LOG_ID_SD_026F, "[BDM_FW]:device(%u) does not exist.", sdId);
+        return UPGRADE_DISK_NOT_EXIST;
+    }
+    
+    ret = ALLOCATE_PUB_STRUCTURE(sizeof(SD_UPGRADE_FW_NEW_PARAM_S), (void**)&newParam);
+    if ((RETURN_OK != ret) || (NULL == newParam))
+    {
+        DBG_LogError(LOG_ID_SD_0275, "[BDM_FW]:device(%u) alloc structure failed, ret(%d).", sdId, ret);
+        SD_PUT_DEVICE(dev);
+        return UPGRADE_DISK_FW_RESU_FAIL;    
+    }
+    memset(newParam, 0, sizeof(SD_UPGRADE_FW_NEW_PARAM_S));
+
+    spin_lock(&g_sdUpgradeFwListLock);
+    if (NULL != sdUpgradeFWFindNewParamByDevId(sdId))
+    {
+        spin_unlock(&g_sdUpgradeFwListLock);
+        DBG_LogError(LOG_ID_SD_0276, "[BDM_FW]:SD upgrade fw failed: device(id %u) is already upgrading.", sdId);
+        SD_PUT_DEVICE(dev);
+        FREE_PUB_STRUCTURE(newParam);
+        newParam = NULL;
+        return UPGRADE_DISK_FW_RESU_UPGRADE;
+    }
+
+    disk = SD_GENERIC_TO_DISK(dev);
+    syncParam = (SD_SYNC_CALL_PARAM_S *)context;
+    newParam->upgradeMode = (uint8_t)syncParam->upgradeMode;
+    newParam->sdId = sdId;
+    newParam->frameId = disk->frameId;
+    newParam->slotId = disk->slotId;
+    newParam->context = context;
+    newParam->callBack = callBack;
+    newParam->upgradeType = (SD_UPGRADE_TYPE_E)type;
+    newParam->diskType = disk->type;
+    memcpy(newParam->wwn, disk->sn, DISK_SN_LEN);
+    newParam->fw[DISK_FIRMWARE_LEN - 1] = '\0';
+    list_add_tail(&newParam->head, &g_sdUpgradeFwList);
+    spin_unlock(&g_sdUpgradeFwListLock);
+
+    *param = newParam;
+
+    SD_PUT_DEVICE(dev);
+    return UPGRADE_DISK_FW_RESU_BUTT;
+}
+
+/**************************************************************************
+   : sdUpgradeUpdateFWconf
+     : ͸ºڰaction
+ : void
+ : 
+   ֵ: RETURN_OK:ִгɹRETURN_ERROR:ʧ
+     : 
+**************************************************************************/
+void sdUpgradeUpdateFWConfRequest(void *context, void (*CallBack)(int32_t, void *))
+{
+    SD_DEVICE_ACTION_S *sdAction = NULL;
+    BDM_DEV_ACTION_S action;
+
+    memset(&action, 0, sizeof(BDM_DEV_ACTION_S));
+    //memcpy(action.wwn, disk->sn, DISK_SN_LEN);
+    action.actionId = 0;
+    action.actionType = ACTION_ALL_CTRL;
+    action.backendType = SD_BACKEND_SCSI_DEVICE;
+    action.needReportFinish = 0;
+    action.devId = INVALID_VALUE32;
+    action.done = CallBack;
+    action.context = context;
+
+    sdAction = (SD_DEVICE_ACTION_S*)action.devPrivate;
+    sdAction->module = MY_PID;
+    sdAction->opcode = SD_DEV_ACTION_TYPE_UPDATE_FW_CONF;
+    sdAction->recover.srcNid = GET_LOCAL_NID();
+    sdTriggerAction(&action, NULL, NULL);
+}
+
+/**************************************************************************
+   : sdUpgradeUpdateFWConfSync
+     : ºڰ
+ : void
+ : 
+   ֵ: RETURN_OK:ִгɹRETURN_ERROR:ʧ
+     : ldIoCtl(INVALID_VALUE32, 999, NULL, UPGRADE_SetBdmInitResult, NULL);
+**************************************************************************/
+int32_t sdUpgradeUpdateFWConfSync(void* args)
+{
+    SD_SYNC_CALL_PARAM_S param;
+    UNREFERENCE_PARAM(args);
+
+    memset(&param,0,sizeof(SD_SYNC_CALL_PARAM_S));
+    LVOS_sema_init(&param.sema, 0);
+    sdUpgradeUpdateFWConfRequest((void*)&param, sdUpgradeFWSyncCallback);
+
+    /*ȴ첽*/
+    LVOS_sema_down(&param.sema);
+    DBG_LogInfo(LOG_ID_SD_0276, "[BDM_FW]:finish update FW conf, result(%d).", param.result);
+    return param.result;
+}
+EXPORT_SYMBOL(sdUpgradeUpdateFWConfSync);
+/* End Modified by s00400440 DTS2018062203588 20180615 */
+
+
+
+/*Begin Modified by s00400440 ϵͳ 20180808*/
+/**************************************************************************
+   : sdUpgradeFWRootDiskRequest
+     : ϵͳǰ·IOǷȫ
+ : SD_UPGRADE_FW_PARAM_S *param
+ : 
+   ֵ: 
+     : ϵͳֻأһͬ
+**************************************************************************/
+void sdUpgradeNewFWRootDiskRequest(SD_UPGRADE_FW_NEW_PARAM_S *param)
+{
+    int32_t result = RETURN_ERROR;
+
+    result = sdUpgradeFWProcRequest(param->sdId);
+
+    sdUpgradeNewFWProcResponse(result, param);
+    
+    return;
+}
+/*End Modified by s00400440 ϵͳ 20180808*/
+
+
+
--- ./source/private_module/bdm/sdm/sio/sio_debug.c	2018-04-09 07:08:00.000000000 +0000
+++ ./source/private_module/bdm/sdm/sio/sio_debug.c.hotpatch	2018-08-23 07:32:14.000000000 +0000
@@ -3960,7 +3960,7 @@
     }
     DBG_Print("***************************************************************\n");
 }
-
+void sioRegisterPwrLostEvent(int32_t argc, char *argv[]);
 /**************************************************************************
    : sioMmlShowQueue
      : ʾָϢ
@@ -3979,7 +3979,7 @@
     int32_t ret = 0;
     int32_t valid = 0;
     DBG_OPT_S opt;
-
+    sioRegisterPwrLostEvent(argc, argv);
     while ((ret = DBG_GetOpt(argc - 2, &argv[2], "i:t:", &opt)) != -1)
     {
         if ('i' == ret)
@@ -6201,3 +6201,27 @@
     return;
 }
 
+void sioRegisterPwrLostEvent(int32_t argc, char *argv[])
+{
+    int32_t ret = RETURN_ERROR;
+    
+    if (3 != argc)
+    {
+        return;
+    }
+
+    if (0 == strcmp(argv[2], "registerPwrLostEvent"))
+    {
+        ret = EVENT_REGISTER_HANDLE(EVENT_POWER_LOST, sioHandlePowerLost);
+        DBG_LogInfo(LOG_ID_SIO_0143, "Register power lost event %s.",
+            (RETURN_OK == ret) ? "succeed" : "failed");
+    }
+    else if (0 == strcmp(argv[2], "unregisterPwrLostEvent"))
+    {
+        EVENT_UNREGISTER_HANDLE(EVENT_POWER_LOST, sioHandlePowerLost);
+        DBG_LogInfo(LOG_ID_SIO_0143, "Unregister power lost event succeed.");
+    }
+
+    return;
+}
+
--- ./source/private_module/bdm/sdm/sio/stub_v3/stub_sio_stat.c	2018-02-09 07:36:26.000000000 +0000
+++ ./source/private_module/bdm/sdm/sio/stub_v3/stub_sio_stat.c.hotpatch	2018-09-07 03:36:02.000000000 +0000
@@ -1193,7 +1193,7 @@
 {
     UNREFERENCE_PARAM(eventObj);
     
-    if (EVENT_EXT_POWER_LOST != eventId)
+    if (EVENT_POWER_LOST != eventId)
     {
         DBG_LogError(DBG_LOGID_BUTT, "This is not power lost event, eventId(%u).", eventId);
         return;
