/* Copyright (c) Huawei Technologies Co., Ltd. 2025-2025. All rights reserved.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

// don't change the include order
#include "adapter.h"
#include "sml_errcodes.h"
#include "sml.h"
#include "ctrl.h"

#ifdef ITEST_ENABLED
#include "ibmc_itest_sml.h"
#endif

/*
 * Description: 获取RAID控制器的初始化状态
 *              修改历史
 * History: 1.2020年1月3日,
 *          新生成函数
 */
guint8 smlib_get_ctrl_init_state(guint8 ctrl_index)
{
    guint8 init_state = INIT_UNKNOWN_STATE;
    SML_CTRL_S* sml_ctrl = NULL;

    if (ctrl_index >= SML_MAX_RAID_CONTROLLER) {
        return init_state;
    }
    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return init_state;
    }

    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    init_state = sml_ctrl->init_state;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);
    return init_state;
}

/*
 * Description: 用于读取RAID控制器的信息，并更新全局缓存数据
 * History: 1.2016年3月7日
 *          新生成函数
 */
gint32 smlib_get_ctrl_info(guint8 ctrl_index, SML_CTRL_BASIC_INFO_S *ctrl)
{
    gint32 retval = SML_SUCCESS;
    guint32 current_timestamp = 0;
    guint32 last_udate_timestamp = 0;
    guint8 updated = FALSE;
    SML_CTRL_BASIC_INFO_S new_ctrl_info = { 0 };
    gint32 data_validity = 0;
    gint32 locked = FALSE;

    guint8 try_count = 0;
    guint8 warnning_cfm_cnt = 0;
    guint8 no_warnning_info = 0;
    guint8 debounce_failed = FALSE;

    guint16 bak_memory_uce_count = 0;
    guint16 bak_memory_ecc_count = 0;
    SML_CTRL_S* sml_ctrl = NULL;

    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, ctrl))) {
        return retval;
    }

#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (gulong)time(0);
#endif

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    last_udate_timestamp = sml_ctrl->controller.ctrl.last_update_timestamp;
    new_ctrl_info.ctrl_warnig_info_reported = sml_ctrl->controller.ctrl.ctrl_warnig_info_reported;

    // 准备防抖失败以备恢复的数据
    bak_memory_uce_count = sml_ctrl->controller.ctrl.memory_uce_count;
    bak_memory_ecc_count = sml_ctrl->controller.ctrl.memory_ecc_count;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);

    // 上次更新数据的时间是0或者距离上次更新数据已经超过数据更新时间间隔，并且当前控制器没有在执行任何操作，否则直接取缓存数据
    data_validity =
        check_cache_data_is_expired(0, current_timestamp, last_udate_timestamp, 6 * SMLIB_UPDATE_CACHE_DATA_INTREVAL);
    // 超时刷新，试探获取操作锁；如果是无效数据或者强制刷新，必须等待获取操作锁
    if (CACHE_DATA_INVALID_TIMEOUT == data_validity) {
        if (g_mutex_trylock(&sml_ctrl->op_mutex)) {
            locked = TRUE;
        } else {
            debug_log(DLOG_DEBUG, "smlib_get_ctrl_info: op_mutex locked, skip operation\n");
        }
    } else if ((CACHE_DATA_INVALID_NO_DATA == data_validity) || (CACHE_DATA_INVALID_FORCED == data_validity)) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        locked = TRUE;
    }

    if (locked) {
        if (NULL != sml_ctrl->pfn_get_ctrl_info) {
            do {
                try_count++;

                // 调用适配层接口获取数据，成功则将数据更新至全局缓存数据区
                retval = sml_ctrl->pfn_get_ctrl_info(sml_ctrl->controller_id, &new_ctrl_info);
                if (SML_SUCCESS == retval) {
                    // 控制器uce,ecc计数值
                    if ((new_ctrl_info.memory_uce_count != 0) || ((new_ctrl_info.memory_ecc_count != 0) &&
                        (new_ctrl_info.memory_ecc_count >= new_ctrl_info.memory_ecc_bucket_size))) {
                        if (new_ctrl_info.ctrl_warnig_info_reported) { // 已经上报的信息，直接标记信息确认次数为最大
                            warnning_cfm_cnt = MAX_WARNNING_INFO_DEBOUNCE_COUNT;
                        } else {
                            warnning_cfm_cnt++;
                        }
                    } else {
                        no_warnning_info = TRUE; // 只要出现过1次不包含告警信息的标记，防抖就不可能成功
                        if (new_ctrl_info.ctrl_warnig_info_reported) {
                            new_ctrl_info.ctrl_warnig_info_reported = 0;
                            warnning_cfm_cnt = 0;
                        }
                    }

                    // 判断是否需要从RAID卡读下一次数据，不需要则直接退出防抖
                    // 全部数据都出现过无告警的信息或者告警信息已经确认上报过，退出防抖读取
                    if ((no_warnning_info == TRUE) || (warnning_cfm_cnt == MAX_WARNNING_INFO_DEBOUNCE_COUNT)) {
                        break;
                    }
                } else {
                    debug_log(DLOG_DEBUG,
                        "smlib: Get RAID controller [Ctrl index %d, Ctrl ID %d] info failed, return 0x%04x\n",
                        ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
                    break;
                }

                // 如果还需要读控制器，需要延时
                if (try_count < MAX_WARNNING_INFO_DEBOUNCE_COUNT) {
                    // delay前先解锁，避免阻塞其他进程对控制器的读写操作
                    g_mutex_unlock(&sml_ctrl->op_mutex);
                    unlock_ctrl_list_mutex(ctrl_index);
                    vos_task_delay(RAID_INFO_DEBOUNCE_DELAY);
                    lock_ctrl_list_mutex(ctrl_index);
                    if (sml_ctrl == NULL) {
                        unlock_ctrl_list_mutex(ctrl_index);
                        return SML_ERR_CTRL_NOT_REGISTERED;
                    }
                    g_mutex_lock(&sml_ctrl->op_mutex);
                }
            } while (try_count < MAX_WARNNING_INFO_DEBOUNCE_COUNT);
        } else {
            retval = SML_ERR_NULL_INFTERFACE;
        }

        g_mutex_unlock(&sml_ctrl->op_mutex);
    }

    // 设置防抖上报结果, 检查防抖结果中是否有启动了防抖但是防抖失败的情况
    if (try_count != 0) {
        new_ctrl_info.ctrl_warnig_info_reported = (warnning_cfm_cnt == MAX_WARNNING_INFO_DEBOUNCE_COUNT) ? 1 : 0;

        if ((warnning_cfm_cnt != MAX_WARNNING_INFO_DEBOUNCE_COUNT) && (warnning_cfm_cnt != 0)) {
            debounce_failed = TRUE;
        }
    }

    // 从RAID卡读取数据成功的就可以更新数据
    /* BEGIN: Modified for PN:CSEC on 2018/12/7 */
    updated = ((0 != try_count) && (SML_SUCCESS == retval)) ? TRUE : FALSE;
    /* END:   Modified for PN:CSEC on 2018/12/7 */
    // 实际从RAID卡更新数据会耗费几百毫秒到几秒的时间，这里再次获取当前系统时间记录更准确
#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif
    /* END:   Modified on 2017/4/19 */

    // 集中更新缓存数据，拷贝需要返回的数据
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    // 从RAID卡实际执行结果更新数据到全局缓存
    if (updated) {
        if (TRUE == debounce_failed) {
            new_ctrl_info.memory_uce_count = bak_memory_uce_count;
            new_ctrl_info.memory_ecc_count = bak_memory_ecc_count;
        }

        memcpy_s(&sml_ctrl->controller.ctrl, sizeof(SML_CTRL_BASIC_INFO_S), &new_ctrl_info,
            sizeof(SML_CTRL_BASIC_INFO_S));

        ASSERT_BIT_IF_TRUE(sml_ctrl->controller.ctrl.memory_ce_count,
            sml_ctrl->controller.health.health_status, 0);
        ASSERT_BIT_IF_TRUE(sml_ctrl->controller.ctrl.memory_uce_count,
            sml_ctrl->controller.health.health_status, 1);
        ASSERT_BIT_IF_TRUE(sml_ctrl->controller.ctrl.memory_ecc_count >=
            sml_ctrl->controller.ctrl.memory_ecc_bucket_size &&
            sml_ctrl->controller.ctrl.memory_ecc_count != 0,
            sml_ctrl->controller.health.health_status, 2);
        sml_ctrl->controller.ctrl.last_update_timestamp = current_timestamp;
    }

    if (SML_SUCCESS != retval) {
        sml_ctrl->controller.ctrl.ctrl_warnig_info_reported = 0;
    }
    memcpy_s(ctrl, sizeof(SML_CTRL_BASIC_INFO_S), &sml_ctrl->controller.ctrl,
        sizeof(SML_CTRL_BASIC_INFO_S));

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    if (SML_ERR_I2C_READ_WRITE_FAILED == retval) {
        smlib_invalid_ctrl_cached_info(ctrl_index, SMLIB_CTRL_INFO_MASK);
    }

    return retval;
}

/*
 * Description: 用于读取RAID控制器的SAS地址，并更新全局缓存数据
 * History: 1.2016年3月7日
 *          新生成函数
 */
gint32 smlib_get_ctrl_sas_addr(guint8 ctrl_index, SML_SAS_ADDR_S *ctrl)
{
    gint32 retval = SML_SUCCESS;
    guint32 current_timestamp = 0;
    guint32 last_udate_timestamp = 0;
    guint8 updated = FALSE;
    SML_SAS_ADDR_S new_sas_addr = { 0 };
    gint32 data_validity = 0;
    gint32 locked = FALSE;
    SML_CTRL_S* sml_ctrl = NULL;

    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, ctrl))) {
        return retval;
    }

#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    last_udate_timestamp = sml_ctrl->controller.sas_addr.last_update_timestamp;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);

    // 上次更新数据的时间是0或者距离上次更新数据已经超过数据更新时间间隔，并且当前控制器没有在执行任何操作，否则直接取缓存数据
    data_validity =
        check_cache_data_is_expired(0, current_timestamp, last_udate_timestamp, 60 * SMLIB_UPDATE_CACHE_DATA_INTREVAL);
    // 超时刷新，试探获取操作锁；如果是无效数据或者强制刷新，必须等待获取操作锁
    if (CACHE_DATA_INVALID_TIMEOUT == data_validity) {
        if (g_mutex_trylock(&sml_ctrl->op_mutex)) {
            locked = TRUE;
        } else {
            debug_log(DLOG_DEBUG, "smlib_get_ctrl_sas_addr: op_mutex locked, skip operation\n");
        }
    } else if ((CACHE_DATA_INVALID_NO_DATA == data_validity) || (CACHE_DATA_INVALID_FORCED == data_validity)) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        locked = TRUE;
    }

    if (locked) {
        if (NULL != sml_ctrl->pfn_get_ctrl_sas_addr) {
            // 调用适配层接口获取数据，成功则将数据更新至全局缓存数据区
            retval = sml_ctrl->pfn_get_ctrl_sas_addr(sml_ctrl->controller_id, &new_sas_addr);
            if (SML_SUCCESS == retval) {
                updated = TRUE;
            } else {
                /* BEGIN: Modified for PN:CSEC on 2018/12/7 */
                debug_log(DLOG_DEBUG,
                    "smlib: Get RAID controller [Ctrl index %d, Ctrl ID %d] SAS addr failed, return 0x%04x\n",
                    ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
            }
        } else {
            retval = SML_ERR_NULL_INFTERFACE;
        }

        g_mutex_unlock(&sml_ctrl->op_mutex);
    }

    // 实际从RAID卡更新数据会耗费几百毫秒到几秒的时间，这里再次获取当前系统时间记录更准确
#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    // 集中更新缓存数据，拷贝需要返回的数据
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    // 从RAID卡实际执行结果更新数据到全局缓存
    if (updated) {
        memcpy_s(&sml_ctrl->controller.sas_addr, sizeof(SML_SAS_ADDR_S), &new_sas_addr,
            sizeof(SML_SAS_ADDR_S));
        sml_ctrl->controller.sas_addr.last_update_timestamp = current_timestamp;
    }
    /* END:   Modified for PN:CSEC on 2018/12/7 */

    memcpy_s(ctrl, sizeof(SML_SAS_ADDR_S), &sml_ctrl->controller.sas_addr, sizeof(SML_SAS_ADDR_S));

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    if (SML_ERR_I2C_READ_WRITE_FAILED == retval) {
        smlib_invalid_ctrl_cached_info(ctrl_index, SMLIB_CTRL_INFO_MASK);
    }

    return retval;
}

static void check_bbu_warnning_infos(SML_BBU_STATUS_S *new_bbu, guint8 *warnning_cfm_cnt, guint8 *no_warnning_info)
{
    if ((new_bbu->failed != 0) || (new_bbu->no_space != 0) || (new_bbu->remaining_capacity_low != 0) ||
        (new_bbu->predictive_failure != 0) || (new_bbu->learn_cycle_timeout != 0) ||
        (new_bbu->learn_cycle_failed != 0) || (new_bbu->replacepack != 0) ||
        (new_bbu->temperature_high != 0) || (new_bbu->voltage_low != 0) || (new_bbu->pack_missing != 0)) {
        if (new_bbu->bbu_warnig_info_reported) { // 已经上报的信息，直接标记信息确认次数为最大
            *warnning_cfm_cnt = MAX_WARNNING_INFO_DEBOUNCE_COUNT;
        } else {
            (*warnning_cfm_cnt)++;
        }
    } else {
        *no_warnning_info = TRUE; // 只要出现过1次不包含告警信息的标记，防抖就不可能成功
        if (new_bbu->bbu_warnig_info_reported) {
            new_bbu->bbu_warnig_info_reported = 0;
            *warnning_cfm_cnt = 0;
        }
    }
}

/*
 * Description: 用于读取RAID控制器的BBU状态，并更新全局缓存数据
 * History: 1.2016年3月7日
 *          新生成函数
 */
gint32 smlib_get_ctrl_bbu_status(guint8 ctrl_index, SML_BBU_STATUS_S *ctrl)
{
    gint32 retval = SML_SUCCESS;
    guint32 current_timestamp = 0;
    guint8 updated = FALSE;
    SML_BBU_STATUS_S new_bbu = { 0 };
    gint32 data_validity = 0;
    gint32 locked = FALSE;

    guint8 try_count = 0;
    guint8 warnning_cfm_cnt = 0;
    guint8 no_warnning_info = 0;
    guint8 debounce_failed = FALSE;

    SML_CTRL_S* sml_ctrl = NULL;

    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, ctrl))) {
        return retval;
    }

#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    guint32 last_udate_timestamp = sml_ctrl->controller.bbu.last_update_timestamp;
    new_bbu.bbu_warnig_info_reported = sml_ctrl->controller.bbu.bbu_warnig_info_reported;

    // 保存原始值以备防抖失败时恢复
    guint8 bak_no_space = sml_ctrl->controller.bbu.no_space;
    guint8 bak_remaining_capacity_low = sml_ctrl->controller.bbu.remaining_capacity_low;
    guint8 bak_predictive_failure = sml_ctrl->controller.bbu.predictive_failure;
    guint8 bak_learn_cycle_timeout = sml_ctrl->controller.bbu.learn_cycle_timeout;
    guint8 bak_learn_cycle_failed = sml_ctrl->controller.bbu.learn_cycle_failed;
    guint8 bak_replacepack = sml_ctrl->controller.bbu.replacepack;
    guint8 bak_temperature_high = sml_ctrl->controller.bbu.temperature_high;
    guint8 bak_voltage_low = sml_ctrl->controller.bbu.voltage_low;
    guint8 bak_pack_missing = sml_ctrl->controller.bbu.pack_missing;
    guint8 bak_failed = sml_ctrl->controller.bbu.failed;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);

    // 上次更新数据的时间是0或者距离上次更新数据已经超过数据更新时间间隔，并且当前控制器没有在执行任何操作，否则直接取缓存数据
    data_validity =
        check_cache_data_is_expired(0, current_timestamp, last_udate_timestamp, 6 * SMLIB_UPDATE_CACHE_DATA_INTREVAL);
    // 超时刷新，试探获取操作锁；如果是无效数据或者强制刷新，必须等待获取操作锁
    if (CACHE_DATA_INVALID_TIMEOUT == data_validity) {
        if (g_mutex_trylock(&sml_ctrl->op_mutex)) {
            locked = TRUE;
        } else {
            debug_log(DLOG_DEBUG, "smlib_get_ctrl_bbu_status: op_mutex locked, skip operation\n");
        }
    } else if ((CACHE_DATA_INVALID_NO_DATA == data_validity) || (CACHE_DATA_INVALID_FORCED == data_validity)) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        locked = TRUE;
    }

    if (locked) {
        if (NULL != sml_ctrl->pfn_get_ctrl_bbu_status) {
            do {
                try_count++;

                // 调用适配层接口获取数据，成功则将数据更新至全局缓存数据区
                retval = sml_ctrl->pfn_get_ctrl_bbu_status(sml_ctrl->controller_id, &new_bbu);
                if (SML_SUCCESS == retval) {
                    // 控制器bbu状态信息
                    check_bbu_warnning_infos(&new_bbu, &warnning_cfm_cnt,  &no_warnning_info);

                    // 判断是否需要从RAID卡读下一次数据，不需要则直接退出防抖
                    // 全部数据都出现过无告警的信息或者告警信息已经确认上报过，退出防抖读取
                    if ((no_warnning_info == TRUE) || (warnning_cfm_cnt == MAX_WARNNING_INFO_DEBOUNCE_COUNT)) {
                        break;
                    }
                } else {
                    debug_log(DLOG_DEBUG,
                        "smlib: Get RAID controller [Ctrl index %d, Ctrl ID %d] BBU status failed, return 0x%04x\n",
                        ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
                    break;
                }

                // 如果还需要读控制器，需要延时
                /* BEGIN: Modified for PN:CSEC on 2018/12/7 */
                if (MAX_WARNNING_INFO_DEBOUNCE_COUNT > try_count) {
                    // delay前先解锁，避免阻塞其他进程对控制器的读写操作
                    g_mutex_unlock(&sml_ctrl->op_mutex);
                    unlock_ctrl_list_mutex(ctrl_index);
                    vos_task_delay(RAID_INFO_DEBOUNCE_DELAY);
                    lock_ctrl_list_mutex(ctrl_index);
                    if (sml_ctrl == NULL) {
                        unlock_ctrl_list_mutex(ctrl_index);
                        return SML_ERR_CTRL_NOT_REGISTERED;
                    }
                    g_mutex_lock(&sml_ctrl->op_mutex);
                }
            } while (MAX_WARNNING_INFO_DEBOUNCE_COUNT > try_count);
            /* END:   Modified for PN:CSEC on 2018/12/7 */
        } else {
            retval = SML_ERR_NULL_INFTERFACE;
        }

        g_mutex_unlock(&sml_ctrl->op_mutex);
    }

    // 设置防抖上报结果, 检查防抖结果中是否有启动了防抖但是防抖失败的情况
    if (try_count != 0) {
        new_bbu.bbu_warnig_info_reported = (warnning_cfm_cnt == MAX_WARNNING_INFO_DEBOUNCE_COUNT) ? 1 : 0;

        if ((warnning_cfm_cnt != MAX_WARNNING_INFO_DEBOUNCE_COUNT) && (warnning_cfm_cnt != 0)) {
            debounce_failed = TRUE;
        }
    }

    // 从RAID卡读取数据成功的就可以更新数据
    /* BEGIN: Modified for PN:CSEC on 2018/12/7 */
    updated = ((SML_SUCCESS == retval) && (try_count != 0)) ? TRUE : FALSE;
    /* END:   Modified for PN:CSEC on 2018/12/7 */
    // 实际从RAID卡更新数据会耗费几百毫秒到几秒的时间，这里再次获取当前系统时间记录更准确
#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif
    /* END:   Modified on 2017/4/19 */

    // 集中更新缓存数据，拷贝需要返回的数据
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    // 从RAID卡实际执行结果更新数据到全局缓存
    if (updated) {
        // BBU在位状态在smlib_get_ctrl_health中更新，这里要防止拷贝SML_BBU_STATUS_S结构体内容时把BBU在位状态覆盖掉
        guint8 bbu_present = sml_ctrl->controller.bbu.present;
        memcpy_s(&sml_ctrl->controller.bbu, sizeof(SML_BBU_STATUS_S), &new_bbu, sizeof(SML_BBU_STATUS_S));
        sml_ctrl->controller.bbu.present = bbu_present;
        sml_ctrl->controller.bbu.last_update_timestamp = current_timestamp;

        if (TRUE == debounce_failed) {
            sml_ctrl->controller.bbu.no_space = bak_no_space;
            sml_ctrl->controller.bbu.remaining_capacity_low = bak_remaining_capacity_low;
            sml_ctrl->controller.bbu.predictive_failure = bak_predictive_failure;
            sml_ctrl->controller.bbu.learn_cycle_timeout = bak_learn_cycle_timeout;
            sml_ctrl->controller.bbu.learn_cycle_failed = bak_learn_cycle_failed;
            sml_ctrl->controller.bbu.replacepack = bak_replacepack;
            sml_ctrl->controller.bbu.temperature_high = bak_temperature_high;
            sml_ctrl->controller.bbu.voltage_low = bak_voltage_low;
            sml_ctrl->controller.bbu.pack_missing = bak_pack_missing;
            sml_ctrl->controller.bbu.failed = bak_failed;
        }
    }

    if (SML_SUCCESS != retval) {
        sml_ctrl->controller.bbu.bbu_warnig_info_reported = 0;
    }
    memcpy_s(ctrl, sizeof(SML_BBU_STATUS_S), &sml_ctrl->controller.bbu, sizeof(SML_BBU_STATUS_S));

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    if (SML_ERR_I2C_READ_WRITE_FAILED == retval) {
        smlib_invalid_ctrl_cached_info(ctrl_index, SMLIB_CTRL_INFO_MASK);
    }
    return retval;
}

static void get_ctrl_assert_bit(SML_CTRL_HEALTH_DATA_S *new_health, SML_CTRL_S *sml_ctrl)
{
    ASSERT_BIT_IF_TRUE(new_health->ctrl_nvram_err_count, sml_ctrl->controller.health.health_status, 3);
    // health_status的第6个bit对应hw_err
    ASSERT_BIT_IF_TRUE(new_health->ctrl_hw_err, sml_ctrl->controller.health.health_status, 6);
    // health_status的第7个bit对应clk_err
    ASSERT_BIT_IF_TRUE(new_health->ctrl_clk_err, sml_ctrl->controller.health.health_status, 7);
    // health_status的第8个bit对应power_err,power_err的bit0不用判断
    ASSERT_BIT_IF_TRUE((new_health->ctrl_power_err & 0xFE), sml_ctrl->controller.health.health_status, 8);
    // health_status的第9个bit对应capacity_err,capacity_err的bit0 bit1 bit2 bit4不用判断
    ASSERT_BIT_IF_TRUE((new_health->ctrl_capacity_err & 0xE8), sml_ctrl->controller.health.health_status, 9);
    // health_status的第10个bit对应flash_err
    ASSERT_BIT_IF_TRUE(new_health->ctrl_flash_err, sml_ctrl->controller.health.health_status, 10);
    // 若当前查询的五个故障状态和上次的五个故障状态不同，即故障状态发生变化，需要打印log
    // 所以在err_change中的1-5bit对应记录是哪个状态发生了变化，以便于打印对应的log信息
    ASSERT_BIT_IF_TRUE(sml_ctrl->controller.health.hw_err != new_health->ctrl_hw_err,
        sml_ctrl->controller.health.err_change, 1); // err_change bit1对应hw_err
    ASSERT_BIT_IF_TRUE(sml_ctrl->controller.health.clk_err != new_health->ctrl_clk_err,
        sml_ctrl->controller.health.err_change, 2); // err_change bit2对应clk_err
    ASSERT_BIT_IF_TRUE(sml_ctrl->controller.health.power_err != new_health->ctrl_power_err,
        sml_ctrl->controller.health.err_change, 3); // err_change bit3对应power_err
    ASSERT_BIT_IF_TRUE(sml_ctrl->controller.health.capacity_err != new_health->ctrl_capacity_err,
        sml_ctrl->controller.health.err_change, 4); // err_change bit4对应capacity_err
    ASSERT_BIT_IF_TRUE(sml_ctrl->controller.health.flash_err != new_health->ctrl_flash_err,
        sml_ctrl->controller.health.err_change, 5); // err_change bit5对应flash_err
    // 将本次查询到的故障状态保存，方便在下一次查询时对比
    sml_ctrl->controller.health.hw_err = new_health->ctrl_hw_err;
    sml_ctrl->controller.health.clk_err = new_health->ctrl_clk_err;
    sml_ctrl->controller.health.power_err = new_health->ctrl_power_err;
    sml_ctrl->controller.health.capacity_err = new_health->ctrl_capacity_err;
    sml_ctrl->controller.health.flash_err = new_health->ctrl_flash_err;
    return;
}

/*
 * Description: 用于读取RAID控制器的健康状态，并更新全局缓存数据
 * History: 1.2016年3月7日
 *          新生成函数
 */
gint32 smlib_get_ctrl_health(guint8 ctrl_index, SML_CTRL_HEALTH_S *ctrl)
{
    gint32 retval = SML_SUCCESS;
    guint32 current_timestamp = 0;
    guint8 updated = FALSE;
    SML_CTRL_HEALTH_DATA_S new_health = { 0 };
    gint32 data_validity = 0;
    gint32 locked = FALSE;

    guint8 try_count = 0;
    guint8 warnning_cfm_cnt = 0;
    guint8 no_warnning_info = 0;
    guint8 debounce_failed = FALSE;

    guint16 bak_health_status = 0;
    SML_CTRL_S* sml_ctrl = NULL;

    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, ctrl))) {
        return retval;
    }

#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    guint32 last_udate_timestamp = sml_ctrl->controller.health.last_update_timestamp;
    new_health.ctrl_nvram_error_reported = sml_ctrl->controller.health.ctrl_nvram_error_reported;
    // 保留原始值以备防抖失败时恢复
    bak_health_status = sml_ctrl->controller.health.health_status;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);

    // 上次更新数据的时间是0或者距离上次更新数据已经超过数据更新时间间隔，并且当前控制器没有在执行任何操作，否则直接取缓存数据
    data_validity =
        check_cache_data_is_expired(0, current_timestamp, last_udate_timestamp, 2 * SMLIB_UPDATE_CACHE_DATA_INTREVAL);
    // 超时刷新，试探获取操作锁；如果是无效数据或者强制刷新，必须等待获取操作锁
    if (CACHE_DATA_INVALID_TIMEOUT == data_validity) {
        if (g_mutex_trylock(&sml_ctrl->op_mutex)) {
            locked = TRUE;
        } else {
            debug_log(DLOG_DEBUG, "smlib_get_ctrl_health: op_mutex locked, skip operation\n");
        }
    } else if ((CACHE_DATA_INVALID_NO_DATA == data_validity) || (CACHE_DATA_INVALID_FORCED == data_validity)) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        locked = TRUE;
    }

    if (locked) {
        if (NULL != sml_ctrl->pfn_get_ctrl_health) {
            do {
                try_count++;

                // 调用适配层接口获取数据，成功则将数据更新至全局缓存数据区
                retval = sml_ctrl->pfn_get_ctrl_health(sml_ctrl->controller_id, &new_health);
                if (SML_SUCCESS == retval) {
                    // 控制器nvram错误计数值
                    if (new_health.ctrl_nvram_err_count != 0) {
                        if (new_health.ctrl_nvram_error_reported) { // 已经上报的信息，直接标记信息确认次数为最大
                            warnning_cfm_cnt = MAX_WARNNING_INFO_DEBOUNCE_COUNT;
                        } else {
                            warnning_cfm_cnt++;
                        }
                    } else {
                        no_warnning_info = TRUE; // 只要出现过1次不包含告警信息的标记，防抖就不可能成功
                        if (new_health.ctrl_nvram_error_reported) {
                            new_health.ctrl_nvram_error_reported = 0;
                            warnning_cfm_cnt = 0;
                        }
                    }

                    // 判断是否需要从RAID卡读下一次数据，不需要则直接退出防抖
                    // 全部数据都出现过无告警的信息或者告警信息已经确认上报过，退出防抖读取
                    if ((no_warnning_info == TRUE) || (warnning_cfm_cnt == MAX_WARNNING_INFO_DEBOUNCE_COUNT)) {
                        break;
                    }
                } else {
                    debug_log(DLOG_DEBUG,
                        "smlib: Get RAID controller [Ctrl index %d, Ctrl ID %d] health failed, return 0x%04x\n",
                        ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
                    break;
                }

                // 如果还需要读控制器，需要延时
                if (try_count < MAX_WARNNING_INFO_DEBOUNCE_COUNT) {
                    // delay前先解锁，避免阻塞其他进程对控制器的读写操作
                    g_mutex_unlock(&sml_ctrl->op_mutex);
                    unlock_ctrl_list_mutex(ctrl_index);
                    vos_task_delay(RAID_INFO_DEBOUNCE_DELAY);
                    lock_ctrl_list_mutex(ctrl_index);
                    if (sml_ctrl == NULL) {
                        unlock_ctrl_list_mutex(ctrl_index);
                        return SML_ERR_CTRL_NOT_REGISTERED;
                    }
                    g_mutex_lock(&sml_ctrl->op_mutex);
                }
                /* BEGIN: Modified for PN:CSEC on 2018/12/7 */
            } while (MAX_WARNNING_INFO_DEBOUNCE_COUNT > try_count);
            /* END:   Modified for PN:CSEC on 2018/12/7 */
        } else {
            retval = SML_ERR_NULL_INFTERFACE;
        }

        g_mutex_unlock(&sml_ctrl->op_mutex);
    }

    // 设置防抖上报结果, 检查防抖结果中是否有启动了防抖但是防抖失败的情况
    if (try_count != 0) {
        new_health.ctrl_nvram_error_reported = (warnning_cfm_cnt == MAX_WARNNING_INFO_DEBOUNCE_COUNT) ? 1 : 0;

        if ((warnning_cfm_cnt != MAX_WARNNING_INFO_DEBOUNCE_COUNT) && (warnning_cfm_cnt != 0)) {
            debounce_failed = TRUE;
        }
    }

    // 从RAID卡读取数据成功的就可以更新数据
    updated = ((try_count != 0) && (SML_SUCCESS == retval)) ? TRUE : FALSE;

    // 实际从RAID卡更新数据会耗费几百毫秒到几秒的时间，这里再次获取当前系统时间记录更准确
#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif
    /* END:   Modified on 2017/4/19 */

    // 集中更新缓存数据，拷贝需要返回的数据
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    // 从RAID卡实际执行结果更新数据到全局缓存
    // 初始化标志位
    sml_ctrl->controller.health.err_change = 0;
    if (updated) {
        get_ctrl_assert_bit(&new_health, sml_ctrl);
        sml_ctrl->controller.bbu.present = new_health.bbu_present;

        if (TRUE == debounce_failed) {
            sml_ctrl->controller.health.health_status = bak_health_status;
        }

        sml_ctrl->controller.health.last_update_timestamp = current_timestamp;
    }

    sml_ctrl->controller.health.ctrl_nvram_error_reported = new_health.ctrl_nvram_error_reported;
    if (SML_SUCCESS != retval) {
        sml_ctrl->controller.health.ctrl_nvram_error_reported = 0;
    }
    memcpy_s(ctrl, sizeof(SML_CTRL_HEALTH_S), &sml_ctrl->controller.health, sizeof(SML_CTRL_HEALTH_S));

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    if (SML_ERR_I2C_READ_WRITE_FAILED == retval) {
        smlib_invalid_ctrl_cached_info(ctrl_index, SMLIB_CTRL_INFO_MASK);
    }
    return retval;
}

/*
 * Description: 用于读取RAID控制器的PHY错误统计，并更新全局缓存数据
 * History: 1.2016年3月7日
 *          新生成函数
 *          2.2017年12月25日, ()
 *          增加控制参数force_update
 */
gint32 smlib_get_ctrl_phy_err_count(guint8 ctrl_index, SML_SASPHY_INFO_S *ctrl, guint8 force_update)
{
    gint32 retval = SML_SUCCESS;
    guint32 current_timestamp = 0;
    guint32 last_udate_timestamp = 0;
    guint8 updated = FALSE;
    SML_SASPHY_INFO_S new_phy = { 0 };
    gint32 data_validity = 0;
    gint32 locked = FALSE;
    guint8 refresh_policy = 0;
    SML_CTRL_S* sml_ctrl = NULL;

    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, ctrl))) {
        return retval;
    }

#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    last_udate_timestamp = sml_ctrl->controller.phy.last_update_timestamp;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);

    // 强制从RAID控制器读取数据一次
    if (1 == force_update) {
        refresh_policy = (0x01 << 4) | RAID_REFRESH_CONTROLLER;
    }

    // 上次更新数据的时间是0或者距离上次更新数据已经超过数据更新时间间隔，并且当前控制器没有在执行任何操作，否则直接取缓存数据
    data_validity = check_cache_data_is_expired(refresh_policy, current_timestamp, last_udate_timestamp,
        6 * SMLIB_UPDATE_CACHE_DATA_INTREVAL);
    // 超时刷新，试探获取操作锁；如果是无效数据或者强制刷新，必须等待获取操作锁
    if (CACHE_DATA_INVALID_TIMEOUT == data_validity) {
        if (g_mutex_trylock(&sml_ctrl->op_mutex)) {
            locked = TRUE;
        } else {
            debug_log(DLOG_DEBUG, "smlib_get_ctrl_phy_err_count: op_mutex locked, skip operation\n");
        }
    } else if ((CACHE_DATA_INVALID_NO_DATA == data_validity) || (CACHE_DATA_INVALID_FORCED == data_validity)) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        locked = TRUE;
    }

    if (locked) {
        if (NULL != sml_ctrl->pfn_get_ctrl_phy_err_count) {
            // 调用适配层接口获取数据，成功则将数据更新至全局缓存数据区
            retval = sml_ctrl->pfn_get_ctrl_phy_err_count(sml_ctrl->controller_id, &new_phy);
            if (SML_SUCCESS == retval) {
                updated = TRUE;
            } else {
                debug_log(DLOG_DEBUG,
                    "smlib: Get RAID controller [Ctrl index %d, Ctrl ID %d] PHY error count failed, return 0x%04x\n",
                    ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
            }
        } else {
            retval = SML_ERR_NULL_INFTERFACE;
        }

        g_mutex_unlock(&sml_ctrl->op_mutex);
    }

    // 实际从RAID卡更新数据会耗费几百毫秒到几秒的时间，这里再次获取当前系统时间记录更准确
#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    // 集中更新缓存数据，拷贝需要返回的数据
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    // 从RAID卡实际执行结果更新数据到全局缓存
    if (updated) {
        memcpy_s(&sml_ctrl->controller.phy, sizeof(SML_SASPHY_INFO_S), &new_phy, sizeof(SML_SASPHY_INFO_S));
        sml_ctrl->controller.phy.last_update_timestamp = current_timestamp;

        /* 只在记录误码文件时（强制更新），才记录PHY误码历史数据 */
        if (1 == force_update) {
            (void)fd_record_ctrl_phy_err_info(&sml_ctrl->controller.phy_history, &new_phy, vos_tick_get());
        }
    }
    memcpy_s(ctrl, sizeof(SML_SASPHY_INFO_S), &sml_ctrl->controller.phy, sizeof(SML_SASPHY_INFO_S));

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    if (SML_ERR_I2C_READ_WRITE_FAILED == retval) {
        smlib_invalid_ctrl_cached_info(ctrl_index, SMLIB_CTRL_INFO_MASK);
    }

    return retval;
}

static gint32 get_ctrl_exp_phy_err_count(SML_CTRL_S* sml_ctrl, SML_CTRL_EXP_SASPHY_INFO_S *expander,
    SML_CTRL_EXP_LIST_INFO_S *exp_list)
{
    gint32 retval = SML_SUCCESS;
    SML_SASPHY_ERR_INFO_S phy_err;

    expander->expander_count = exp_list->count;

    /* 遍历Expander背板 */
    for (gint32 i = 0; i < exp_list->count; i++) {
        expander->expander_phy[i].phy_count = exp_list->phy_count_list[i];
        /* 遍历phy，获取phy err count */
        for (guint16 j = 0; j < expander->expander_phy[i].phy_count; j++) {
            (void)memset_s(&phy_err, sizeof(phy_err), 0, sizeof(phy_err));
            phy_err.phy_id = j;
            phy_err.exp_sas_addr = exp_list->sas_addr_list[i];

            g_mutex_lock(&sml_ctrl->op_mutex);
            if (sml_ctrl->pfn_get_exp_phy_err_count != NULL) {
                (void)sml_ctrl->pfn_get_exp_phy_err_count(sml_ctrl->controller_id, &phy_err);
                memcpy_s(&(expander->expander_phy[i].phy_err[j]), sizeof(SML_SASPHY_ERR_COUNT_S),
                    &(phy_err.phy_err_count), sizeof(SML_SASPHY_ERR_COUNT_S));
            } else {
                retval = SML_ERR_NULL_INFTERFACE;
            }
            g_mutex_unlock(&sml_ctrl->op_mutex);
            vos_task_delay(100); // 100 防止同一时间命令过多
        }
    }

    return retval;
}

/*
 * Description: 用于读取RAID控制器下的Expander的PHY错误统计，并更新全局缓存数据
 * History: 1.2018年10月31日,
 *          新生成函数
 */
gint32 smlib_get_ctrl_exp_phy_err_count(guint8 ctrl_index, SML_CTRL_EXP_SASPHY_INFO_S *expander)
{
    gint32 retval = SML_SUCCESS;
    SML_CTRL_S* sml_ctrl = NULL;
    SML_CTRL_EXP_LIST_INFO_S exp_list;
    if ((retval = check_input_parameters(ctrl_index, expander)) != SML_SUCCESS) {
        return retval;
    }

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    if (sml_ctrl->pfn_get_ctrl_exp_list != NULL) {
        (void)memset_s(&exp_list, sizeof(exp_list), 0, sizeof(exp_list));
        g_mutex_lock(&sml_ctrl->op_mutex);
        retval = sml_ctrl->pfn_get_ctrl_exp_list(sml_ctrl->controller_id, &exp_list);
        g_mutex_unlock(&sml_ctrl->op_mutex);
        if (retval == SML_SUCCESS) {
            retval = get_ctrl_exp_phy_err_count(sml_ctrl, expander, &exp_list);
        }
    } else if (sml_ctrl->pfn_get_ctrl_exp_phy_err_count != NULL) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        retval = sml_ctrl->pfn_get_ctrl_exp_phy_err_count(sml_ctrl->controller_id, expander);
        g_mutex_unlock(&sml_ctrl->op_mutex);
    } else {
        retval = SML_ERR_NULL_INFTERFACE;
    }

    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    /* 更新RAID卡下expander的计数 */
    if (retval == SML_SUCCESS) {
        sml_ctrl->controller.expander.expander_count = expander->expander_count;
        (void)fd_record_exp_phy_err_info(&sml_ctrl->controller.phy_history, expander, vos_tick_get());
    } else if (retval == SML_ERR_EXP_NO_EXPANDER) {
        sml_ctrl->controller.expander.expander_count = 0;
    }
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    return retval;
}

/*
 * Description: 依据逻辑盘的id列表顺序，调整对应的逻辑盘信息排列顺序而不必从控制器获取信息，
 *              就能使两者之间保持正确的对应关系
 * History: 1.2016年12月27日, ()
 *          新生成函数
 */
static gint32 resort_ld_infos(SML_LD_LIST_S *new_ld_list, SML_LD_LIST_S *old_ld_list, SML_LD_INFO_S *ld_info)
{
    SML_LD_INFO_S *temp_info = NULL;
    guint16 i = 0;
    guint8 ld_idx = 0;

    if ((new_ld_list == NULL) || (old_ld_list == NULL) || (ld_info == NULL)) {
        return SML_ERR_NULL_DATA;
    }

    if (SML_MAX_LOGIC_DRIVES < MAX(new_ld_list->ld_count, old_ld_list->ld_count)) {
        return SML_ERR_EXCEED_LIMIT;
    }

    temp_info = (SML_LD_INFO_S *)g_malloc(old_ld_list->ld_count * sizeof(SML_LD_INFO_S));
    if (NULL == temp_info) {
        return SML_ERR_CANNOT_ALLOC_MEM;
    }

    // 将原来的逻辑盘信息备份
    errno_t securec_rv = memcpy_s(temp_info, old_ld_list->ld_count * sizeof(SML_LD_INFO_S), ld_info,
        old_ld_list->ld_count * sizeof(SML_LD_INFO_S));
    if (securec_rv != EOK) {
        debug_log(DLOG_ERROR, "%s: memcpy_s failed, ret = %d", __FUNCTION__, securec_rv);
    }

    for (i = 0; i < new_ld_list->ld_count; i++) {
        // 查找新id在原来的id列表中的位置，找到后将逻辑盘信息拷贝到新id对应的位置(数组下标一致)
        if ((RET_OK == check_ld_target_id(new_ld_list->target_ids[i], old_ld_list, &ld_idx)) &&
            (ld_idx < old_ld_list->ld_count)) {
            memcpy_s(&ld_info[i], sizeof(SML_LD_INFO_S), &temp_info[ld_idx], sizeof(SML_LD_INFO_S));
        } else { // 没有找到逻辑盘信息的设置为无效值
            (void)memset_s(&ld_info[i], sizeof(SML_LD_INFO_S), 0xff, sizeof(SML_LD_INFO_S));
            ld_info[i].ldinfo.last_update_timestamp = 0;
            ld_info[i].pd_in_ld.last_update_timestamp = 0;
            ld_info[i].pd_in_ld.pd_count = 0;
        }
    }

    g_free(temp_info);

    return SML_SUCCESS;
}

/*
 * Description: 依据物理盘的id列表顺序，调整对应的物理盘信息排列顺序而不必从控制器获取信息，
 *              就能使两者之间保持正确的对应关系
 * History: 1.2017年1月3日, ()
 *          新生成函数
 */
static gint32 resort_pd_infos(SML_PD_LIST_S *new_pd_list, SML_PD_LIST_S *old_pd_list, SML_PD_INFO_S *pd_info)
{
    SML_PD_INFO_S *temp_info = NULL;
    guint16 i = 0;
    guint16 pd_idx = 0;

    if ((new_pd_list == NULL) || (old_pd_list == NULL) || (pd_info == NULL)) {
        return SML_ERR_NULL_DATA;
    }

    if (SML_MAX_PHYSICAL_DRIVES < MAX(new_pd_list->pd_count, old_pd_list->pd_count)) {
        return SML_ERR_EXCEED_LIMIT;
    }

    temp_info = (SML_PD_INFO_S *)g_malloc(old_pd_list->pd_count * sizeof(SML_PD_INFO_S));
    if (NULL == temp_info) {
        return SML_ERR_CANNOT_ALLOC_MEM;
    }

    // 将原来的物理盘信息备份
    errno_t securec_rv = memcpy_s(temp_info, old_pd_list->pd_count * sizeof(SML_PD_INFO_S), pd_info,
        old_pd_list->pd_count * sizeof(SML_PD_INFO_S));
    if (securec_rv != EOK) {
        debug_log(DLOG_ERROR, "%s: memcpy_s failed, ret = %d", __FUNCTION__, securec_rv);
    }

    for (i = 0; i < new_pd_list->pd_count; i++) {
        // 查找新id在原来的id列表中的位置，找到后将物理盘信息拷贝到新id对应的位置(数组下标一致)
        if ((RET_OK == check_pd_device_id(new_pd_list->device_ids[i], old_pd_list, &pd_idx)) &&
            (pd_idx < old_pd_list->pd_count)) {
            memcpy_s(&pd_info[i], sizeof(SML_PD_INFO_S), &temp_info[pd_idx], sizeof(SML_PD_INFO_S));
        } else { // 没有找到物理盘信息的设置为无效值
            (void)memset_s(&pd_info[i], sizeof(SML_PD_INFO_S), 0xff, sizeof(SML_PD_INFO_S));
            pd_info[i].last_update_timestamp = 0;
            pd_info[i].smartinfo.valid_flag = 0;
            pd_info[i].smartinfo.last_update_timestamp = 0;

            pd_info[i].pdinfo.proginfo.patrol_state = 0;
            pd_info[i].pdinfo.proginfo.patrol_progress = 0;
            pd_info[i].pdinfo.proginfo.rebuild_state = 0;
            pd_info[i].pdinfo.proginfo.rebuild_progress = 0;

            pd_info[i].pdinfo.media_err_count = 0;
            pd_info[i].pdinfo.prefail_count = 0;
            pd_info[i].pdinfo.other_err_count = 0;

            pd_info[i].pdinfo.fw_state = 0;

            (void)memset_s(pd_info[i].pd_warnig_info_reported, MAX_PD_WARNNING_INFO, 0, MAX_PD_WARNNING_INFO);
            (void)memset_s(&pd_info[i].hw_defined_smartinfo, sizeof(SML_PD_HW_DEFINED_SMART_INFO_S), 0,
                sizeof(SML_PD_HW_DEFINED_SMART_INFO_S));
            (void)memset_s(&pd_info[i].pdinfo.estimated_lifespan, sizeof(SML_PD_ESTIMATED_LIFESPAN_INFO_S), 0,
                sizeof(SML_PD_ESTIMATED_LIFESPAN_INFO_S));
            (void)memset_s(&pd_info[i].pdinfo.spare_block, sizeof(SML_PD_SPARE_BLOCK_INFO_S), 0,
                sizeof(SML_PD_SPARE_BLOCK_INFO_S));
            (void)memset_s(&pd_info[i].pdinfo.write_amp, sizeof(SML_PD_WRITE_AMP_INFO_S), 0,
                sizeof(SML_PD_WRITE_AMP_INFO_S));
        }
    }

    g_free(temp_info);

    return SML_SUCCESS;
}
/* END:   Added on 2017/1/11 */

/*
 * Description: 用于读取RAID控制器的LD概况，并更新全局缓存数据
 * History: 1.2016年3月7日
 *          新生成函数
 */
gint32 smlib_get_ctrl_ld_list(guint8 ctrl_index, SML_LD_LIST_S *ctrl)
{
    gint32 retval = SML_SUCCESS;
    guint32 current_timestamp = 0;
    guint32 last_udate_timestamp = 0;
    /* BEGIN: Modified for PN:CSEC on 2018/12/7 */
    guint8 update = FALSE;
    SML_LD_LIST_S new_ld_list = { 0 };
    gint32 data_validity = 0;
    gint32 locked = FALSE;
    SML_CTRL_S* sml_ctrl = NULL;

    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, ctrl))) {
        return retval;
    }

#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    last_udate_timestamp = sml_ctrl->controller.ldlist.last_update_timestamp;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);

    // 上次更新数据的时间是0或者距离上次更新数据已经超过数据更新时间间隔，并且当前控制器没有在执行任何操作，否则直接取缓存数据
    data_validity =
        check_cache_data_is_expired(0, current_timestamp, last_udate_timestamp, SMLIB_UPDATE_CACHE_DATA_INTREVAL);
    // 超时刷新，试探获取操作锁；如果是无效数据或者强制刷新，必须等待获取操作锁
    if (CACHE_DATA_INVALID_TIMEOUT == data_validity) {
        if (g_mutex_trylock(&sml_ctrl->op_mutex)) {
            locked = TRUE;
        } else {
            debug_log(DLOG_DEBUG, "smlib_get_ctrl_ld_list: op_mutex locked, skip operation\n");
        }
    } else if ((CACHE_DATA_INVALID_NO_DATA == data_validity) || (CACHE_DATA_INVALID_FORCED == data_validity)) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        locked = TRUE;
    }

    if (locked) {
        if (NULL != sml_ctrl->pfn_get_ctrl_ld_list) {
            // 调用适配层接口获取数据，成功则将数据更新至全局缓存数据区
            retval = sml_ctrl->pfn_get_ctrl_ld_list(sml_ctrl->controller_id, &new_ld_list);
            if (SML_SUCCESS == retval) {
                update = TRUE;
            } else {
                debug_log(DLOG_DEBUG,
                    "smlib: Get RAID controller [Ctrl index %d, Ctrl ID %d] LD list failed, return 0x%04x\n",
                    ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
            }
        } else {
            retval = SML_ERR_NULL_INFTERFACE;
        }

        g_mutex_unlock(&sml_ctrl->op_mutex);
    }

    // 实际从RAID卡更新数据会耗费几百毫秒到几秒的时间，这里再次获取当前系统时间记录更准确
#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    // 集中更新缓存数据，拷贝需要返回的数据
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    // 从RAID卡实际执行结果更新数据到全局缓存
    if (update) {
        // 如果逻辑盘id列表发生了变化，与之对应的逻辑盘信息存储顺序也需要对应调整
        // 调整的目的是为了充分利用已有的逻辑盘信息而不必重新从硬件读取
        if (new_ld_list.ld_count != sml_ctrl->controller.ldlist.ld_count) {
            (void)resort_ld_infos(&new_ld_list, &sml_ctrl->controller.ldlist,
                &sml_ctrl->controller.ld[0]);
        }

        memcpy_s(&sml_ctrl->controller.ldlist, sizeof(SML_LD_LIST_S), &new_ld_list, sizeof(SML_LD_LIST_S));
        sml_ctrl->controller.ldlist.last_update_timestamp = current_timestamp;
    }

    /* END:   Modified for PN:CSEC on 2018/12/7 */
    memcpy_s(ctrl, sizeof(SML_LD_LIST_S), &sml_ctrl->controller.ldlist, sizeof(SML_LD_LIST_S));

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    return retval;
}

/*
 * Description: 用于读取RAID控制器的PD概况，并更新全局缓存数据
 * History: 1.2016年3月7日
 *          新生成函数
 */
gint32 smlib_get_ctrl_pd_list(guint8 ctrl_index, SML_PD_LIST_S *ctrl)
{
    gint32 retval = SML_SUCCESS;
    guint32 current_timestamp = 0;
    guint32 last_udate_timestamp = 0;
    guint8 updated = FALSE;
    SML_PD_LIST_S new_pd_list = { 0 };
    gint32 data_validity = 0;
    gint32 locked = FALSE;
    SML_CTRL_S* sml_ctrl = NULL;

    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, ctrl))) {
        return retval;
    }

#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    last_udate_timestamp = sml_ctrl->controller.pdlist.last_update_timestamp;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);

    // 上次更新数据的时间是0或者距离上次更新数据已经超过数据更新时间间隔，并且当前控制器没有在执行任何操作，否则直接取缓存数据
    data_validity =
        check_cache_data_is_expired(0, current_timestamp, last_udate_timestamp, SMLIB_UPDATE_CACHE_DATA_INTREVAL);
    // 超时刷新，试探获取操作锁；如果是无效数据或者强制刷新，必须等待获取操作锁
    if (CACHE_DATA_INVALID_TIMEOUT == data_validity) {
        if (g_mutex_trylock(&sml_ctrl->op_mutex)) {
            locked = TRUE;
        } else {
            debug_log(DLOG_DEBUG, "smlib_get_ctrl_pd_list: op_mutex locked, skip operation\n");
        }
    } else if ((CACHE_DATA_INVALID_NO_DATA == data_validity) || (CACHE_DATA_INVALID_FORCED == data_validity)) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        locked = TRUE;
    }

    if (locked) {
        if (NULL != sml_ctrl->pfn_get_ctrl_pd_list) {
            // 调用适配层接口获取数据，成功则将数据更新至全局缓存数据区
            retval = sml_ctrl->pfn_get_ctrl_pd_list(sml_ctrl->controller_id, &new_pd_list);
            if (SML_SUCCESS == retval) {
                updated = TRUE;
            } else {
                /* BEGIN: Modified for PN:CSEC on 2018/12/7 */
                debug_log(DLOG_DEBUG,
                    "smlib: Get RAID controller [Ctrl index %d, Ctrl ID %d] PD list failed, return 0x%04x\n",
                    ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
                /* END:   Modified for PN:CSEC on 2018/12/7 */
            }
        } else {
            retval = SML_ERR_NULL_INFTERFACE;
        }

        g_mutex_unlock(&sml_ctrl->op_mutex);
    }

    // 实际从RAID卡更新数据会耗费几百毫秒到几秒的时间，这里再次获取当前系统时间记录更准确
#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    // 集中更新缓存数据，拷贝需要返回的数据
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    // 从RAID卡实际执行结果更新数据到全局缓存
    if (updated) {
        // 如果物理盘id列表发生了变化，与之对应的物理盘信息存储顺序也需要对应调整
        // 调整的目的是为了充分利用已有的物理盘信息而不必重新从硬件读取
        if (new_pd_list.pd_count != sml_ctrl->controller.pdlist.pd_count) {
            (void)resort_pd_infos(&new_pd_list, &sml_ctrl->controller.pdlist,
                &sml_ctrl->controller.pd[0]);
        }

        memcpy_s(&sml_ctrl->controller.pdlist, sizeof(SML_PD_LIST_S), &new_pd_list, sizeof(SML_PD_LIST_S));
        sml_ctrl->controller.pdlist.last_update_timestamp = current_timestamp;
    }

    memcpy_s(ctrl, sizeof(SML_PD_LIST_S), &sml_ctrl->controller.pdlist, sizeof(SML_PD_LIST_S));

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    return retval;
}

/*
 * Description: 用于读取RAID控制器的ARRAY列表，并更新全局缓存数据
 * History: 1.2016年11月8日, ()
 *          新生成函数
 */
gint32 smlib_get_ctrl_array_list(guint8 ctrl_index, SML_ARRAY_LIST_S *ctrl)
{
    gint32 retval = SML_SUCCESS;
    guint32 current_timestamp = 0;
    guint32 last_udate_timestamp = 0;
    guint8 updated = FALSE;
    SML_ARRAY_LIST_S new_array_list = { 0 };
    gint32 data_validity = 0;
    gint32 locked = FALSE;
    SML_CTRL_S* sml_ctrl = NULL;

    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, ctrl))) {
        return retval;
    }

#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->ctrl_mutex);
    last_udate_timestamp = sml_ctrl->controller.arraylist.last_update_timestamp;
    g_mutex_unlock(&sml_ctrl->ctrl_mutex);

    // 上次更新数据的时间是0或者距离上次更新数据已经超过数据更新时间间隔，并且当前控制器没有在执行任何操作，否则直接取缓存数据
    data_validity =
        check_cache_data_is_expired(0, current_timestamp, last_udate_timestamp, SMLIB_UPDATE_CACHE_DATA_INTREVAL);
    // 超时刷新，试探获取操作锁；如果是无效数据或者强制刷新，必须等待获取操作锁
    if (CACHE_DATA_INVALID_TIMEOUT == data_validity) {
        if (g_mutex_trylock(&sml_ctrl->op_mutex)) {
            locked = TRUE;
        } else {
            debug_log(DLOG_DEBUG, "smlib_get_ctrl_array_list: op_mutex locked, skip operation\n");
        }
    } else if ((CACHE_DATA_INVALID_NO_DATA == data_validity) || (CACHE_DATA_INVALID_FORCED == data_validity)) {
        g_mutex_lock(&sml_ctrl->op_mutex);
        locked = TRUE;
    }

    if (locked) {
        if (NULL != sml_ctrl->pfn_get_ctrl_array_list) {
            // 调用适配层接口获取数据，成功则将数据更新至全局缓存数据区
            retval =
                sml_ctrl->pfn_get_ctrl_array_list(sml_ctrl->controller_id, &new_array_list);
            if (SML_SUCCESS == retval) {
                updated = TRUE;
            } else {
                /* BEGIN: Modified for PN:CSEC on 2018/12/7 */
                debug_log(DLOG_DEBUG,
                    "smlib: Get RAID controller [Ctrl index %d, Ctrl ID %d] Array list failed, return 0x%04x\n",
                    ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
            }
        } else {
            retval = SML_ERR_NULL_INFTERFACE;
        }

        g_mutex_unlock(&sml_ctrl->op_mutex);
    }

    // 实际从RAID卡更新数据会耗费几百毫秒到几秒的时间，这里再次获取当前系统时间记录更准确
#ifdef ITEST_ENABLED
    current_timestamp = iTest_get_cur_time_stamp();
#else
    current_timestamp = (guint32)time(0);
#endif

    // 集中更新缓存数据，拷贝需要返回的数据
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    // 从RAID卡实际执行结果更新数据到全局缓存
    if (updated) {
        gboolean array_list_changed = (sml_ctrl->controller.arraylist.array_count != new_array_list.array_count) ||
            (memcmp(sml_ctrl->controller.arraylist.array_refs, new_array_list.array_refs,
            sizeof(sml_ctrl->controller.arraylist.array_refs)) != 0);
        if (array_list_changed) {
            (void)memset_s(&sml_ctrl->controller.array, sizeof(SML_ARRAY_INFO_S) * SML_MAX_ARRAY, 0,
                sizeof(SML_ARRAY_INFO_S) * SML_MAX_ARRAY);
        }
        memcpy_s(&sml_ctrl->controller.arraylist, sizeof(SML_ARRAY_LIST_S), &new_array_list,
            sizeof(SML_ARRAY_LIST_S));
        sml_ctrl->controller.arraylist.last_update_timestamp = current_timestamp;
    }
    /* END:   Modified for PN:CSEC on 2018/12/7 */

    memcpy_s(ctrl, sizeof(SML_ARRAY_LIST_S), &sml_ctrl->controller.arraylist, sizeof(SML_ARRAY_LIST_S));

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    return retval;
}

/*
 * Description: 用于读取RAID控制器的启动模式
 * History: 1.2018年6月27日
 */
gint32 smlib_get_ctrl_boot_mode(guint8 ctrl_index, guint8 *boot_mode)
{
    gint32 retval = SML_SUCCESS;
    SML_CTRL_S* sml_ctrl = NULL;
    if (SML_SUCCESS != (retval = check_input_parameters(ctrl_index, boot_mode))) {
        return retval;
    }

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->op_mutex);

    if (sml_ctrl->pfn_get_ctrl_boot_mode) {
        retval = sml_ctrl->pfn_get_ctrl_boot_mode(sml_ctrl->controller_id, boot_mode);
    }
    g_mutex_unlock(&sml_ctrl->op_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    return retval;
}

/*
 * Description: 执行RAID控制器相关操作
 * History: 1.2016年11月10日, ()
 *          新生成函数
 */
gint32 smlib_exec_ctrl_operation(guint8 ctrl_index, guint8 operation, gpointer param, guint32 param_length)
{
    gint32 retval = SML_SUCCESS;
    SML_CTRL_S* sml_ctrl = NULL;

    // 有的操作不需要参数，param可能为空
    retval = check_input_parameters(ctrl_index, param);
    if (SML_SUCCESS != retval && SML_ERR_NULL_DATA != retval) {
        return retval;
    }

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->op_mutex);

    if (NULL != sml_ctrl->pfn_ctrl_operation) {
        // 调用适配层接口执行操作
        retval = sml_ctrl->pfn_ctrl_operation(sml_ctrl->controller_id, operation, param,
            param_length);
        if (retval != SML_SUCCESS && retval != SML_ERR_REBOOT_REQUIRED) {
            debug_log(DLOG_DEBUG,
                "smlib: RAID controller [Ctrl index %d, Ctrl ID %d] exec Controller operation %d failed, return "
                "0x%04x\n",
                ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), operation, retval);
        }
    } else {
        retval = SML_ERR_NULL_INFTERFACE;
    }

    g_mutex_unlock(&sml_ctrl->op_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    // 强制要求刷新控制器信息
    if (retval == SML_SUCCESS || retval == SML_ERR_REBOOT_REQUIRED) {
        smlib_invalid_ctrl_cached_info(ctrl_index, CTRL_INFO_TYPE_CTRL);

        smlib_refresh_all_lds_from_cache_next(ctrl_index, 1);
        smlib_refresh_all_arrays_from_cache_next(ctrl_index, 1);
        smlib_refresh_all_pds_from_cache_next(ctrl_index, 1);
        smlib_refresh_all_other_from_cache_next(ctrl_index, 1);
    }

    return retval;
}

/*
 * Description: 获取控制器的启动盘
 */
gint32 smlib_get_ctrl_boot_devices(SML_CTRL_BOOTABLE_DEVICES_S *boot_devices)
{
    guint8 i;
    guint8 boot_priority;
    guint32 volume_id;

    if (boot_devices == NULL) {
        return SML_ERR_NULL_DATA;
    }

    guint8 ctrl_index = boot_devices->i_controller_index;

    lock_ctrl_list_mutex(ctrl_index);
    SML_CTRL_S* sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }

    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    /* 遍历物理盘的启动盘状况 */
    for (i = 0; i < sml_ctrl->controller.pdlist.pd_count; i++) {
        boot_priority = sml_ctrl->controller.pd[i].pdinfo.boot_priority;
        if (boot_priority == BOOT_PRIORITY_NONE) {
            continue;
        }

        // 左移8位存放背板id
        volume_id = VOLUME_TYPE_PHYSICAL_DRIVE_BIT | (sml_ctrl->controller.pd[i].pdinfo.encl_device_id << 8) |
            sml_ctrl->controller.pd[i].pdinfo.slot_num;

        if (boot_priority == BOOT_PRIORITY_PRIMARY || boot_priority == BOOT_PRIORITY_ALL) {
            boot_devices->o_bootable_devices[0] = volume_id;
        }

        if (boot_priority == BOOT_PRIORITY_SECONDARY || boot_priority == BOOT_PRIORITY_ALL) {
            boot_devices->o_bootable_devices[1] = volume_id;
        }
    }

    /* 找全了可以不用找了 */
    if (boot_devices->o_bootable_devices[0] != 0 && boot_devices->o_bootable_devices[1] != 0) {
        g_mutex_unlock(&sml_ctrl->ctrl_mutex);
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_SUCCESS;
    }

    /* 遍历逻辑盘的启动盘状况 */
    for (i = 0; i < sml_ctrl->controller.ldlist.ld_count; i++) {
        boot_priority = sml_ctrl->controller.ld[i].ldinfo.boot_priority;
        if (boot_priority == BOOT_PRIORITY_NONE) {
            continue;
        }

        volume_id = VOLUME_TYPE_LOGICAL_DRIVE_BIT | sml_ctrl->controller.ld[i].ldinfo.target_id;

        if (boot_priority == BOOT_PRIORITY_PRIMARY || boot_priority == BOOT_PRIORITY_ALL) {
            boot_devices->o_bootable_devices[0] = volume_id;
        }

        if (boot_priority == BOOT_PRIORITY_SECONDARY || boot_priority == BOOT_PRIORITY_ALL) {
            boot_devices->o_bootable_devices[1] = volume_id;
        }
    }

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);
    return SML_SUCCESS;
}

gint32 smlib_exec_parse_ctrl_log(guint8 ctrl_index, const gchar *src_dir, const gchar *dest_dir)
{
    gint32 retval = SML_SUCCESS;
    retval = check_input_parameters(ctrl_index, (gpointer)1);
    if (SML_SUCCESS != retval && SML_ERR_NULL_DATA != retval) {
        return retval;
    }

    lock_ctrl_list_mutex(ctrl_index);
    SML_CTRL_S* sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->op_mutex);

    if (sml_ctrl->pfn_get_ctrl_parsed_log != NULL) {
        // 调用适配层接口执行操作
        retval = sml_ctrl->pfn_get_ctrl_parsed_log(src_dir, dest_dir);
        if (retval != SML_SUCCESS) {
            debug_log(DLOG_ERROR,
                "smlib: RAID controller [Ctrl index %d, Ctrl ID %d] exec parse ctrl log failed, return 0x%04x\n",
                ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
        }
    } else {
        retval = SML_ERR_NULL_INFTERFACE;
    }

    g_mutex_unlock(&sml_ctrl->op_mutex);
    unlock_ctrl_list_mutex(ctrl_index);
    return retval;
}

gint32 smlib_exec_pd_trans_drive_data(guint8 ctrl_index, const gchar *json_raw_str)
{
    gint32 retval = SML_SUCCESS;

    retval = check_input_parameters(ctrl_index, (gpointer)1);
    if (retval != SML_SUCCESS) {
        return retval;
    }
    
    lock_ctrl_list_mutex(ctrl_index);
    SML_CTRL_S* sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
   
    g_mutex_lock(&sml_ctrl->ctrl_mutex);

    if (sml_ctrl->pfn_trans_drive_data != NULL) {
        // 调用适配层接口执行操作
        retval = sml_ctrl->pfn_trans_drive_data(json_raw_str);
        if (retval != SML_SUCCESS) {
            debug_log(DLOG_ERROR,
                "smlib: RAID controller [Ctrl index %d, Ctrl ID %d] trans_drive_data failed, return 0x%04x\n",
                ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
        }
    } else {
        retval = SML_ERR_NULL_INFTERFACE;
    }

    g_mutex_unlock(&sml_ctrl->ctrl_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    return retval;
}

/*
* Description : 传输固件升级文件到RAID控制器
*/
gint32 smlib_upgrade_ctrl_process(guint8 ctrl_index, const gchar *file_path)
{
    gint32 retval = SML_SUCCESS;
    SML_CTRL_S *sml_ctrl = NULL;

    if (file_path == NULL || file_path[0] == '\0') {
        return SML_ERR_NULL_DATA;
    }
    retval = check_input_parameters(ctrl_index, (gpointer)file_path);
    if (retval != SML_SUCCESS) {
        return retval;
    }

    lock_ctrl_list_mutex(ctrl_index);
    sml_ctrl = get_ctrl_by_index(ctrl_index);
    if (sml_ctrl == NULL) {
        unlock_ctrl_list_mutex(ctrl_index);
        return SML_ERR_CTRL_NOT_REGISTERED;
    }
    g_mutex_lock(&sml_ctrl->op_mutex);

    if (sml_ctrl->pfn_upgrade_ctrl_process != NULL) {
        retval = sml_ctrl->pfn_upgrade_ctrl_process(sml_ctrl->controller_id, file_path);
        if (retval != SML_SUCCESS) {
            debug_log(DLOG_ERROR,
                "smlib: RAID controller [Ctrl index %d, Ctrl ID %d] upgrade failed, return 0x%04x",
                ctrl_index, SML_CTRL_ID_VALID_BIT(sml_ctrl->controller_id), retval);
        }
    } else {
        retval = SML_ERR_NULL_INFTERFACE;
    }

    g_mutex_unlock(&sml_ctrl->op_mutex);
    unlock_ctrl_list_mutex(ctrl_index);

    return retval;
}
