| /***************************************************************************** |
| * Copyright Statement: |
| * -------------------- |
| * This software is protected by Copyright and the information contained |
| * herein is confidential. The software may not be copied and the information |
| * contained herein may not be used or disclosed except with the written |
| * permission of MediaTek Inc. (C) 2005 |
| * |
| * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
| * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
| * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON |
| * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
| * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
| * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
| * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH |
| * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO |
| * NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S |
| * SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. |
| * |
| * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE |
| * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
| * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
| * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO |
| * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
| * |
| * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE |
| * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF |
| * LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND |
| * RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER |
| * THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). |
| * |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| * Filename: |
| * --------- |
| * nvram_drval_fat.c |
| * |
| * Project: |
| * -------- |
| * MAUI |
| * |
| * Description: |
| * ------------ |
| * This is Driver adaption level functions. |
| * |
| * Author: |
| * ------- |
| * ------- |
| * |
| *============================================================================ |
| * HISTORY |
| * Below this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| *------------------------------------------------------------------------------ |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| * removed! |
| * removed! |
| * removed! |
| * |
| *------------------------------------------------------------------------------ |
| * Upper this line, this part is controlled by PVCS VM. DO NOT MODIFY!! |
| *============================================================================ |
| ****************************************************************************/ |
| |
| /***************************************************************************** |
| * Include |
| *****************************************************************************/ |
| |
| #include "stdio.h" |
| #include "string.h" |
| #include "stdarg.h" |
| |
| #include "kal_general_types.h" |
| #include "kal_public_api.h" |
| |
| #include "fs_type.h" |
| #include "fs_func.h" |
| #include "fs_errcode.h" |
| |
| #include "nvram_main.h" |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| #include "dcl_gpt.h" |
| #endif |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| #include "nvram_cache_interface.h" |
| #endif |
| |
| |
| #if defined(__MTK_TARGET__) |
| #include "SST_secure.h" |
| #endif |
| #include "us_timer.h" |
| #include "ex_public.h" |
| |
| /***************************************************************************** |
| * Define |
| *****************************************************************************/ |
| |
| /***************************************************************************** |
| * Global Variable |
| *****************************************************************************/ |
| extern kal_mutexid g_nvram_fs_mutex; |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| extern DCL_HANDLE nvram_gpt_handle; |
| #endif |
| |
| #ifdef __NVRAM_WRITE_WITH_FILE_SIZE__ |
| extern kal_bool bResetNvramData; |
| #endif |
| |
| #ifdef __NVRAM_CHECK_FILE_AND_RECOVER__ |
| extern kal_bool Cali_filelist_found; |
| extern kal_bool Imei_filelist_found; |
| extern kal_bool is_nvram_in_ota_flow; |
| extern kal_bool is_nvram_first_restore; |
| extern kal_uint8 *CALI_FileListBuf; |
| extern kal_uint8 *IMEI_FileListBuf; |
| |
| #endif |
| |
| extern nvram_ee_info_type* nvram_ee_info; |
| extern kal_char nvram_trace_dump_temp_buffer[]; |
| extern kal_char nvram_trace_dump_buffer[]; |
| extern kal_mutexid g_nvram_dump_trace_mutex; |
| extern kal_wchar nvram_trace_filename[]; |
| extern FS_HANDLE nvram_trace_file_hdl; |
| extern kal_uint32 nvram_trace_dump_buffer_offset; |
| extern module_type stack_get_active_module_id( void ); |
| |
| /***************************************************************************** |
| * Local Variable |
| *****************************************************************************/ |
| |
| static kal_int32 nvram_fat_last_err; |
| static kal_uint32 nvram_fat_last_line; |
| static kal_uint8 g_chksum[128] = {0}; |
| |
| #ifdef __NVRAM_CRYPT_TEST__ |
| extern kal_uint32 bWriteMsp; |
| extern kal_uint32 bReadMsp; |
| #define NVRAM_SWCHANGE_REPORT_MSP_ENCRYPT_FILE "Z:\\NVRAM\\W_TST" |
| #define NVRAM_SWCHANGE_REPORT_MSP_DENCRYPT_FILE "Z:\\NVRAM\\R_TST" |
| |
| static kal_uint8 NVRAM_EF_MSP_TEST_W[NVRAM_MSP_TEST_LEN * 3]; |
| static kal_uint8 NVRAM_EF_MSP_TEST_R[NVRAM_MSP_TEST_LEN * 3]; |
| #endif |
| |
| #ifndef __MTK_TARGET__ /* Simulate by nvram on MODIS */ |
| void SST_Secure_Algo (kal_uint8 Direction, kal_uint32 ContentAddr, |
| kal_uint32 ContentLen, kal_uint8 *CustomSeed, |
| kal_uint8 *ResText) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_uint8 *source = (kal_uint8 *) ContentAddr; |
| kal_int32 i; |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| if ((ContentAddr & 0x03) != 0) |
| { |
| NVRAM_EXT_ASSERT(KAL_FALSE, ContentAddr, NVRAM_LOC_ADDRESS_ALIGN_FAIL_1, 0); |
| } |
| |
| if (NVRAM_MSP_ALIGNMENT_REMAINDER(ContentLen) != 0) |
| { |
| NVRAM_EXT_ASSERT(KAL_FALSE,ContentLen , NVRAM_LOC_LENGTH_ALIGN_FAIL_1, 0); |
| } |
| |
| for (i = 0 ;i < ContentLen; i ++) |
| { |
| *(ResText+i) = *(source+i) ^ i; |
| } |
| } |
| #endif |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_gpt_timeout_callback |
| * DESCRIPTION |
| * if FS access timeout will trigger assert |
| * PARAMETERS |
| * RETURNS |
| *****************************************************************************/ |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| void nvram_gpt_timeout_callback(void *data) |
| { |
| //timeout assert |
| NVRAM_EXT_ASSERT(KAL_FALSE,0, NVRAM_LOC_ACCESS_TIMEOUT_1, 0); |
| } |
| #endif |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_fat_last_err |
| * DESCRIPTION |
| * get the last error in nvram drv fat |
| * PARAMETERS |
| * RETURNS |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_get_last_err(void) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| return nvram_fat_last_err; |
| } |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_fat_last_line |
| * DESCRIPTION |
| * get the last error in nvram drv fat |
| * PARAMETERS |
| * RETURNS |
| *****************************************************************************/ |
| kal_uint32 nvram_drv_fat_get_last_line(void) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| return nvram_fat_last_line; |
| } |
| |
| #ifdef __NVRAM_CRYPT_TEST__ |
| static kal_bool nvram_create_report_msp_file(kal_bool bWrite) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| FS_HANDLE handle; |
| kal_uint32 filelen = NVRAM_MSP_TEST_LEN*3; |
| kal_uint32 written; |
| kal_int32 result = FS_NO_ERROR; |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| if ( bWrite ) |
| { |
| kal_wsprintf(filename, "%s", NVRAM_SWCHANGE_REPORT_MSP_ENCRYPT_FILE); |
| NVRAM_FS_START_EX(FS_OP_GETATTRIBUTES,filename); |
| result = FS_GetAttributes(filename); |
| NVRAM_FS_END(FS_OP_GETATTRIBUTES,result); |
| if (result >= FS_NO_ERROR) |
| { |
| NVRAM_FS_START_EX(FS_OP_DELETE, filename); |
| result = FS_Delete(filename); |
| NVRAM_FS_END(FS_OP_DELETE,result); |
| } |
| |
| |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| handle = FS_Open(filename, FS_CREATE_ALWAYS | FS_READ_WRITE); |
| NVRAM_FS_END(FS_OP_OPEN,handle); |
| if (handle > FS_NO_ERROR) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(handle, &NVRAM_EF_MSP_TEST_W, filelen, &written); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (result != FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Write fail at %d,result=%d \r\n",__FUNCTION__,__LINE__,result); |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(handle); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| bWriteMsp = 0; |
| return KAL_FALSE; |
| } |
| } |
| else |
| { |
| return KAL_FALSE; |
| } |
| |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(handle); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| bWriteMsp = 0; |
| } |
| else |
| { |
| kal_wsprintf(filename, "%s", NVRAM_SWCHANGE_REPORT_MSP_DENCRYPT_FILE); |
| NVRAM_FS_START_EX(FS_OP_GETATTRIBUTES,filename); |
| result = FS_GetAttributes(filename); |
| NVRAM_FS_END(FS_OP_GETATTRIBUTES,result); |
| if (result >= FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_GetAttributes fail at %d,result=%d \r\n",__FUNCTION__,__LINE__,result); |
| NVRAM_FS_START_EX(FS_OP_DELETE,filename); |
| result = FS_Delete(filename); |
| NVRAM_FS_END(FS_OP_DELETE,result); |
| } |
| |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| handle = FS_Open(filename, FS_CREATE_ALWAYS | FS_READ_WRITE); |
| NVRAM_FS_END(FS_OP_OPEN,handle); |
| if (handle > FS_NO_ERROR) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(handle, &NVRAM_EF_MSP_TEST_R, filelen, &written); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (result != FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Write fail at %d,result=%d \r\n",__FUNCTION__,__LINE__,result); |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(handle); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| bReadMsp = 0; |
| return KAL_FALSE; |
| } |
| } |
| else |
| { |
| return KAL_FALSE; |
| } |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(handle); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| bReadMsp = 0; |
| } |
| |
| return KAL_TRUE; |
| } |
| #endif |
| |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_init |
| * DESCRIPTION |
| * This is nvram_drv_fat_init() function of NVRAM module. |
| * PARAMETERS |
| * void |
| * RETURNS |
| * if NVRAM folder does not exist, it means the FAT is empty. |
| *****************************************************************************/ |
| nvram_drv_status_enum nvram_drv_fat_status(void) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| FS_HANDLE hFile; |
| nvram_folder_enum i; |
| kal_int32 result = FS_NO_ERROR; |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_START; |
| nvram_ee_info->nvram_init_type = NVRAM_INIT_NORMAL_BOOT_UP; |
| } |
| #if !(defined(_SIMULATION) || defined(__PALLADIUM__) || defined(__FPGA__)) |
| if (nvram_check_first_bootup_log("FAT")) |
| { |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_CHECK_DONE; |
| nvram_ee_info->nvram_init_type = NVRAM_INIT_FIRST_BOOT_UP; |
| } |
| return NVRAM_DRV_UNFORMATTED; |
| } |
| #endif |
| |
| NVRAM_FS_MAKE_ROOT_PATH(filename); |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| hFile = FS_Open((const kal_wchar*)filename, FS_READ_ONLY | FS_OPEN_DIR); |
| NVRAM_FS_END(FS_OP_OPEN,hFile); |
| |
| if (hFile == FS_FILE_NOT_FOUND || hFile == FS_PATH_NOT_FOUND) |
| { |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_CHECK_DONE; |
| nvram_ee_info->nvram_init_type = NVRAM_INIT_FIRST_BOOT_UP; |
| } |
| return NVRAM_DRV_UNFORMATTED; |
| } |
| else if (hFile == FS_FDM_USER_DRIVE_BROKEN || |
| hFile == FS_FDM_SYS_DRIVE_BROKEN || |
| hFile == FS_FDM_MULTIPLE_BROKEN) |
| { |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_CHECK_DONE; |
| nvram_ee_info->nvram_init_context.dev_broken = KAL_TRUE; |
| } |
| return NVRAM_DRV_DRIVE_BROKEN; |
| } |
| else if (hFile == FS_FDM_VERSION_MISMATCH) |
| { |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_CHECK_DONE; |
| nvram_ee_info->nvram_init_context.dev_broken = KAL_TRUE; |
| } |
| return NVRAM_DRV_DRIVE_VNOERR; |
| } |
| else if (hFile >= FS_NO_ERROR) /* Success */ |
| { |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| } |
| else |
| { |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(hFile, __LINE__); |
| NVRAM_EXT_ASSERT(KAL_FALSE, (kal_uint32) hFile, NVRAM_LOC_OPEN_NV_FOLDER_FAIL_3, 0); |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_CHECK_DONE; |
| } |
| return NVRAM_DRV_FATAL_ERROR; |
| } |
| |
| |
| for (i = NVRAM_FOLDER_BEGIN; i < NVRAM_FOLDER_TOTAL; i++) |
| { |
| kal_wsprintf(filename, "%s", nvram_query_work_path(i)); |
| NVRAM_FS_START_EX(FS_OP_GETATTRIBUTES, filename); |
| result = FS_GetAttributes(filename); |
| NVRAM_FS_END(FS_OP_GETATTRIBUTES,result); |
| if (FS_NO_ERROR > result) |
| { |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FACTORY_BOOT_START; |
| } |
| return NVRAM_DRV_FOLDER_NOT_READY; |
| } |
| } |
| |
| return NVRAM_DRV_OK; |
| |
| } |
| |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_init |
| * DESCRIPTION |
| * This is nvram_drv_fat_init() function of NVRAM module. |
| * PARAMETERS |
| * void |
| * RETURNS |
| * if NVRAM folder does not exist, it means the FAT is empty. |
| *****************************************************************************/ |
| nvram_drv_status_enum nvram_drv_fat_init_start(void) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| kal_int32 Ret = FS_NO_ERROR; |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| Ret = NVRAM_FS_GET_FULL_PATH_LEN; |
| |
| nvram_create_first_bootup_log("FAT"); |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_CREATE_FAT_FILE_DONE; |
| } |
| /* check nvram root folder, if not exist, create it! */ |
| NVRAM_FS_MAKE_ROOT_PATH(filename); |
| NVRAM_FS_START_EX(FS_OP_GETATTRIBUTES, filename); |
| Ret = FS_GetAttributes(filename); |
| NVRAM_FS_END(FS_OP_GETATTRIBUTES,Ret); |
| if(FS_NO_ERROR > Ret) |
| { |
| NVRAM_FS_START_EX(FS_OP_CREATEDIR,filename); |
| Ret = FS_CreateDir((const kal_wchar*)filename); |
| NVRAM_FS_END(FS_OP_CREATEDIR,Ret); |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(Ret, __LINE__); |
| } |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_CREATE_MAIN_FOLDER_DONE; |
| } |
| nvram_create_all_folder(); |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_CREATE_ALL_FOLDER_DONE; |
| nvram_ee_info->nvram_init_time[2] = kal_get_systicks(); |
| } |
| return NVRAM_DRV_OK; |
| } |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_init |
| * DESCRIPTION |
| * This is nvram_drv_fat_init() function of NVRAM module. |
| * PARAMETERS |
| * void |
| * RETURNS |
| * if NVRAM folder does not exist, it means the FAT is empty. |
| *****************************************************************************/ |
| nvram_drv_status_enum nvram_drv_fat_init_end(void) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| nvram_delete_first_bootup_log("FAT"); |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_step = NVRAM_CORE_INIT_FIRST_BOOT_DELETE_FAT_FILE_DONE; |
| } |
| return NVRAM_DRV_OK; |
| } |
| |
| |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_format |
| * DESCRIPTION |
| * Dummy format function. |
| * PARAMETERS |
| * void |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| void nvram_drv_fat_format(void) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| /* Folder is ready as init, nothing to do in format */ |
| return; |
| } |
| |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_nvram_drv_fat_backup |
| * DESCRIPTION |
| * To make a backup. |
| * PARAMETERS |
| * prefix [IN] file prefix |
| * verno [IN] file verno |
| * a_to_b [IN] direction |
| * RETURNS |
| * error code |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_backup(nvram_ltable_entry_struct *ldi, kal_bool a_to_b) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_wchar src_path[NVRAM_MAX_PATH_LEN], dest_path[NVRAM_MAX_PATH_LEN]; |
| NVRAM_FILE_NAME nvramname; |
| kal_int32 result = FS_NO_ERROR; |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| if (a_to_b) |
| { |
| nvram_util_make_lid_filename(ldi, nvramname, KAL_TRUE); // A |
| nvram_query_file_name(nvram_query_folder_index_ex(ldi->category, KAL_TRUE), nvramname, src_path); |
| |
| #ifdef __NVRAM_BACKUP_DISK_FAT__ |
| if (NVRAM_IS_ATTR_BACKUP_FAT(ldi->attr)) |
| { |
| nvram_util_make_lid_filename(ldi, nvramname, KAL_TRUE); |
| nvram_query_file_name(NVRAM_NVD_BAK, nvramname, dest_path); |
| } |
| else |
| #endif |
| { |
| nvram_util_make_lid_filename(ldi, nvramname, KAL_FALSE); // B |
| nvram_query_file_name(nvram_query_folder_index_ex(ldi->category, KAL_FALSE), nvramname, dest_path); |
| } |
| } |
| else |
| { |
| #ifdef __NVRAM_BACKUP_DISK_FAT__ |
| if (NVRAM_IS_ATTR_BACKUP_FAT(ldi->attr)) |
| { |
| nvram_util_make_lid_filename(ldi, nvramname, KAL_TRUE); |
| nvram_query_file_name(NVRAM_NVD_BAK, nvramname, src_path); |
| } |
| else |
| #endif |
| { |
| nvram_util_make_lid_filename(ldi, nvramname, KAL_FALSE); // B |
| nvram_query_file_name(nvram_query_folder_index_ex(ldi->category, KAL_FALSE), nvramname, src_path); |
| |
| } |
| |
| nvram_util_make_lid_filename(ldi, nvramname, KAL_TRUE); // A |
| nvram_query_file_name(nvram_query_folder_index_ex(ldi->category, KAL_TRUE), nvramname, dest_path); |
| } |
| |
| #ifndef __LOW_COST_SUPPORT_ULC__ |
| |
| // FS_SetAttributes(dest_path, 0); |
| NVRAM_FS_START_EX(FS_OP_DELETE,dest_path); |
| result = FS_Delete(dest_path); |
| NVRAM_FS_END(FS_OP_DELETE,result); |
| NVRAM_FS_START_EX(FS_OP_MOVE,src_path); |
| result = FS_Move(src_path, dest_path, FS_MOVE_COPY, NULL, NULL, 0); |
| NVRAM_FS_END(FS_OP_MOVE,result); |
| #else |
| { |
| FS_HANDLE src, dest; |
| NVRAM_FS_START_EX(FS_OP_OPEN,src_path); |
| src = FS_Open(src_path, FS_READ_ONLY); |
| NVRAM_FS_END(FS_OP_OPEN,src); |
| NVRAM_FS_START_EX(FS_OP_OPEN,dest_path); |
| dest = FS_Open(dest_path, FS_READ_WRITE | FS_CREATE_ALWAYS); |
| NVRAM_FS_END(FS_OP_OPEN,dest); |
| |
| if (src >= FS_NO_ERROR && dest >= FS_NO_ERROR) |
| { |
| kal_uint32 len; |
| kal_uint8 *buf = (kal_uint8 *)get_ctrl_buffer(MAX_NVRAM_RECORD_SIZE); |
| NVRAM_FS_START(FS_OP_READ); |
| result = FS_Read(src, buf, MAX_NVRAM_RECORD_SIZE, &len); |
| NVRAM_FS_END(FS_OP_READ,result); |
| while ((ret == FS_NO_ERROR) && |
| result >= FS_NO_ERROR && |
| (len > 0)) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(dest, buf, len, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| } |
| nvram_fat_last_err = ret; |
| nvram_fat_last_line = __LINE__; |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(src); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(dest); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| free_ctrl_buffer(buf); |
| buf = NULL; |
| } |
| else |
| { |
| if (src < FS_NO_ERROR) |
| return src; |
| else |
| return dest; |
| } |
| } |
| #endif |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| if(result >= FS_NO_ERROR) |
| { |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_RD_WITH_CACHE(ldi->LID)) |
| { |
| unmask_valid_bit_by_ltable_entry(ldi, 0, (ldi->total_records + 1)); |
| } |
| } |
| #endif |
| |
| return result; |
| } |
| |
| #if defined(__NVRAM_FS_OPERATION_COMPACT__) && defined(__NVRAM_FS_CMPT_SIMULATION__) |
| /***************************************************************************** |
| * FUNCTION |
| * FS_CMPT_Read |
| * DESCRIPTION |
| * To simulate SP FS CMPT API |
| * RETURNS |
| * error code |
| *****************************************************************************/ |
| kal_int32 FS_CMPT_Read(const WCHAR * FileName, NVRAM_FS_PARAM_CMPT_T* nvram_param) |
| { |
| FS_HANDLE hFile; |
| int result; |
| kal_int32 ret = FS_NO_ERROR; |
| if((nvram_param->opid_map & (NVRAM_FS_CMPT_OPEN)) == (NVRAM_FS_CMPT_OPEN)){ |
| nvram_param->ret[0] |= NVRAM_FS_CMPT_OPEN; |
| NVRAM_FS_START_EX(FS_OP_OPEN,FileName); |
| hFile = FS_Open((const kal_wchar*)FileName, nvram_param->Flag); |
| NVRAM_FS_END(FS_OP_OPEN,hFile); |
| if (hFile < FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Open fail at %d,hFile=%d \r\n",__FUNCTION__,__LINE__,hFile); |
| nvram_param->ret[1] = hFile; |
| return hFile; |
| } |
| } |
| if((nvram_param->opid_map & (NVRAM_FS_CMPT_GETFILESIZE)) == (NVRAM_FS_CMPT_GETFILESIZE)){ |
| nvram_param->ret[0] |= NVRAM_FS_CMPT_GETFILESIZE; |
| NVRAM_FS_START(FS_OP_GETFILESIZE); |
| result = FS_GetFileSize(hFile, nvram_param->FileSize); |
| NVRAM_FS_END(FS_OP_GETFILESIZE,result); |
| if (result < FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_GetFileSize fail at %d,result=%d \r\n",__FUNCTION__,__LINE__,result); |
| nvram_param->ret[1] = result; |
| NVRAM_FS_START(FS_OP_CLOSE); |
| ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,ret); |
| return result; |
| } |
| } |
| if((nvram_param->opid_map & (NVRAM_FS_CMPT_SEEK)) == (NVRAM_FS_CMPT_SEEK)){ |
| nvram_param->ret[0] |= NVRAM_FS_CMPT_SEEK; |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, nvram_param->Offset, nvram_param->Whence); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if (result < FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek fail at %d,result=%d \r\n",__FUNCTION__,__LINE__,result); |
| nvram_param->ret[1] = result; |
| NVRAM_FS_START(FS_OP_CLOSE); |
| ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,ret); |
| return result; |
| } |
| } |
| if((nvram_param->opid_map & (NVRAM_FS_CMPT_READ)) == (NVRAM_FS_CMPT_READ)){ |
| nvram_param->ret[0] |= NVRAM_FS_CMPT_READ; |
| NVRAM_FS_START(FS_OP_READ); |
| result = FS_Read(hFile, nvram_param->DataPtr, nvram_param->Length, nvram_param->Read); |
| NVRAM_FS_END(FS_OP_READ,result); |
| if (result < FS_NO_ERROR) |
| { |
| nvram_param->ret[1] = result; |
| NVRAM_FS_START(FS_OP_CLOSE); |
| ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,ret); |
| return result; |
| } |
| } |
| nvram_param->ret[0] |= NVRAM_FS_CMPT_CLOSE; |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| |
| return result; |
| } |
| #endif /* __NVRAM_FS_CMPT_SIMULATION__ */ |
| |
| #if (defined(__NVRAM_FS_OPERATION_COMPACT__)&& defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__)) || defined(__NVRAM_FS_CMPT_SIMULATION__) |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_read_section_cmpt |
| * DESCRIPTION |
| * read record(s) from FAT. |
| * PARAMETERS |
| * hFile [IN] file handle |
| * rec_index [IN] which record to read (start) |
| * rec_amount [IN] how many record to read at once |
| * rec_size [IN] size of record |
| * buffer [IN/OUT] buffer of check sum |
| * type [IN] read content or checksum |
| * ismsp [IN] to indicate that the records protected by hw |
| * RETURNS |
| * = 0: success |
| * > 0: NVRAM error code |
| * < 0: FS error code |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_read_section_cmpt( |
| FS_HANDLE hFile, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| kal_uint8 *buffer, |
| nvram_drv_read_type_enum type, |
| nvram_ltable_entry_struct *ldi, |
| kal_wchar *filename, |
| NVRAM_FS_PARAM_CMPT_T *nvram_param |
| ) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_uint16 chksum3 = 0; |
| kal_uint8 *chksum1 = NULL; |
| kal_uint8 *chksum2 = NULL; |
| kal_uint32 len = 0, remainLen = 0; |
| kal_uint32 section_size; |
| kal_uint32 working_buffer_size; |
| kal_uint8 *working_buffer = NULL; |
| kal_int32 result = NVRAM_DRV_OK; |
| kal_uint32 i,j; |
| kal_bool skip_verify = KAL_FALSE; |
| kal_uint32 file_offset = nvram_param->Offset; |
| nvram_ldi_ota_header *ota_header; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| kal_bool is_valid_bit = KAL_TRUE; |
| kal_uint32 m, n; |
| kal_bool is_only_chksum = KAL_FALSE; |
| kal_uint32 max_cache_read_size = 0; |
| #endif |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| /* read RAW data directly */ |
| if(NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) { |
| nvram_param->opid_map |= NVRAM_FS_CMPT_SEEK; |
| nvram_param->Whence = FS_FILE_CURRENT; |
| |
| nvram_param->opid_map |= NVRAM_FS_CMPT_READ; |
| nvram_param->DataPtr = buffer; |
| nvram_param->Length = rec_size; |
| nvram_param->Read = &len; |
| nvram_param->opid_map |= NVRAM_FS_CMPT_CLOSE; |
| NVRAM_FS_START_EX(FS_OP_CMPTREAD,filename); |
| result = FS_CMPT_Read(filename, nvram_param); |
| NVRAM_FS_END(FS_OP_CMPTREAD,result); |
| if (nvram_param->opid_map != nvram_param->ret[0]) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_CMPT_Read fail at %d \r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]nvram_param->opid_map(%d) != nvram_param->ret[0](%d) \r\n",nvram_param->opid_map,nvram_param->ret[0]); |
| nvram_fat_last_err = nvram_param->ret[1]; |
| nvram_fat_last_line = __LINE__; |
| } |
| if (len==0) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"%s ->FS_CMPT_Read fail as len=0\r\n",__FUNCTION__); |
| result = FS_INVALID_FILE_POS; // End of File |
| nvram_fat_last_line = __LINE__; |
| } |
| goto END; |
| } |
| |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if ((ldi->attr & NVRAM_ATTR_MSP)||(ldi->attr & NVRAM_ATTR_CONFIDENTIAL)) |
| { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| } |
| #else |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| } |
| #endif |
| |
| section_size = rec_size + nvram_chksum_size + remainLen; |
| |
| nvram_param->opid_map |= NVRAM_FS_CMPT_SEEK; |
| nvram_param->Offset += (rec_index - 1) * section_size; |
| nvram_param->Whence = FS_FILE_CURRENT; |
| |
| /* |
| //working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| //MAX_NVRAM_RECORD_SIZE = (NVRAM_CUSTOM_CFG_MAX_RECORD_SECTOR_NUM * NVRAM_RECORD_SECTOR_SIZE) |
| // = (128 0r 16 or 4) * 512 |
| */ |
| |
| working_buffer_size = section_size * rec_amount; |
| #ifdef __NVRAM_LID_CACHE__ |
| if(working_buffer_size < MD_CCCI_LIMIT_SIZE) |
| { |
| max_cache_read_size = MD_CCCI_LIMIT_SIZE; |
| } |
| else |
| { |
| max_cache_read_size = ((working_buffer_size -1 )/MD_CCCI_LIMIT_SIZE + 1)* MD_CCCI_LIMIT_SIZE; |
| } |
| if(max_cache_read_size > MAX_NVRAM_RECORD_SIZE) |
| { |
| max_cache_read_size = MAX_NVRAM_RECORD_SIZE; |
| } |
| #endif |
| if (working_buffer_size > MAX_NVRAM_RECORD_SIZE) |
| { |
| working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| } |
| |
| // judge read checksum only |
| if ((type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY) || (type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B)) { |
| //Do not support read checksum only from encrypted |
| if(ldi->attr & (NVRAM_ATTR_CONFIDENTIAL | NVRAM_ATTR_MSP) || |
| (rec_amount * nvram_chksum_size) > MAX_NVRAM_RECORD_SIZE ) { |
| type = (type==NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B)?NVRAM_DRV_READ_TYPE_CHKSUM_2B: NVRAM_DRV_READ_TYPE_CHKSUM; |
| } |
| else { |
| skip_verify = KAL_TRUE; |
| working_buffer_size = (rec_amount * nvram_chksum_size); |
| #ifdef __NVRAM_LID_CACHE__ |
| is_only_chksum = KAL_TRUE; |
| #endif |
| } |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| working_buffer = (kal_uint8*) get_ctrl_buffer(max_cache_read_size); |
| #else |
| working_buffer = (kal_uint8*) get_ctrl_buffer(working_buffer_size); |
| #endif |
| // return checksum only |
| if(skip_verify) |
| { |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) { |
| //get appendix header |
| if(ldi->append_offset == 0) { |
| ota_header = (nvram_ldi_ota_header *)get_ctrl_buffer(NVRAM_LDI_OTA_HEADER_SIZE); |
| if(KAL_TRUE == nvram_read_data_header(filename, LDI_HEADER_OTA_SECTION, ota_header, NVRAM_LDI_OTA_HEADER_SIZE) && |
| (ota_header->ldi_attr & NVRAM_ATTR_CHKSUM_INTEGRATE) ) |
| { |
| ldi->append_offset = nvram_appendix_header_offset(ldi); |
| } |
| else { |
| ldi->append_offset = -1; |
| } |
| free_ctrl_buffer(ota_header); |
| } |
| if(ldi->append_offset > 0) { |
| nvram_param->opid_map |= NVRAM_FS_CMPT_READ; |
| nvram_param->Offset = (ldi->append_offset + NVRAM_LDI_APPENDIX_HEADER_SIZE + ((rec_index - 1) * nvram_chksum_size)); |
| nvram_param->DataPtr = working_buffer; |
| nvram_param->Length = (rec_amount * nvram_chksum_size); |
| nvram_param->Read = &len; |
| nvram_param->opid_map |= NVRAM_FS_CMPT_CLOSE; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| if (NVRAM_RD_WITH_CACHE(ldi->LID)) |
| { |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_read_data_from_cache(ldi, nvram_param))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"%s ->nvram_read_data_from_cache fail,result=%d\r\n",__FUNCTION__,result); |
| result = FS_ERROR_RESERVED; |
| nvram_fat_last_line = __LINE__; |
| } |
| |
| for(m = 0; m < rec_amount; m++) |
| { |
| is_valid_bit = KAL_FALSE; |
| for(n = 0; n < nvram_chksum_size; n++) |
| { |
| if(*(((kal_uint8*)(nvram_param->DataPtr)) + (m * nvram_chksum_size + n)) != 0) |
| { |
| is_valid_bit = KAL_TRUE; |
| break; |
| } |
| } |
| if(is_valid_bit == KAL_FALSE) |
| { |
| break; |
| } |
| } |
| |
| if(is_valid_bit == KAL_FALSE) |
| { |
| NVRAM_FS_START_EX(FS_OP_CMPTREAD,filename); |
| result = FS_CMPT_Read(filename, nvram_param); |
| NVRAM_FS_END(FS_OP_CMPTREAD,result); |
| if (result == FS_NO_ERROR) { |
| update_cache_data(ldi, rec_index, rec_amount, nvram_param, is_only_chksum); |
| } |
| } |
| }else |
| #endif |
| { |
| NVRAM_FS_START_EX(FS_OP_CMPTREAD,filename); |
| result = FS_CMPT_Read(filename, nvram_param); |
| NVRAM_FS_END(FS_OP_CMPTREAD,result); |
| } |
| |
| if ((nvram_param->opid_map != nvram_param->ret[0]) || (len==0)) |
| { |
| //goto normal read flow when read appendix fail |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_CMPT_Read fail at %d\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]nvram_param->opid_map(%d) != nvram_param->ret[0](%d) or len==%d \r\n",nvram_param->opid_map,nvram_param->ret[0],len); |
| goto NO_CHKSUM_INTEGRATE; |
| } |
| } |
| else { |
| goto NO_CHKSUM_INTEGRATE; |
| } |
| } |
| else { |
| NO_CHKSUM_INTEGRATE: |
| for (j = 0; j < rec_amount; j++) |
| { |
| nvram_param->opid_map |= NVRAM_FS_CMPT_READ; |
| /* |
| 1, will be a full process: fs_open() ==> fs_seek(, offsert) ==> fs_read() ==> fs_close() |
| 2, offset should be right |
| */ |
| nvram_param->Offset = file_offset + (rec_size + ((j + rec_index - 1) * section_size)); |
| nvram_param->DataPtr = (working_buffer + (j* nvram_chksum_size)); |
| nvram_param->Length = nvram_chksum_size; |
| nvram_param->Read = &len; |
| nvram_param->opid_map |= NVRAM_FS_CMPT_CLOSE; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| if (NVRAM_RD_WITH_CACHE(ldi->LID)) |
| { |
| result = nvram_read_data_from_cache(ldi, nvram_param); |
| is_valid_bit = KAL_FALSE; |
| for(n = 0; n < nvram_chksum_size; n++) |
| { |
| if(*(((kal_uint8*)(nvram_param->DataPtr)) + n) != 0) |
| { |
| is_valid_bit = KAL_TRUE; |
| break; |
| } |
| } |
| if (is_valid_bit == KAL_FALSE) |
| { |
| NVRAM_FS_START_EX(FS_OP_CMPTREAD,filename); |
| result = FS_CMPT_Read(filename, nvram_param); |
| NVRAM_FS_END(FS_OP_CMPTREAD,result); |
| if (result == FS_NO_ERROR) { |
| update_cache_data(ldi, rec_index+j, 1, nvram_param, is_only_chksum); |
| } |
| } |
| }else |
| #endif |
| { |
| NVRAM_FS_START_EX(FS_OP_CMPTREAD,filename); |
| result = FS_CMPT_Read(filename, nvram_param); |
| NVRAM_FS_END(FS_OP_CMPTREAD,result); |
| } |
| |
| if (nvram_param->opid_map != nvram_param->ret[0]) |
| { |
| nvram_fat_last_err = nvram_param->ret[1]; |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_CMPT_Read fail at %d\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]nvram_param->opid_map(%d) != nvram_param->ret[0](%d)\r\n",nvram_param->opid_map,nvram_param->ret[0]); |
| goto final; |
| } |
| if (len==0) |
| { |
| result = FS_INVALID_FILE_POS; // End of File |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_CMPT_Read fail at %d,len=0\r\n",__FUNCTION__,__LINE__); |
| goto final; |
| } |
| } |
| } |
| //Caculate checksum |
| if(type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B) { |
| for (j = 0; j < rec_amount; j++) { |
| chksum3 = nvram_util_md5_checksum_convert((working_buffer + (j* nvram_chksum_size)), NULL, KAL_TRUE); |
| kal_mem_cpy(buffer + (NVRAM_CHKSUM_SIZE_2B* j), &chksum3, NVRAM_CHKSUM_SIZE_2B); |
| } |
| } |
| else { |
| kal_mem_cpy(buffer, working_buffer, (rec_amount * nvram_chksum_size)); |
| } |
| } |
| else |
| { |
| kal_int32 rec_in_block = working_buffer_size / section_size; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| kal_uint32 rec_cnt_for_cache_read = 0; |
| kal_uint32 rec_index_for_cache_read = 0; |
| kal_uint32 cache_read_length = 0; |
| kal_int32 rec_in_block_for_cache_read = max_cache_read_size / section_size; |
| kal_uint32 nvram_param_offset_temp = 0; |
| void *DataPtr_temp = NULL; |
| #endif |
| chksum1 = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size); |
| for (i = 0 ; i < rec_amount; ) |
| { |
| kal_uint32 total_read = section_size * rec_in_block; |
| kal_uint32 working_buffer_sub_index = 0; |
| |
| |
| nvram_param->Offset = file_offset + (rec_index - 1) * section_size; |
| nvram_param->Offset += (i*section_size); |
| #ifdef __NVRAM_LID_CACHE__ |
| is_valid_bit = KAL_TRUE; |
| #endif |
| |
| /* last read */ |
| if (rec_in_block > rec_amount - i) |
| { |
| rec_in_block = rec_amount - i; |
| total_read = section_size * rec_in_block; |
| } |
| len = 0; |
| do |
| { |
| nvram_param->opid_map |= NVRAM_FS_CMPT_READ; |
| /* |
| 1, will be a full process: fs_open() ==> fs_seek(, offsert) ==> fs_read() ==> fs_close() |
| 2, offset should be right |
| */ |
| nvram_param->Offset += len; |
| nvram_param->DataPtr = (working_buffer + working_buffer_sub_index); |
| nvram_param->Length = total_read; |
| nvram_param->Read = &len; |
| nvram_param->opid_map |= NVRAM_FS_CMPT_CLOSE; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| is_valid_bit = KAL_TRUE; |
| nvram_param_offset_temp = nvram_param->Offset; |
| //DataPtr_temp = nvram_param->DataPtr; |
| cache_read_length = total_read; |
| |
| if (NVRAM_RD_WITH_CACHE(ldi->LID)) |
| { |
| int n; |
| rec_cnt_for_cache_read = rec_in_block_for_cache_read; |
| for( n = 0; n < rec_in_block; n++) |
| { |
| if (!check_valid_bit_by_ltable_entry(ldi, rec_index+i+n)) |
| { |
| rec_index_for_cache_read = rec_index +i+n; |
| if(rec_index+i+n + rec_in_block_for_cache_read > ldi->total_records) |
| { |
| rec_cnt_for_cache_read = ldi->total_records - (rec_index+i+n )+1; |
| } |
| is_valid_bit = KAL_FALSE; |
| break; |
| } |
| } |
| if(!is_valid_bit) |
| { |
| DataPtr_temp = (kal_uint8*) get_ctrl_buffer(rec_cnt_for_cache_read * section_size); |
| nvram_param->Offset += ((rec_index_for_cache_read- rec_index- i) * (section_size)); |
| nvram_param->DataPtr = DataPtr_temp; |
| nvram_param->Length = rec_cnt_for_cache_read * section_size; |
| NVRAM_FS_START_EX(FS_OP_CMPTREAD,filename); |
| result = FS_CMPT_Read(filename,nvram_param); |
| NVRAM_FS_END(FS_OP_CMPTREAD,result); |
| if (nvram_param->opid_map != nvram_param->ret[0]) |
| { |
| free_ctrl_buffer(DataPtr_temp); |
| DataPtr_temp = NULL; |
| nvram_fat_last_err = nvram_param->ret[1]; |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_CMPT_Read fail at %d\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]nvram_param->opid_map(%d) != nvram_param->ret[0](%d)\r\n",nvram_param->opid_map,nvram_param->ret[0]); |
| goto final; |
| } |
| if (len != nvram_param->Length) |
| { |
| free_ctrl_buffer(DataPtr_temp); |
| DataPtr_temp = NULL; |
| result = FS_INVALID_FILE_POS; // End of File |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_CMPT_Read fail at %d\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]len(%d) != %d\r\n",len, nvram_param->Length); |
| goto final; |
| } |
| update_cache_data(ldi, rec_index_for_cache_read, rec_cnt_for_cache_read, nvram_param, is_only_chksum); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index_for_cache_read, rec_cnt_for_cache_read); |
| free_ctrl_buffer(DataPtr_temp); |
| DataPtr_temp = NULL; |
| } |
| nvram_param->Offset = nvram_param_offset_temp; |
| nvram_param->DataPtr = (working_buffer + working_buffer_sub_index); |
| nvram_param->Length = cache_read_length; |
| len = total_read; |
| nvram_read_data_from_cache(ldi, nvram_param); |
| } |
| else |
| #endif |
| { |
| NVRAM_FS_START_EX(FS_OP_CMPTREAD,filename); |
| result = FS_CMPT_Read(filename, nvram_param); |
| NVRAM_FS_END(FS_OP_CMPTREAD,result); |
| if (nvram_param->opid_map != nvram_param->ret[0]) |
| { |
| nvram_fat_last_err = nvram_param->ret[1]; |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_CMPT_Read fail at %d\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]nvram_param->opid_map(%d) != nvram_param->ret[0](%d)\r\n",nvram_param->opid_map,nvram_param->ret[0]); |
| goto final; |
| } |
| |
| if (len == 0) |
| { |
| result = FS_INVALID_FILE_POS; // End of File |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_CMPT_Read fail at %d,len=0\r\n",__FUNCTION__,__LINE__); |
| goto final; |
| } |
| } |
| total_read -= len; |
| working_buffer_sub_index += len; |
| |
| }while(total_read > 0); |
| |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bReadMsp == 1) |
| { |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_R, working_buffer, NVRAM_MSP_TEST_LEN); |
| } |
| #endif |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| |
| if (ldi->attr & NVRAM_ATTR_MSP) |
| { |
| for (j = 0; j < rec_in_block; j++) |
| { |
| /* work arround solution for hw.. sej is not stable */ |
| #ifdef __CCCIFS_SUPPORT__ |
| kal_uint8 *working_buffer2 = (kal_uint8*) get_ctrl_buffer(section_size); |
| kal_uint8 *working_buffer3 = (kal_uint8*) get_ctrl_buffer(section_size); |
| |
| //copy the encrypted data from working_buffer to working_buffer2 |
| memcpy(working_buffer2, working_buffer + section_size * j, section_size); |
| |
| do |
| { |
| nvram_trace_to_file(__LINE__, 999, 1, 0, 0 ,0); |
| nvram_trace_to_file(nvram_ptr->secret_key[0], nvram_ptr->secret_key[1], nvram_ptr->secret_key[2], nvram_ptr->secret_key[3], 0, 0); |
| nvram_trace_to_file(working_buffer[j*section_size], working_buffer[j*section_size + 1], working_buffer[j*section_size + 2], working_buffer[j*section_size + 3], 0, 0); |
| //decrypt the working_buffer |
| SST_Secure_Algo(NVRAM_MSP_DECRYPT, (kal_uint32) (working_buffer + section_size * j), section_size, nvram_ptr->secret_key, working_buffer + section_size * j); |
| nvram_trace_to_file(working_buffer[j*section_size], working_buffer[j*section_size + 1], working_buffer[j*section_size + 2], working_buffer[j*section_size + 3], 0, 0); |
| |
| //copy decrypted data from working_buffer to working_buffer3 |
| memcpy(working_buffer3, working_buffer + section_size * j, section_size); |
| //encrypt the working_buffer3 |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer3, section_size, nvram_ptr->secret_key, working_buffer3); |
| |
| //compare the working_buffer2 & working_buffer3 |
| if (memcmp(working_buffer2, working_buffer3, section_size) == 0) |
| { |
| //decrypt PASS |
| break; |
| } |
| else |
| { |
| //decrypt FAIL, try again |
| memcpy(working_buffer + section_size * j, working_buffer2, section_size); |
| } |
| }while(1); |
| |
| free_ctrl_buffer(working_buffer2); |
| free_ctrl_buffer(working_buffer3); |
| working_buffer2 = NULL; |
| working_buffer3 = NULL; |
| #else |
| SST_Secure_Algo(NVRAM_MSP_DECRYPT, (kal_uint32) (working_buffer + section_size * j), section_size, nvram_ptr->secret_key, working_buffer + section_size * j); |
| #endif |
| } |
| } |
| #endif |
| |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bReadMsp == 1) |
| { |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_R[NVRAM_MSP_TEST_LEN],working_buffer,NVRAM_MSP_TEST_LEN); |
| } |
| #endif |
| |
| /* Handle multi-record reading */ |
| for (j = 0; j < rec_in_block; j++) |
| { |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| // custom_nvram_decrypt(nvram_ptr->secret_key, working_buffer + section_size * j, rec_size, rec_size); |
| nvram_AES_decrypt(working_buffer + section_size * j, section_size); |
| } |
| //get checksum from the working buffer |
| chksum2 = (kal_uint8*) (working_buffer + section_size * j + rec_size); |
| |
| //calculate the checksum from the content |
| /* checksum from content */ |
| kal_mem_set(chksum1, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, working_buffer + (section_size * j), rec_size, chksum1); |
| |
| if (kal_mem_cmp(chksum1, chksum2, nvram_chksum_size)!=0) |
| { |
| nvram_ptr->sw_status &= NVRAM_SW_SOME_CORRUPT; |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_context.sw_status = nvram_ptr->sw_status; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| if (NVRAM_RD_WITH_CACHE(ldi->LID)) |
| { |
| unmask_valid_bit_by_ltable_entry(ldi, 0, (ldi->total_records + 1)); |
| } |
| #endif |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_CHECKSUM_ERROR; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s Checksum error at %d\r\n",__FUNCTION__,__LINE__); |
| goto final; |
| } |
| //seems no need to calculate checksum3, and buffer for NVRAM_DRV_READ_TYPE_CHKSUM_2B is useless if we do not verify the checksum? |
| //if we want to compare the checksum between A & B, we need another buffer to use memcmp |
| /* checksum after decrypt */ |
| #ifdef __NV_CHKSUM_ENHANCE__ |
| if(lid_chksum_info.algo_info.chksum_algo_type == NVRAM_MD5) |
| { |
| kal_mem_set(chksum1, 0, nvram_chksum_size); |
| chksum3 = nvram_util_caculate_checksum(ldi, working_buffer + (section_size * j), rec_size, chksum1); |
| } |
| #else |
| chksum3 = nvram_util_caculate_checksum(ldi, working_buffer + (section_size * j), rec_size, chksum1); |
| #endif |
| if (type == NVRAM_DRV_READ_TYPE_DATA) |
| { |
| kal_mem_cpy(buffer + (rec_size * (i + j)), working_buffer + (section_size * j), rec_size); |
| } |
| else if ((type == NVRAM_DRV_READ_TYPE_CHKSUM_2B)||(type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B)) |
| { |
| kal_mem_cpy(buffer + (NVRAM_CHKSUM_SIZE_2B * (i + j)), &chksum3, NVRAM_CHKSUM_SIZE_2B); |
| } |
| else if ((type == NVRAM_DRV_READ_TYPE_CHKSUM)||(type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY)) |
| { |
| kal_mem_cpy(buffer + (nvram_chksum_size * (i + j)), chksum2, nvram_chksum_size); |
| } |
| } |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bReadMsp == 1) |
| { |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_R[NVRAM_MSP_TEST_LEN*2],working_buffer,NVRAM_MSP_TEST_LEN); |
| nvram_create_report_msp_file(KAL_FALSE); |
| } |
| #endif |
| |
| i += rec_in_block; |
| } |
| |
| } |
| final: |
| |
| if(chksum1) |
| { |
| free_ctrl_buffer(chksum1); |
| chksum1 = NULL; |
| } |
| if (working_buffer) |
| { |
| free_ctrl_buffer(working_buffer); |
| working_buffer = NULL; |
| } |
| |
| END: |
| if (FS_NO_ERROR > result) |
| { |
| nvram_fat_last_err = result; |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d status %d\r\n",__FUNCTION__,nvram_fat_last_line,nvram_fat_last_err); |
| } |
| |
| return result; |
| } |
| #endif |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_read_aux |
| * DESCRIPTION |
| * read record(s) from FAT. |
| * PARAMETERS |
| * hFile [IN] file handle |
| * rec_index [IN] which record to read (start) |
| * rec_amount [IN] how many record to read at once |
| * rec_size [IN] size of record |
| * buffer [IN/OUT] buffer of check sum |
| * type [IN] read content or checksum |
| * ismsp [IN] to indicate that the records protected by hw |
| * RETURNS |
| * = 0: success |
| * > 0: NVRAM error code |
| * < 0: FS error code |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_read_section( |
| FS_HANDLE hFile, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| kal_uint8 *buffer, |
| nvram_drv_read_type_enum type, |
| nvram_ltable_entry_struct *ldi) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_uint16 chksum3 = 0; |
| kal_uint8 *chksum1 = NULL; |
| kal_uint8 *chksum2 = NULL; |
| kal_uint32 len = 0, remainLen = 0; |
| kal_uint32 section_size; |
| kal_uint32 working_buffer_size; |
| kal_uint8 *working_buffer = NULL; |
| kal_int32 result = NVRAM_DRV_OK; |
| kal_uint32 i,j; |
| kal_bool skip_verify = KAL_FALSE; |
| nvram_ldi_ota_header *ota_header; |
| kal_uint32 seek_offset = 0; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| /* read RAW data directly */ |
| if(NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) { |
| NVRAM_FS_START(FS_OP_READ); |
| result = FS_Read(hFile, buffer, rec_size, &len); |
| NVRAM_FS_END(FS_OP_READ,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Read error at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| } |
| goto ERROR; |
| } |
| |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if ((ldi->attr & NVRAM_ATTR_MSP)||(ldi->attr & NVRAM_ATTR_CONFIDENTIAL)) |
| { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| } |
| #else |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| } |
| #endif |
| |
| section_size = rec_size + nvram_chksum_size + remainLen; |
| |
| |
| /* seek to the record start */ |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, (rec_index - 1) * section_size, FS_FILE_CURRENT); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Seek error at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto ERROR; |
| } |
| |
| //working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| //MAX_NVRAM_RECORD_SIZE = (NVRAM_CUSTOM_CFG_MAX_RECORD_SECTOR_NUM * NVRAM_RECORD_SECTOR_SIZE) |
| // = (16 or 4) * 512 |
| working_buffer_size = section_size * rec_amount; |
| if (working_buffer_size > MAX_NVRAM_RECORD_SIZE) |
| { |
| working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| } |
| // judge read checksum only |
| if ((type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY) || (type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B)) { |
| //Do not support read checksum only from encrypted |
| if(ldi->attr & (NVRAM_ATTR_CONFIDENTIAL | NVRAM_ATTR_MSP) || |
| (rec_amount * nvram_chksum_size) > MAX_NVRAM_RECORD_SIZE ) { |
| type = (type==NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B)?NVRAM_DRV_READ_TYPE_CHKSUM_2B: NVRAM_DRV_READ_TYPE_CHKSUM; |
| } |
| else { |
| skip_verify = KAL_TRUE; |
| working_buffer_size = (rec_amount * nvram_chksum_size); |
| } |
| } |
| working_buffer = (kal_uint8*) get_ctrl_buffer(working_buffer_size); |
| if(skip_verify) |
| { |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) { |
| //get appendix header |
| if(ldi->append_offset == 0) { |
| NVRAM_FS_START(FS_OP_SEEK); |
| seek_offset = FS_Seek(hFile, 0, FS_FILE_CURRENT); //backup FS offset |
| NVRAM_FS_END(FS_OP_SEEK,seek_offset); |
| ota_header = (nvram_ldi_ota_header *)get_ctrl_buffer(NVRAM_LDI_OTA_HEADER_SIZE); |
| if(KAL_TRUE == nvram_read_ota_header(hFile, ota_header, NVRAM_LDI_OTA_HEADER_SIZE) && |
| (ota_header->ldi_attr & NVRAM_ATTR_CHKSUM_INTEGRATE) ) |
| { |
| ldi->append_offset = nvram_appendix_header_offset(ldi); |
| } |
| else { |
| ldi->append_offset = -1; |
| } |
| free_ctrl_buffer(ota_header); |
| ota_header = NULL; |
| } |
| if(ldi->append_offset > 0) { |
| if(!seek_offset) { |
| //backup FS offset |
| NVRAM_FS_START(FS_OP_SEEK); |
| seek_offset = FS_Seek(hFile, 0, FS_FILE_CURRENT); |
| NVRAM_FS_END(FS_OP_SEEK,seek_offset); |
| } |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, (ldi->append_offset + NVRAM_LDI_APPENDIX_HEADER_SIZE + ((rec_index - 1) * nvram_chksum_size)), FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if(FS_NO_ERROR > result) |
| { |
| //goto normal read flow when read appendix fail |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek error at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| goto NO_CHKSUM_INTEGRATE; |
| } |
| NVRAM_FS_START(FS_OP_READ); |
| result = FS_Read(hFile, working_buffer, (rec_amount * nvram_chksum_size), &len); |
| NVRAM_FS_END(FS_OP_READ,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Read error at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| goto NO_CHKSUM_INTEGRATE; |
| } |
| } |
| else { |
| goto NO_CHKSUM_INTEGRATE; |
| } |
| } |
| else { |
| NO_CHKSUM_INTEGRATE: |
| if(seek_offset) { |
| //Restore FS ptr |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, seek_offset, FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| } |
| for (j = 0; j < rec_amount; j++) |
| { |
| /* seek to the record checksum */ |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, rec_size, FS_FILE_CURRENT); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if(FS_NO_ERROR > result) |
| { |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek error at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| goto ERROR; |
| } |
| |
| NVRAM_FS_START(FS_OP_READ); |
| result = FS_Read(hFile, (working_buffer + (j* nvram_chksum_size)), nvram_chksum_size, &len); |
| NVRAM_FS_END(FS_OP_READ,result); |
| if (FS_NO_ERROR > result) |
| { |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Read error at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| goto final; |
| } |
| } |
| } |
| //Caculate checksum |
| if(type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B) { |
| for (j = 0; j < rec_amount; j++) { |
| chksum3 = nvram_util_md5_checksum_convert((working_buffer + (j* nvram_chksum_size)), NULL, KAL_TRUE); |
| kal_mem_cpy(buffer + (NVRAM_CHKSUM_SIZE_2B* j), &chksum3, NVRAM_CHKSUM_SIZE_2B); |
| } |
| } |
| else { |
| kal_mem_cpy(buffer, working_buffer, (rec_amount * nvram_chksum_size)); |
| } |
| |
| } |
| else |
| { |
| kal_int32 rec_in_block = working_buffer_size / section_size; |
| |
| chksum1 = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size); |
| for (i = 0 ; i < rec_amount; ) |
| { |
| kal_uint32 total_read = section_size * rec_in_block; |
| kal_uint32 working_buffer_sub_index = 0; |
| |
| /* last read */ |
| if (rec_in_block > rec_amount - i) |
| { |
| rec_in_block = rec_amount - i; |
| } |
| |
| #define NVRAM_MAX_READ_LEN (3*1024) |
| |
| do |
| { |
| kal_uint32 this_read = total_read; |
| |
| if (total_read >= NVRAM_MAX_READ_LEN) |
| { |
| this_read = NVRAM_MAX_READ_LEN; |
| } |
| NVRAM_FS_START(FS_OP_READ); |
| result = FS_Read(hFile, working_buffer + working_buffer_sub_index, this_read, &len); |
| NVRAM_FS_END(FS_OP_READ,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Read error at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| |
| if (len==0) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Read error at %d,len=0\r\n",__FUNCTION__,__LINE__); |
| result = FS_INVALID_FILE_POS; // End of File |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| |
| total_read -= len; |
| working_buffer_sub_index += len; |
| |
| }while(total_read > 0); |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| |
| if (ldi->attr & NVRAM_ATTR_MSP) |
| { |
| for (j = 0; j < rec_in_block; j++) |
| { |
| /* work arround solution for hw.. sej is not stable */ |
| #ifdef __CCCIFS_SUPPORT__ |
| kal_uint8 *working_buffer2 = (kal_uint8*) get_ctrl_buffer(section_size); |
| kal_uint8 *working_buffer3 = (kal_uint8*) get_ctrl_buffer(section_size); |
| |
| //copy the encrypted data from working_buffer to working_buffer2 |
| memcpy(working_buffer2, working_buffer + section_size * j, section_size); |
| |
| do |
| { |
| nvram_trace_to_file(__LINE__, 999, 1, 0, 0 ,0); |
| nvram_trace_to_file(nvram_ptr->secret_key[0], nvram_ptr->secret_key[1], nvram_ptr->secret_key[2], nvram_ptr->secret_key[3], 0, 0); |
| nvram_trace_to_file(working_buffer[j*section_size], working_buffer[j*section_size + 1], working_buffer[j*section_size + 2], working_buffer[j*section_size + 3], 0, 0); |
| //decrypt the working_buffer |
| SST_Secure_Algo(NVRAM_MSP_DECRYPT, (kal_uint32) (working_buffer + section_size * j), section_size, nvram_ptr->secret_key, working_buffer + section_size * j); |
| nvram_trace_to_file(working_buffer[j*section_size], working_buffer[j*section_size + 1], working_buffer[j*section_size + 2], working_buffer[j*section_size + 3], 0, 0); |
| |
| //copy decrypted data from working_buffer to working_buffer3 |
| memcpy(working_buffer3, working_buffer + section_size * j, section_size); |
| //encrypt the working_buffer3 |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer3, section_size, nvram_ptr->secret_key, working_buffer3); |
| |
| //compare the working_buffer2 & working_buffer3 |
| if (memcmp(working_buffer2, working_buffer3, section_size) == 0) |
| { |
| //decrypt PASS |
| break; |
| } |
| else |
| { |
| //decrypt FAIL, try again |
| memcpy(working_buffer + section_size * j, working_buffer2, section_size); |
| } |
| }while(1); |
| |
| free_ctrl_buffer(working_buffer2); |
| free_ctrl_buffer(working_buffer3); |
| working_buffer2 = NULL; |
| working_buffer3 = NULL; |
| #else |
| SST_Secure_Algo(NVRAM_MSP_DECRYPT, (kal_uint32) (working_buffer + section_size * j), section_size, nvram_ptr->secret_key, working_buffer + section_size * j); |
| #endif |
| } |
| } |
| #endif |
| |
| |
| /* Handle multi-record reading */ |
| for (j = 0; j < rec_in_block; j++) |
| { |
| |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| // custom_nvram_decrypt(nvram_ptr->secret_key, working_buffer + section_size * j, rec_size, rec_size); |
| nvram_AES_decrypt(working_buffer + section_size * j, section_size); |
| } |
| //verify checksum one at once |
| |
| //get checksum from the working buffer |
| chksum2 = (kal_uint8*) (working_buffer + section_size * j + rec_size); |
| |
| //calculate the checksum from the content |
| /* checksum from content */ |
| kal_mem_set(chksum1, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, working_buffer + (section_size * j), rec_size,chksum1); |
| |
| if (kal_mem_cmp(chksum1, chksum2, nvram_chksum_size)!=0) |
| { |
| nvram_ptr->sw_status &= NVRAM_SW_SOME_CORRUPT; |
| if(nvram_ee_info != NULL){ |
| nvram_ee_info->nvram_init_context.sw_status = nvram_ptr->sw_status; |
| } |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_CHECKSUM_ERROR; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s Checksum error at %d\r\n",__FUNCTION__,__LINE__); |
| goto final; |
| } |
| |
| |
| //seems no need to calculate checksum3, and buffer for NVRAM_DRV_READ_TYPE_CHKSUM_2B is useless if we do not verify the checksum? |
| //if we want to compare the checksum between A & B, we need another buffer to use memcmp |
| /* checksum after decrypt */ |
| #ifdef __NV_CHKSUM_ENHANCE__ |
| if(lid_chksum_info.algo_info.chksum_algo_type== NVRAM_MD5) |
| { |
| kal_mem_set(chksum1, 0, nvram_chksum_size); |
| chksum3 = nvram_util_caculate_checksum(ldi, working_buffer + (section_size * j), rec_size,chksum1); |
| } |
| #else |
| chksum3 = nvram_util_caculate_checksum(ldi, working_buffer + (section_size * j), rec_size,chksum1); |
| #endif |
| if (type == NVRAM_DRV_READ_TYPE_DATA) |
| { |
| kal_mem_cpy(buffer + (rec_size * (i + j)), working_buffer + (section_size * j), rec_size); |
| } |
| else if((type == NVRAM_DRV_READ_TYPE_CHKSUM_2B)||(type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY_2B)) |
| { |
| kal_mem_cpy(buffer + (NVRAM_CHKSUM_SIZE_2B * (i + j)), &chksum3, NVRAM_CHKSUM_SIZE_2B); |
| } |
| else if ((type == NVRAM_DRV_READ_TYPE_CHKSUM)||(type == NVRAM_DRV_READ_TYPE_CHKSUM_ONLY)) |
| { |
| kal_mem_cpy(buffer + (nvram_chksum_size * (i + j)), chksum1, nvram_chksum_size); |
| } |
| } |
| i += rec_in_block; |
| } |
| |
| } |
| |
| final: |
| |
| if(chksum1) |
| { |
| free_ctrl_buffer(chksum1); |
| chksum1 = NULL; |
| } |
| if (working_buffer) |
| { |
| free_ctrl_buffer(working_buffer); |
| working_buffer = NULL; |
| } |
| |
| ERROR: |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_err = result; |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| } |
| |
| return result; |
| } |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_read_aux |
| * DESCRIPTION |
| * read record(s) from FAT. |
| * PARAMETERS |
| * filename [IN] full path of the data item |
| * rec_index [IN] which record to read (start) |
| * rec_amount [IN] how many record to read at once |
| * rec_size [IN] size of record |
| * buffer [IN/OUT] buffer of check sum |
| * type [IN] read content or checksum |
| * ismsp [IN] to indicate that the records protected by hw |
| * RETURNS |
| * = 0: success |
| * > 0: NVRAM error code |
| * < 0: FS error code |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_read( |
| kal_char *nvramname, |
| nvram_folder_enum nvram_folder, /* folder index */ |
| kal_uint32 file_offset, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| kal_uint8 *buffer, |
| nvram_drv_read_type_enum type, |
| nvram_ltable_entry_struct *ldi) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| FS_HANDLE hFile = 0; |
| kal_uint32 len = 0; |
| kal_int32 result = 0; |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| SGPT_CTRL_START_T start; |
| #endif |
| |
| #if (defined(__NVRAM_FS_OPERATION_COMPACT__) && defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__)) || defined(__NVRAM_FS_CMPT_SIMULATION__) |
| NVRAM_FS_PARAM_CMPT_T nvram_param = {0}; |
| #else |
| kal_int32 ret = 0; |
| #endif |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| /* NVRAM GPT timeout assert start timer */ |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| start.u2Tick= NVRAM_READ_GPT_TIMEOUT; |
| start.pfCallback=nvram_gpt_timeout_callback; |
| start.vPara=NULL; |
| #endif |
| |
| nvram_util_take_mutex(g_nvram_fs_mutex); |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start); //start timer |
| #endif |
| |
| do |
| { |
| if (rec_index < 1) |
| { |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error] invalid record index(%d) \r\n",rec_index); |
| break; |
| } |
| |
| nvram_query_file_name(nvram_folder, nvramname, filename); |
| |
| #if !defined(__NVRAM_FS_OPERATION_COMPACT__) || defined(__NVRAM_PSEUDO_MERGE__) || !((defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__)) || defined(__NVRAM_FS_CMPT_SIMULATION__)) |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| hFile = FS_Open((const kal_wchar*)filename, FS_READ_ONLY | FS_OPEN_NO_DIR | FS_OPEN_SHARED); |
| NVRAM_FS_END(FS_OP_OPEN,hFile); |
| if (hFile == FS_FILE_NOT_FOUND) |
| { |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_EMPTY_RECORD; |
| break; |
| } |
| else if (hFile <= FS_NO_ERROR) |
| { |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_FATAL_ERROR; |
| break; |
| } |
| |
| /* check if a empty record */ |
| NVRAM_FS_START(FS_OP_GETFILESIZE); |
| result = FS_GetFileSize(hFile, &len); |
| NVRAM_FS_END(FS_OP_GETFILESIZE,result); |
| if ((result == FS_NO_ERROR) && (len == 0)) |
| { |
| NVRAM_FS_START(FS_OP_CLOSE); |
| ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,ret); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_EMPTY_RECORD; |
| break; |
| } |
| |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, file_offset, FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_FS_START(FS_OP_CLOSE); |
| ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,ret); |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| |
| result = nvram_drv_fat_read_section(hFile, rec_index, rec_amount, rec_size, buffer, type, ldi); |
| if (hFile > FS_NO_ERROR) |
| { |
| NVRAM_FS_START(FS_OP_CLOSE); |
| ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,ret); |
| } |
| #else |
| nvram_param.opid_map = 0; |
| nvram_param.ret[0] = 0; |
| nvram_param.ret[1] = 0; |
| |
| nvram_param.Flag = (FS_READ_ONLY | FS_OPEN_NO_DIR | FS_OPEN_SHARED); |
| nvram_param.opid_map |= NVRAM_FS_CMPT_OPEN; |
| nvram_param.opid_map |= NVRAM_FS_CMPT_GETFILESIZE; |
| nvram_param.FileSize = &len; |
| nvram_param.Offset = file_offset; |
| result = nvram_drv_fat_read_section_cmpt(hFile, rec_index, rec_amount, rec_size, buffer, type, ldi,(kal_wchar*)filename, &nvram_param); |
| #endif |
| }while(0); |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_STOP, (DCL_CTRL_DATA_T*)NULL); //stop timer |
| #endif |
| |
| nvram_util_give_mutex(g_nvram_fs_mutex); |
| |
| #if !defined(__NVRAM_FS_OPERATION_COMPACT__) || defined(__NVRAM_PSEUDO_MERGE__) || !((defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__)) || defined(__NVRAM_FS_CMPT_SIMULATION__)) |
| if (result < FS_NO_ERROR) |
| { |
| nvram_fat_last_err = result; |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]result = %d ,last_err=%d,last_line=%d\r\n",result,nvram_fat_last_err,nvram_fat_last_line); |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| } |
| #else |
| if (nvram_param.opid_map != nvram_param.ret[0]) |
| { |
| nvram_fat_last_err = nvram_param.ret[1] || result; |
| nvram_fat_last_line = __LINE__; |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]result = %d last_err=%d,last_line=%d\r\n",result,nvram_fat_last_err,nvram_fat_last_line); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]nvram_param.opid_map(%d) != nvram_param.ret[0](%d)\r\n",nvram_param.opid_map,nvram_param.ret[0]); |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| |
| } |
| #endif |
| |
| return result; |
| } |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_read_exception_item |
| * DESCRIPTION |
| * read exception record from FAT. |
| * PARAMETERS |
| * buffer [?] |
| * nvramname [?] |
| * section_number [IN] |
| * size [IN] |
| * readsize [IN] |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| nvram_drv_status_enum nvram_drv_fat_read_exception_item(kal_uint8 *buffer, |
| kal_char *nvramname, |
| kal_uint16 section_number, |
| kal_uint32 size, |
| kal_uint32 readsize) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| FS_HANDLE hFile = 0; |
| kal_uint32 len = 0; |
| kal_int32 Ret; |
| kal_uint32 nvram_chksum_size = 0; |
| kal_char cfilename[NVRAM_FILE_LEN + 1] = {0}; |
| kal_wchar wcfilename[NVRAM_FILE_LEN + 1] = {0}; |
| nvram_ltable_entry_struct *ldi = NULL; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| if (section_number < 1) |
| { |
| /* kal_print("Nvram write: section_number < 1 !"); */ |
| return NVRAM_DRV_INVALID_RECORD_ID; |
| } |
| |
| /* translate record id to filename */ |
| nvram_query_file_name(NVRAM_NVD_DATA, nvramname, filename); |
| |
| nvram_query_file_name_by_path((kal_wchar *)filename, wcfilename); |
| kal_dchar2char((WCHAR *)wcfilename, cfilename); |
| nvram_util_get_data_item_by_fileprefix(&ldi, cfilename); |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| /* open NV_RCD.(RCD#) file */ |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| hFile = FS_Open((const kal_wchar*)filename, FS_READ_ONLY | FS_OPEN_NO_DIR); |
| NVRAM_FS_END(FS_OP_OPEN,hFile); |
| |
| if (hFile == FS_FILE_NOT_FOUND) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Open %s fail \r\n",__FUNCTION__,nvramname); |
| return NVRAM_DRV_EMPTY_RECORD; |
| } |
| else if (hFile <= FS_NO_ERROR) |
| { |
| /* kal_print("Nvram read: FS_Open return error!"); */ |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Open %s fail \r\n",__FUNCTION__,nvramname); |
| return NVRAM_DRV_FATAL_ERROR; |
| } |
| |
| /* check if a empty record */ |
| NVRAM_FS_START(FS_OP_GETFILESIZE); |
| Ret = FS_GetFileSize(hFile, &len); |
| NVRAM_FS_END(FS_OP_GETFILESIZE,Ret); |
| if ((Ret == FS_NO_ERROR) && (len == 0)) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_GetFileSize fail,result=%d \r\n",__FUNCTION__,Ret); |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| return NVRAM_DRV_EMPTY_RECORD; |
| } |
| |
| /* seek to the record start */ |
| NVRAM_FS_START(FS_OP_SEEK); |
| Ret = FS_Seek(hFile, (NVRAM_LDI_HEADER_SIZE + ((section_number - 1) * (size + nvram_chksum_size))), FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,Ret); |
| if (Ret >= FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek fail,result=%d \r\n",__FUNCTION__,Ret); |
| NVRAM_FS_START(FS_OP_READ); |
| Ret = FS_Read(hFile, buffer, (kal_uint32) readsize, &len); |
| NVRAM_FS_END(FS_OP_READ,Ret); |
| } |
| |
| if (Ret != FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Read fail,result=%d \r\n",__FUNCTION__,Ret); |
| /* kal_print("Nvram read: Read error!"); */ |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| return NVRAM_DRV_CHECKSUM_ERROR; |
| } |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| return NVRAM_DRV_OK; |
| } |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_prepare_data |
| * DESCRIPTION |
| * copy data into buffer |
| * PARAMETERS |
| * source: [IN] source data |
| * offset: [IN] offset in data |
| * buffer: [OUT] buffer |
| * buffer_size: [IN] size of buffer |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| void nvram_drv_fat_prepare_data(kal_uint8 *buffer, const kal_uint8 *source, kal_uint32 offset, kal_uint32 buffer_size) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| if (source == NVRAM_EF_ZERO_DEFAULT) |
| { |
| nvram_memset(buffer, 0x00, buffer_size); |
| } |
| else if (source == NVRAM_EF_FF_DEFAULT) |
| { |
| nvram_memset(buffer, 0xFF, buffer_size); |
| } |
| else |
| { |
| kal_mem_cpy(buffer, source+offset, buffer_size); |
| } |
| } |
| |
| #ifdef __NVRAM_WRITE_WITH_FILE_SIZE__ |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_write_multiple |
| * DESCRIPTION |
| * write record(s) to FAT. |
| * PARAMETERS |
| * hFile [?] |
| * buffer [?] |
| * rec_amount [IN] |
| * rec_size [IN] |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_write_multiple( |
| FS_HANDLE hFile, |
| const kal_uint8 *buffer, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| nvram_ltable_entry_struct *ldi) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_uint32 len = 0, remainLen = 0; |
| kal_uint8 *chksum = NULL; |
| kal_uint32 max_rec_amount; |
| kal_uint32 section_size; |
| kal_uint32 working_buffer_size; |
| kal_uint8 *working_buffer = NULL; |
| kal_int32 result = NVRAM_DRV_OK; |
| kal_uint32 i; |
| kal_uint32 rec_in_block; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| kal_uint32 cache_offset = 0; |
| kal_uint32 temp_cache_offset = 0; |
| kal_uint16 temp_rec_index = rec_index; |
| #endif |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP, "[NVUT_UTIL_CAL]%s():%d NVRAM chksize %d \n\r", __FUNCTION__, __LINE__,nvram_chksum_size); |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if ((ldi->attr & NVRAM_ATTR_MSP)||(ldi->attr & NVRAM_ATTR_CONFIDENTIAL)) |
| { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| } |
| #else |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| } |
| #endif |
| |
| //16bytes alignment, limitation: msp data will be oversize |
| section_size = rec_size + nvram_chksum_size + remainLen; |
| working_buffer_size = section_size * rec_amount; |
| |
| if (rec_index > 1) |
| { |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, (rec_index - 1) * section_size, FS_FILE_CURRENT); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek fail,result=%d\r\n",__FUNCTION__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| } |
| |
| if (working_buffer_size > MAX_NVRAM_RECORD_SIZE) |
| { |
| working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| } |
| |
| working_buffer = (kal_uint8*) get_ctrl_buffer(working_buffer_size); |
| max_rec_amount = working_buffer_size/section_size; |
| chksum = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size); |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| cache_offset = 0; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->get_lid_record_cache_offset fail,result=%d\r\n",__FUNCTION__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| } |
| temp_cache_offset = cache_offset; |
| #endif |
| |
| if (!(ldi->attr & NVRAM_ATTR_MSP) && !(ldi->attr & NVRAM_ATTR_CONFIDENTIAL) && |
| buffer != NVRAM_EF_ZERO_DEFAULT && buffer != NVRAM_EF_FF_DEFAULT) |
| { |
| for(i = 0; i < rec_amount; i++) |
| { |
| if (ldi->attr & NVRAM_ATTR_MULTI_DEFAULT) |
| { |
| //rec_index start from 1 |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, buffer + (i+rec_index-1)*rec_size, rec_size,chksum); |
| kal_mem_cpy(working_buffer + i*(rec_size + nvram_chksum_size), buffer + (i+rec_index-1)*rec_size, rec_size); |
| kal_mem_cpy(working_buffer + i*(rec_size + nvram_chksum_size)+rec_size, chksum, nvram_chksum_size); |
| } |
| else |
| { |
| if (i==0) |
| { |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, buffer, rec_size,chksum); |
| } |
| kal_mem_cpy(working_buffer + i*(rec_size + nvram_chksum_size), buffer, rec_size); |
| kal_mem_cpy(working_buffer + i*(rec_size + nvram_chksum_size)+rec_size, chksum, nvram_chksum_size); |
| } |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| |
| if (i == (rec_amount - 1)) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, working_buffer, section_size * rec_amount, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail,result=%d\r\n",__FUNCTION__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| nvram_write_data_to_cache(ldi, working_buffer, section_size * rec_amount, cache_offset); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index, rec_amount); |
| } |
| #endif |
| } |
| } |
| goto final; |
| } |
| |
| rec_in_block = 0; |
| max_rec_amount = working_buffer_size / section_size; |
| |
| for (i = 0; i < rec_amount; i ++) |
| { |
| nvram_drv_fat_prepare_data(working_buffer + rec_in_block * section_size, buffer, (i+rec_index-1) * rec_size, rec_size); |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, working_buffer + rec_in_block * section_size, rec_size, chksum); |
| |
| kal_mem_cpy(working_buffer + rec_in_block * section_size + rec_size, chksum, nvram_chksum_size); |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| |
| if (remainLen) |
| { |
| kal_mem_set(working_buffer + rec_in_block * section_size + rec_size + nvram_chksum_size , 0x00, remainLen); |
| } |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| //custom_nvram_encrypt(nvram_ptr->secret_key, working_buffer + rec_in_block * section_size, rec_size, rec_size); |
| nvram_AES_encrypt(working_buffer + rec_in_block * section_size, section_size); |
| } |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if (ldi->attr & NVRAM_ATTR_MSP) |
| { |
| /* this solution is only for work arround */ |
| #if (defined(__SMART_PHONE_MODEM__) || defined(__CCCIFS_SUPPORT__)) |
| kal_uint8 *working_buffer2 = (kal_uint8*) get_ctrl_buffer(section_size); |
| kal_uint8 *working_buffer3 = (kal_uint8*) get_ctrl_buffer(section_size); |
| |
| //copy the original data from working_buffer to working_buffer2 |
| memcpy(working_buffer2, working_buffer + rec_in_block * section_size, section_size); |
| |
| do |
| { |
| nvram_trace_to_file(__LINE__, 999, 0, 0, 0, 0); |
| nvram_trace_to_file(nvram_ptr->secret_key[0], nvram_ptr->secret_key[1], nvram_ptr->secret_key[2], nvram_ptr->secret_key[3], 0, 0); |
| nvram_trace_to_file(working_buffer[rec_in_block*section_size], working_buffer[rec_in_block*section_size + 1], working_buffer[rec_in_block*section_size + 2], working_buffer[rec_in_block*section_size + 3], 0, 0); |
| |
| //encrypt working_buffer |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer + rec_in_block * section_size, section_size, nvram_ptr->secret_key, working_buffer + rec_in_block * section_size); |
| nvram_trace_to_file(working_buffer[rec_in_block*section_size], working_buffer[rec_in_block*section_size + 1], working_buffer[rec_in_block*section_size + 2], working_buffer[rec_in_block*section_size + 3], 0, 0); |
| |
| //copy the encrypted data from working_buffer to working_buffer3 |
| memcpy(working_buffer3, working_buffer + rec_in_block * section_size, section_size); |
| //decrypt the working_buffer3 |
| SST_Secure_Algo(NVRAM_MSP_DECRYPT, (kal_uint32)working_buffer3, section_size, nvram_ptr->secret_key, working_buffer3); |
| |
| //compare the data between the working_buffer2 & working_buffer3 |
| if (memcmp(working_buffer2, working_buffer3, section_size) == 0) |
| { |
| //encrypt PASS |
| break; |
| } |
| else |
| { |
| //encrypt FAIL, try again, WTF |
| memcpy(working_buffer + rec_in_block * section_size, working_buffer2, section_size); |
| } |
| }while(1); |
| |
| free_ctrl_buffer(working_buffer2); |
| free_ctrl_buffer(working_buffer3); |
| working_buffer2 = NULL; |
| working_buffer3 = NULL; |
| #else |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer + rec_in_block * section_size, section_size, nvram_ptr->secret_key, working_buffer + rec_in_block * section_size); |
| |
| #endif |
| } |
| #endif |
| |
| /* if this is not multi default, no need to prepare data anymore */ |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| break; |
| } |
| |
| rec_in_block ++; |
| |
| if (rec_in_block == max_rec_amount || i == rec_amount - 1) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, working_buffer, section_size * rec_in_block, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail,result=%d\r\n",__FUNCTION__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| nvram_write_data_to_cache(ldi, working_buffer, section_size * rec_in_block, temp_cache_offset); |
| mask_valid_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| |
| temp_cache_offset += section_size * rec_in_block; |
| temp_rec_index += rec_in_block; |
| } |
| #endif |
| |
| rec_in_block = 0; |
| } |
| } |
| |
| /* special handling for not multi default */ |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| for (i = 0; i < rec_amount; i++) |
| { |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) |
| { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)(working_buffer+rec_size), nvram_chksum_size); |
| } |
| |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, working_buffer, section_size, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail,result=%d\r\n",__FUNCTION__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| temp_cache_offset = cache_offset + section_size * i; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| nvram_write_data_to_cache(ldi, working_buffer, section_size, temp_cache_offset); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index+i, 1); |
| } |
| #endif |
| } |
| } |
| |
| final: |
| |
| if (working_buffer) |
| { |
| free_ctrl_buffer(working_buffer); |
| working_buffer = NULL; |
| } |
| |
| if (chksum) |
| { |
| free_ctrl_buffer(chksum); |
| chksum = NULL; |
| } |
| |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_err = result; |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| return result; |
| } |
| |
| return NVRAM_DRV_OK; |
| } |
| #endif |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_write_section |
| * DESCRIPTION |
| * write record(s) to FAT. |
| * PARAMETERS |
| * buffer [?] |
| * nvramname [?] |
| * section_number [IN] |
| * size [IN] |
| * initialize [IN] true for reset, false for normal write. |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_write_section( |
| FS_HANDLE hFile, |
| const kal_uint8 *buffer, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| nvram_ltable_entry_struct *ldi, |
| kal_uint32 filesize) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_uint32 len = 0, remainLen = 0; |
| kal_uint8 *chksum = NULL; |
| kal_uint32 max_rec_amount; |
| kal_uint32 section_size; |
| kal_uint32 working_buffer_size; |
| kal_uint8 *working_buffer = NULL; |
| kal_int32 result = NVRAM_DRV_OK; |
| kal_bool encrypt_data = KAL_FALSE; |
| kal_uint32 i; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| kal_uint32 cache_offset = 0; |
| kal_uint32 temp_cache_offset = 0; |
| kal_uint16 temp_rec_index = rec_index; |
| #endif |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if ((ldi->attr & NVRAM_ATTR_MSP)||(ldi->attr & NVRAM_ATTR_CONFIDENTIAL)) |
| { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| encrypt_data = KAL_TRUE; |
| } |
| #else |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| encrypt_data = KAL_TRUE; |
| } |
| #endif |
| |
| section_size = rec_size + nvram_chksum_size + remainLen; |
| working_buffer_size = section_size * rec_amount; |
| if (working_buffer_size > MAX_NVRAM_RECORD_SIZE) |
| { |
| working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| } |
| |
| working_buffer = (kal_uint8*) get_ctrl_buffer(working_buffer_size); |
| chksum = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size); |
| |
| if (rec_index > 1 && rec_amount == 1) |
| { |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, (rec_index - 1) * section_size, FS_FILE_CURRENT); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| } |
| |
| /* we can write data into FS directly, we don't need another buffer*/ |
| if (!(ldi->attr & NVRAM_ATTR_MSP) && !(ldi->attr & NVRAM_ATTR_CONFIDENTIAL) && |
| #if defined(__MTK_TARGET__) && defined(__NVRAM_IMPORTANT_PARTITIONS__) |
| !(ldi->attr & NVRAM_ATTR_COMMITTED) && |
| #endif |
| buffer != NVRAM_EF_ZERO_DEFAULT && buffer != NVRAM_EF_FF_DEFAULT) |
| { |
| #ifdef __NVRAM_LID_CACHE__ |
| cache_offset = 0; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->get_lid_record_cache_offset fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| } |
| #endif |
| for(i = 0;i < rec_amount;i++) |
| { |
| nvram_memset(working_buffer, (kal_uint8) NVRAM_EF_ZERO_DEFAULT_VALUE, working_buffer_size); |
| if ((i == 0 || (ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) && |
| !NVRAM_IS_ATTR_RAW_DATA(ldi->attr) ) |
| { |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, buffer + i * rec_size, rec_size, chksum); |
| } |
| |
| if (ldi->attr & NVRAM_ATTR_MULTI_DEFAULT) |
| { |
| if (NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, (void *)(buffer + i * rec_size), rec_size, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| } |
| else |
| { |
| kal_mem_cpy(working_buffer, (void *)(buffer + i * rec_size), rec_size); |
| } |
| } |
| else |
| { |
| if (NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, (void *)buffer, rec_size, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| } |
| else |
| { |
| kal_mem_cpy(working_buffer, (void *)buffer, rec_size); |
| } |
| } |
| if (NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) { |
| goto final; |
| } |
| //write data & checksum |
| kal_mem_cpy((void *)(working_buffer + rec_size), (void *)chksum, nvram_chksum_size); |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, working_buffer, section_size, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| if(NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| nvram_write_data_to_cache(ldi, working_buffer, section_size, (cache_offset + i * section_size)); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| } |
| #endif |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| } |
| goto final; |
| } |
| |
| //working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| //MAX_NVRAM_RECORD_SIZE = (NVRAM_CUSTOM_CFG_MAX_RECORD_SECTOR_NUM * NVRAM_RECORD_SECTOR_SIZE) |
| // = (16 or 4) * 512 |
| |
| #ifdef __NVRAM_LARGE_RECORD_SIZE__ |
| /* size too large , we need to operate block by block */ |
| if (section_size > working_buffer_size) |
| { |
| /* we need to prepare extra working buffer; |
| and due to msp need 16-bytes alignment, therefore |
| we set the working buffer to 16-bytes alignment also */ |
| kal_uint8 *tmpchksum = NULL; |
| |
| kal_int32 j,cs_idx; |
| |
| working_buffer_size = NVRAM_MSP_ALIGNMENT_FLOOR(working_buffer_size) - NVRAM_MSP_ALIGNMENT; |
| tmpchksum = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size); |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| cache_offset = 0; |
| temp_cache_offset = 0; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->get_lid_record_cache_offset fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| if (tmpchksum) |
| { |
| free_ctrl_buffer(tmpchksum); |
| tmpchksum = NULL; |
| } |
| goto final; |
| } |
| } |
| #endif |
| |
| for (i = 0 ; i < rec_amount; i++) |
| { |
| #ifdef __NVRAM_LID_CACHE__ |
| temp_cache_offset = cache_offset + i*section_size; |
| #endif |
| for (j = 0; j < rec_size; j += working_buffer_size) |
| { |
| kal_int32 byte_in_block = rec_size - j; |
| kal_bool last_block = KAL_FALSE; |
| |
| if (byte_in_block > working_buffer_size) |
| { |
| byte_in_block = working_buffer_size; |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| nvram_drv_fat_prepare_data(working_buffer, buffer, j, byte_in_block); |
| } |
| else |
| { |
| nvram_drv_fat_prepare_data(working_buffer, buffer, i * rec_size + j, byte_in_block); |
| } |
| } |
| else /* last block */ |
| { |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| nvram_drv_fat_prepare_data(working_buffer, buffer, j, byte_in_block); |
| } |
| else |
| { |
| nvram_drv_fat_prepare_data(working_buffer, buffer, i * rec_size + j, byte_in_block); |
| } |
| last_block = KAL_TRUE; |
| } |
| |
| if (i == 0 || ldi->attr & NVRAM_ATTR_MULTI_DEFAULT) |
| { |
| if (j == 0) |
| { |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| } |
| kal_mem_set(tmpchksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, working_buffer, byte_in_block, tmpchksum); |
| for(cs_idx= 0; cs_idx < nvram_chksum_size;cs_idx++){ |
| chksum[cs_idx] += tmpchksum[cs_idx]; |
| } |
| } |
| |
| /* last block */ |
| if (last_block) |
| { |
| kal_mem_cpy(working_buffer + byte_in_block, chksum, nvram_chksum_size); |
| kal_mem_set(working_buffer + byte_in_block + nvram_chksum_size, 0, remainLen); |
| byte_in_block += (nvram_chksum_size + remainLen); |
| } |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| //custom_nvram_encrypt(nvram_ptr->secret_key, working_buffer, byte_in_block, rec_size); |
| nvram_AES_encrypt(working_buffer, byte_in_block); |
| } |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if (ldi->attr & NVRAM_ATTR_MSP) |
| { |
| |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer, byte_in_block, nvram_ptr->secret_key, working_buffer); |
| } |
| #endif |
| |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, working_buffer, byte_in_block, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| if (tmpchksum) |
| { |
| free_ctrl_buffer(tmpchksum); |
| tmpchksum = NULL; |
| } |
| goto final; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| nvram_write_data_to_cache(ldi, working_buffer, byte_in_block, temp_cache_offset); |
| temp_cache_offset = temp_cache_offset + byte_in_block; |
| } |
| #endif |
| } |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| mask_valid_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| } |
| #endif |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| } |
| if (tmpchksum) |
| { |
| free_ctrl_buffer(tmpchksum); |
| tmpchksum = NULL; |
| } |
| } |
| else |
| #endif |
| { |
| kal_uint32 rec_in_block = 0; |
| |
| max_rec_amount = working_buffer_size / section_size; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| cache_offset = 0; |
| temp_cache_offset = 0; |
| temp_rec_index = rec_index; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) |
| { |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| } |
| #endif |
| |
| for (i = 0; i < rec_amount ; i ++) |
| { |
| /* |
| * Write several record at once to reduce io Write |
| * case a: all remain record |
| * section_number - i |
| * case b: max record we can write in one time |
| * max_rec_amount |
| * check which case is smaller |
| */ |
| |
| nvram_drv_fat_prepare_data(working_buffer + rec_in_block * section_size, buffer, i * rec_size, rec_size); |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, working_buffer + rec_in_block * section_size, rec_size, chksum); |
| |
| kal_mem_cpy(working_buffer + rec_in_block * section_size + rec_size, chksum, nvram_chksum_size); |
| |
| if (remainLen) |
| { |
| kal_mem_set(working_buffer + rec_in_block * section_size + rec_size + nvram_chksum_size , 0x00, remainLen); |
| } |
| |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bWriteMsp == 1){ |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_W,working_buffer,NVRAM_MSP_TEST_LEN); |
| } |
| #endif |
| nvram_AES_encrypt(working_buffer + rec_in_block * section_size, section_size); |
| |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bWriteMsp == 1){ |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_W[NVRAM_MSP_TEST_LEN],working_buffer,NVRAM_MSP_TEST_LEN); |
| } |
| #endif |
| } |
| |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if (ldi->attr & NVRAM_ATTR_MSP) |
| { |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer + rec_in_block * section_size, section_size, nvram_ptr->secret_key, working_buffer + rec_in_block * section_size); |
| } |
| #endif |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| |
| /* if this is not multi default, no need to prepare data anymore */ |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| break; |
| } |
| rec_in_block ++; |
| |
| if (rec_in_block == max_rec_amount || i == rec_amount - 1) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, working_buffer, section_size * rec_in_block, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| nvram_write_data_to_cache(ldi, working_buffer, section_size * rec_in_block, cache_offset); |
| mask_valid_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| |
| cache_offset += section_size * rec_in_block; |
| temp_rec_index += rec_in_block; |
| } |
| #endif |
| |
| rec_in_block = 0; |
| } |
| } |
| |
| |
| /* special handling for not multi default */ |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| /* special handling for NVRAM_EF_ZERO_DEFAULT write speed up*/ |
| if((buffer == NVRAM_EF_ZERO_DEFAULT) && |
| (filesize <= NVRAM_LDI_HEADER_SIZE) && |
| !encrypt_data ) |
| { |
| #ifdef __NVRAM_LID_CACHE__ |
| temp_rec_index = rec_index; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset); |
| } |
| #endif |
| |
| for(i = 0; i < rec_amount; i++) { |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, rec_size, FS_FILE_CURRENT); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if(FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, (working_buffer + rec_size), nvram_chksum_size, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| temp_cache_offset = cache_offset + i* section_size; |
| nvram_write_data_to_cache(ldi, working_buffer, section_size, temp_cache_offset); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| } |
| #endif |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)(working_buffer + rec_size), nvram_chksum_size); |
| } |
| } |
| goto final; |
| } |
| |
| if (rec_amount > 1) |
| { |
| for (i = 1; i < max_rec_amount && i < rec_amount; i++) |
| { |
| kal_mem_cpy(working_buffer + section_size * i, working_buffer, section_size); |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)(working_buffer+rec_size), nvram_chksum_size); |
| } |
| } |
| } |
| |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bWriteMsp == 1) |
| { |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_W[NVRAM_MSP_TEST_LEN*2],working_buffer,NVRAM_MSP_TEST_LEN); |
| nvram_create_report_msp_file(KAL_TRUE); |
| } |
| #endif |
| #ifdef __NVRAM_LID_CACHE__ |
| temp_rec_index = rec_index; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset); |
| } |
| temp_cache_offset = cache_offset; |
| #endif |
| |
| for (i = 0 ; i < rec_amount ; i += max_rec_amount) |
| { |
| rec_in_block = (rec_amount - i) > max_rec_amount ? max_rec_amount: (rec_amount - i); |
| |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, working_buffer, section_size * rec_in_block, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Write fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| nvram_write_data_to_cache(ldi, working_buffer, section_size * rec_in_block, temp_cache_offset); |
| mask_valid_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| |
| temp_rec_index = temp_rec_index + rec_in_block; |
| temp_cache_offset = cache_offset + section_size * rec_in_block; |
| } |
| #endif |
| } |
| } |
| |
| } |
| |
| |
| |
| |
| final: |
| |
| if (working_buffer) |
| { |
| free_ctrl_buffer(working_buffer); |
| } |
| |
| if (chksum) |
| { |
| free_ctrl_buffer(chksum); |
| chksum = NULL; |
| } |
| |
| if (FS_NO_ERROR > result) |
| { |
| nvram_fat_last_err = result; |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| return result; |
| } |
| |
| return NVRAM_DRV_OK; |
| } |
| |
| #ifdef __NVRAM_WRITE_WITH_FILE_SIZE__ |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_write_multRec |
| * DESCRIPTION |
| * write record(s) to FAT,now it only used at initiation stage |
| * PARAMETERS |
| * buffer [?] |
| * nvramname [?] |
| * section_number [IN] |
| * size [IN] |
| * initialize [IN] true for reset, false for normal write. |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| nvram_drv_status_enum nvram_drv_fat_write_multRec(nvram_ltable_entry_struct *ldi, |
| kal_char *nvramname, |
| nvram_folder_enum nvram_folder, |
| kal_uint32 file_offset, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| const kal_uint8 *buffer, |
| kal_bool initialize) |
| { |
| kal_int32 result = FS_NO_ERROR; |
| kal_int32 ret = FS_NO_ERROR; |
| #ifdef __NVRAM_LID_CACHE__ |
| if(NVRAM_WR_WITH_CACHE(ldi->LID) && (!(NVRAM_IS_ATTR_RAW_DATA(ldi->attr)))) |
| { |
| result = nvram_drv_fat_write_multiRec_to_cache(buffer, rec_index, rec_amount, rec_size, ldi); |
| } |
| else |
| #endif |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| FS_HANDLE hFile = 0; |
| |
| kal_uint32 openOption = FS_READ_WRITE | FS_OPEN_NO_DIR; |
| kal_uint32 len; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| SGPT_CTRL_START_T start; |
| #endif |
| nvram_ldi_ota_header ota_header; |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| kal_uint32 cache_offset = 0; |
| #endif |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| /* NVRAM GPT timeout assert start timer */ |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| start.u2Tick= NVRAM_WRITE_GPT_TIMEOUT; |
| start.pfCallback=nvram_gpt_timeout_callback; |
| start.vPara=NULL; |
| #endif |
| |
| nvram_util_take_mutex(g_nvram_fs_mutex); |
| |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start); //start timer |
| #endif |
| |
| do |
| { |
| if (rec_index < 1 || rec_amount < 1) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index=%d,rec_amount=%d\r\n",rec_index,rec_amount); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| break; |
| } |
| |
| /* translate record id to filename */ |
| nvram_query_file_name(nvram_folder, nvramname, filename); |
| |
| /* set the attribute to empty before write data |
| sometime the files may be read only if the nvram lock is turn on |
| ex: software update when nvram lock is turned on |
| But it is not a good solution here, we should unlock it in io layer */ |
| |
| |
| openOption |= FS_CREATE; |
| #if (defined(__SMART_PHONE_MODEM__) || defined(__CCCIFS_SUPPORT__)) && defined(__MTK_TARGET__) |
| if (ldi->attr & NVRAM_ATTR_COMMITTED) |
| { |
| openOption |= FS_COMMITTED; |
| } |
| #endif |
| //Get appdenix header info |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) { |
| ldi->append_buffer = get_ctrl_buffer(rec_amount * nvram_chksum_size); |
| } |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| hFile = FS_Open((const kal_wchar*)filename, openOption); |
| NVRAM_FS_END(FS_OP_OPEN,hFile); |
| |
| if (hFile == FS_FILE_NOT_FOUND) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Open %s fail\r\n",__FUNCTION__,nvramname); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]Fail at %d,FS_FILE_NOT_FOUND result=%d\r\n",__LINE__,hFile); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_EMPTY_RECORD; |
| break; |
| } |
| else if (hFile <= FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Open %s fail\r\n",__FUNCTION__,nvramname); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]Fail at %d,result=%d\r\n",__LINE__,hFile); |
| nvram_fat_last_line = __LINE__; |
| result = hFile; |
| break; |
| } |
| if (!nvram_util_has_file_created(ldi)) |
| { |
| kal_uint32 ldi_hd_buffer_size = 0; |
| kal_uint8 ldi_hd_buffer[NVRAM_LDI_HEADER_SIZE] = {0}; |
| //prepare header data and write header |
| nvram_prepare_data_header(ldi, ldi_hd_buffer); |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, ldi_hd_buffer, NVRAM_LDI_HEADER_SIZE, &ldi_hd_buffer_size); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (result < FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Write fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| cache_offset = 0; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| get_lid_cache_base_address(ldi, &cache_offset); |
| nvram_write_data_to_cache(ldi, (void *)ldi_hd_buffer, NVRAM_LDI_HEADER_SIZE, cache_offset); |
| mask_valid_bit_by_ltable_entry(ldi, 0, 1); |
| } |
| #endif |
| } |
| else |
| { |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, file_offset, FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if (file_offset && FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Seek fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| } |
| result = nvram_drv_fat_write_multiple(hFile, buffer, rec_index, rec_amount, rec_size, ldi); |
| }while(0); |
| |
| //write-back appdenix header info |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) { |
| //Write appendix header |
| kal_mem_set(&ota_header, 0, NVRAM_LDI_APPENDIX_HEADER_SIZE); |
| nvram_prepare_appendix_header(NVRAM_APPEND_TYPE_CHKSUM, (nvram_ldi_appendix_header*)(&ota_header), ldi, NVRAM_LDI_APPENDIX_HEADER_SIZE); |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, ldi->append_offset, FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, &ota_header, NVRAM_LDI_APPENDIX_HEADER_SIZE, &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| if (result < FS_NO_ERROR) { |
| kal_prompt_trace(MOD_NVRAM, "NVRAM appendix header write fail:0x%x\n\r", result); |
| kal_prompt_trace(MOD_NVRAM, "category:0x%x, attr:0x%x\n\r", ldi->category, ldi->attr); |
| kal_prompt_trace(MOD_NVRAM, "fileprefix:%s, fileverno:%s\n\r", ldi->fileprefix, ldi->fileverno); |
| |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"NVRAM appendix header write fail:0x%x\r\n", result); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"LID 0x%04X,category:0x%08X, attr:0x%08X\r\n",ldi->LID, ldi->category, ldi->attr); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"fileprefix:%s, fileverno:%s\r\n", ldi->fileprefix, ldi->fileverno); |
| if(NVRAM_IS_ATTR_FAULT_ASSERT(ldi->attr)) { |
| if(ldi->append_buffer) { |
| free_ctrl_buffer(ldi->append_buffer); |
| ldi->append_buffer = NULL; |
| } |
| NVRAM_FS_START(FS_OP_CLOSE); |
| result = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,result); |
| NVRAM_EXT_ASSERT(KAL_FALSE, (kal_uint32)hFile, NVRAM_LOC_WRITE_FILE_FAIL_4, ldi->LID, result); |
| } |
| } |
| #ifdef __NVRAM_LID_CACHE__ |
| else |
| { |
| cache_offset = 0; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| get_lid_cache_base_address(ldi, &cache_offset); |
| cache_offset = cache_offset + ldi->append_offset; |
| nvram_write_data_to_cache(ldi, (void *)&ota_header, NVRAM_LDI_APPENDIX_HEADER_SIZE, cache_offset); |
| } |
| } |
| #endif |
| |
| //Write appendix info |
| if(ldi->append_offset == 0) { |
| kal_mem_set(&ota_header, 0, NVRAM_LDI_OTA_HEADER_SIZE); |
| #if defined(__NVRAM_LID_CACHE__) && (defined(__NVRAM_LID_PREREAD__) || defined(__NVRAM_CACHE_BYPASS_W_LIST__)) |
| if(KAL_TRUE == nvram_cache_read_ota_header(filename, hFile, &ota_header, NVRAM_LDI_OTA_HEADER_SIZE) && |
| (ota_header.ldi_attr & NVRAM_ATTR_CHKSUM_INTEGRATE) ) |
| #else |
| if(KAL_TRUE == nvram_read_ota_header(hFile, &ota_header, NVRAM_LDI_OTA_HEADER_SIZE) && |
| (ota_header.ldi_attr & NVRAM_ATTR_CHKSUM_INTEGRATE) ) |
| #endif |
| { |
| ldi->append_offset = nvram_appendix_header_offset(ldi); |
| } |
| else { |
| ldi->append_offset = -1; |
| } |
| } |
| if(ldi->append_offset > 0) { |
| NVRAM_FS_START(FS_OP_SEEK); |
| ret = FS_Seek(hFile, (ldi->append_offset + NVRAM_LDI_APPENDIX_HEADER_SIZE + ((rec_index - 1) * nvram_chksum_size)), FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,ret); |
| NVRAM_FS_START(FS_OP_WRITE); |
| ret = FS_Write(hFile, ldi->append_buffer, (rec_amount * nvram_chksum_size), &len); |
| NVRAM_FS_END(FS_OP_WRITE,ret); |
| #ifdef __NVRAM_LID_CACHE__ |
| cache_offset = 0; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| get_lid_cache_base_address(ldi, &cache_offset); |
| cache_offset = cache_offset + (ldi->append_offset + NVRAM_LDI_APPENDIX_HEADER_SIZE + ((rec_index - 1) * nvram_chksum_size)); |
| nvram_write_data_to_cache(ldi, (kal_uint8*)ldi->append_buffer, (rec_amount * nvram_chksum_size), cache_offset); |
| } |
| #endif |
| } |
| if(ldi->append_buffer) { |
| free_ctrl_buffer(ldi->append_buffer); |
| ldi->append_buffer = NULL; |
| } |
| } |
| |
| if (hFile > FS_NO_ERROR) |
| { |
| NVRAM_FS_START(FS_OP_CLOSE); |
| ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,ret); |
| } |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_STOP, (DCL_CTRL_DATA_T*)NULL); //stop timer |
| #endif |
| |
| nvram_util_give_mutex(g_nvram_fs_mutex); |
| |
| /* Set the attribute back to original attribute */ |
| if (result < FS_NO_ERROR) |
| { |
| nvram_fat_last_err = result; |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| } |
| } |
| return result; |
| } |
| #endif |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_write |
| * DESCRIPTION |
| * write record(s) to FAT. |
| * PARAMETERS |
| * buffer [?] |
| * nvramname [?] |
| * section_number [IN] |
| * size [IN] |
| * initialize [IN] true for reset, false for normal write. |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| nvram_drv_status_enum nvram_drv_fat_write(kal_char *nvramname, |
| nvram_folder_enum nvram_folder, |
| kal_uint32 file_offset, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| const kal_uint8 *buffer, |
| nvram_ltable_entry_struct *ldi, |
| kal_bool initialize) |
| { |
| |
| kal_int32 result = FS_NO_ERROR; |
| kal_int32 Ret = FS_NO_ERROR; |
| #ifdef __NVRAM_LID_CACHE__ |
| if(NVRAM_WR_WITH_CACHE(ldi->LID) && (!(NVRAM_IS_ATTR_RAW_DATA(ldi->attr)))) |
| { |
| result = nvram_drv_fat_write_cache_section(buffer, rec_index, rec_amount, rec_size, ldi); |
| } |
| else |
| #endif |
| { |
| |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| FS_HANDLE hFile = 0; |
| kal_uint32 openOption = FS_READ_WRITE | FS_OPEN_NO_DIR; |
| kal_uint32 len; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| SGPT_CTRL_START_T start; |
| #endif |
| nvram_ldi_ota_header ota_header; |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| /* NVRAM GPT timeout assert start timer */ |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| start.u2Tick= NVRAM_WRITE_GPT_TIMEOUT; |
| start.pfCallback=nvram_gpt_timeout_callback; |
| start.vPara=NULL; |
| #endif |
| |
| nvram_util_take_mutex(g_nvram_fs_mutex); |
| |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start); //start timer |
| #endif |
| |
| do |
| { |
| if (rec_index < 1 || rec_amount < 1) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d,\r\n",__FUNCTION__,__LINE__); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]rec_index=%d,rec_amount=%d\r\n",rec_index,rec_amount); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| break; |
| } |
| |
| /* translate record id to filename */ |
| nvram_query_file_name(nvram_folder, nvramname, filename); |
| |
| /* set the attribute to empty before write data |
| sometime the files may be read only if the nvram lock is turn on |
| ex: software update when nvram lock is turned on |
| But it is not a good solution here, we should unlock it in io layer */ |
| |
| |
| openOption |= FS_CREATE; |
| if (initialize != KAL_TRUE) |
| { |
| #if !defined(_NAND_FLASH_BOOTING_) && !defined(__FS_SYSDRV_ON_NAND__) && !defined(__EMMC_BOOTING__) |
| openOption |= FS_PROTECTION_MODE; /* boot from NAND and single bank NOR don't support this */ |
| #endif |
| } |
| |
| #if defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__) |
| if (ldi->attr & NVRAM_ATTR_COMMITTED) |
| { |
| openOption |= FS_COMMITTED; |
| } |
| #endif |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| hFile = FS_Open((const kal_wchar*)filename, openOption); |
| NVRAM_FS_END(FS_OP_OPEN,hFile); |
| |
| if (hFile == FS_FILE_NOT_FOUND) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Open %s fail\r\n",__FUNCTION__,nvramname); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]Fail at %d,FS_FILE_NOT_FOUND hFile=%d\r\n",__LINE__,hFile); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_EMPTY_RECORD; |
| break; |
| } |
| else if (hFile <= FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Open %s fail \r\n",__FUNCTION__,nvramname); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]Fail at %d,hFile=%d\r\n",__LINE__,hFile); |
| nvram_fat_last_line = __LINE__; |
| result = hFile; |
| break; |
| } |
| |
| //Get appdenix header info |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) { |
| ldi->append_buffer = get_ctrl_buffer(rec_amount * nvram_chksum_size); |
| } |
| |
| if (file_offset) |
| { |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, file_offset, FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if(FS_NO_ERROR > result){ |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| } |
| |
| /* try to write one record in file, but found the file size is zero. strange ! */ |
| if (!(ldi->attr & NVRAM_ATTR_BACKUP_RAW) && |
| !NVRAM_IS_ATTR_RAW_DATA(ldi->attr) && |
| !initialize |
| ) //only have header, fill content is NULL |
| { |
| NVRAM_FS_START(FS_OP_GETFILESIZE); |
| result = FS_GetFileSize(hFile, &len); |
| NVRAM_FS_END(FS_OP_GETFILESIZE,result); |
| if( result == FS_NO_ERROR && (len <= NVRAM_LDI_HEADER_SIZE)){ |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_GetFileSize fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_EMPTY_RECORD; |
| #if defined(__NVRAM_WRITE_PROTECT_ENABLE__) && defined(__NVRAM_IMPORTANT_PARTITIONS__) && defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__) |
| if(nvram_folder != NVRAM_NVD_IMPNT2) |
| { |
| // Permit to write Y: as the important_l4 data is maybe deleted manualy |
| break; |
| } |
| #else |
| break; |
| #endif |
| } |
| } |
| |
| /* Fast reset need to know whether file be written */ |
| if (!(ldi->attr & NVRAM_ATTR_BACKUP_RAW) && |
| !NVRAM_IS_ATTR_RAW_DATA(ldi->attr) && |
| initialize && |
| (buffer == NVRAM_EF_ZERO_DEFAULT)) |
| { |
| NVRAM_FS_START(FS_OP_GETFILESIZE); |
| result = FS_GetFileSize(hFile, &len); |
| NVRAM_FS_END(FS_OP_GETFILESIZE,result); |
| } |
| |
| result = nvram_drv_fat_write_section(hFile, buffer, rec_index, rec_amount, rec_size, ldi, len); |
| }while(0); |
| |
| //write-back appdenix header info |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) { |
| if(ldi->append_offset == 0) { |
| #if defined(__NVRAM_LID_CACHE__) && (defined(__NVRAM_LID_PREREAD__) || defined(__NVRAM_CACHE_BYPASS_W_LIST__)) |
| if(KAL_TRUE == nvram_cache_read_ota_header(filename, hFile, &ota_header, NVRAM_LDI_OTA_HEADER_SIZE) && |
| (ota_header.ldi_attr & NVRAM_ATTR_CHKSUM_INTEGRATE) ) |
| #else |
| if(KAL_TRUE == nvram_read_ota_header(hFile, &ota_header, NVRAM_LDI_OTA_HEADER_SIZE) && |
| (ota_header.ldi_attr & NVRAM_ATTR_CHKSUM_INTEGRATE) ) |
| #endif |
| { |
| ldi->append_offset = nvram_appendix_header_offset(ldi); |
| } |
| else { |
| ldi->append_offset = -1; |
| } |
| } |
| if(ldi->append_offset > 0) { |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, (ldi->append_offset + NVRAM_LDI_APPENDIX_HEADER_SIZE + ((rec_index - 1) * nvram_chksum_size)), FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(hFile, ldi->append_buffer, (rec_amount * nvram_chksum_size), &len); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| #if defined(__NVRAM_LID_CACHE__) |
| kal_uint32 cache_offset = 0; |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_WR_2_FILE_WITH_2_CACHE(ldi->LID)) |
| { |
| get_lid_cache_base_address(ldi, &cache_offset); |
| cache_offset = cache_offset + (ldi->append_offset + NVRAM_LDI_APPENDIX_HEADER_SIZE + ((rec_index - 1) * nvram_chksum_size)); |
| nvram_write_data_to_cache(ldi, (kal_uint8*)ldi->append_buffer, (rec_amount * nvram_chksum_size), cache_offset); |
| } |
| |
| #endif |
| } |
| |
| if(ldi->append_buffer) { |
| free_ctrl_buffer(ldi->append_buffer); |
| ldi->append_buffer = NULL; |
| } |
| } |
| |
| if (hFile > FS_NO_ERROR) |
| { |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| } |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_STOP, (DCL_CTRL_DATA_T*)NULL); //stop timer |
| #endif |
| |
| nvram_util_give_mutex(g_nvram_fs_mutex); |
| |
| /* Set the attribute back to original attribute */ |
| |
| |
| if (result < FS_NO_ERROR) |
| { |
| nvram_fat_last_err = result; |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| } |
| } |
| |
| return result; |
| } |
| |
| nvram_drv_status_enum nvram_drv_fat_write_exception_item(kal_uint8 *buffer, |
| kal_char *nvramname, |
| kal_uint16 section_number, |
| kal_uint32 size, |
| kal_uint32 writesize) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| kal_char cfilename[NVRAM_FILE_LEN + 1] = {0}; |
| kal_wchar wcfilename[NVRAM_FILE_LEN + 1] = {0}; |
| FS_HANDLE hFile = 0; |
| kal_uint32 len = 0; |
| kal_uint32 offset = 0; |
| kal_int32 Ret = FS_NO_ERROR; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_ltable_entry_struct *ldi = NULL; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| if (section_number < 1) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d,section_number=%d\r\n",__FUNCTION__,__LINE__,section_number); |
| /* kal_print("Nvram write: section_number < 1 !"); */ |
| return NVRAM_DRV_INVALID_RECORD_ID; |
| } |
| |
| /* translate record id to filename */ |
| nvram_query_file_name(NVRAM_NVD_DATA, nvramname, filename); |
| |
| nvram_query_file_name_by_path((kal_wchar *)filename, wcfilename); |
| kal_dchar2char((WCHAR *)wcfilename, cfilename); |
| nvram_util_get_data_item_by_fileprefix(&ldi, cfilename); |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| if(nvram_chksum_size > sizeof(g_chksum)) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s-> %d nvram_chksum_size > chksum array size.\r\n",__FUNCTION__, __LINE__); |
| } |
| |
| /* open NV_RCD.(RCD#) file */ |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| hFile = FS_Open((const kal_wchar*)filename, FS_CREATE | FS_READ_WRITE | FS_OPEN_NO_DIR); |
| NVRAM_FS_END(FS_OP_OPEN,hFile); |
| |
| if (hFile == FS_FILE_NOT_FOUND) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Open %s fail\r\n",__FUNCTION__,nvramname); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]Fail at %d,FS_FILE_NOT_FOUND hFile=%d\r\n",__LINE__,hFile); |
| return NVRAM_DRV_EMPTY_RECORD; |
| } |
| else if (hFile <= FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->FS_Open %s fail\r\n",__FUNCTION__,nvramname); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]Fail at %d,hFile=%d\r\n",__LINE__,hFile); |
| /* kal_print("Nvram write: FS_Open return error!"); */ |
| return NVRAM_DRV_FATAL_ERROR; |
| } |
| |
| /* seek to the record start */ |
| offset = NVRAM_LDI_HEADER_SIZE; |
| offset += (section_number - 1) * (size + nvram_chksum_size); |
| NVRAM_FS_START(FS_OP_SEEK); |
| Ret = FS_Seek(hFile, offset, FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,Ret); |
| if (Ret == offset) |
| { |
| NVRAM_FS_START(FS_OP_WRITE); |
| Ret = FS_Write(hFile, buffer, (kal_uint32) writesize, &len); |
| NVRAM_FS_END(FS_OP_WRITE,Ret); |
| if (Ret == FS_NO_ERROR) |
| { |
| nvram_util_caculate_checksum(ldi, buffer, writesize,g_chksum); |
| NVRAM_FS_START(FS_OP_WRITE); |
| Ret = FS_Write(hFile, g_chksum, nvram_chksum_size, &len); |
| NVRAM_FS_END(FS_OP_WRITE,Ret); |
| } |
| } |
| |
| if (Ret != FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,Ret); |
| /* kal_print("Nvram write: Read error!"); */ |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| return NVRAM_DRV_CHECKSUM_ERROR; |
| } |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| |
| return NVRAM_DRV_OK; |
| } |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_get_record_size |
| * DESCRIPTION |
| * get the record size. |
| * PARAMETERS |
| * nvramname [?] |
| * Hint [?] |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_get_record_size(kal_char *nvramname, void *Hint, nvram_folder_enum nvram_folder) |
| { |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| kal_uint32 size = 0; |
| kal_int32 Ret = FS_NO_ERROR; |
| #if !defined(__NVRAM_FS_OPERATION_COMPACT__) || !(defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__)) |
| FS_HANDLE hFile; |
| nvram_query_file_name(nvram_folder, nvramname, filename); |
| nvram_util_take_mutex(g_nvram_fs_mutex); |
| NVRAM_FS_START_EX(FS_OP_OPENHINT,filename); |
| hFile = FS_OpenHint(filename, FS_READ_ONLY, (FS_FileOpenHint*) Hint); |
| NVRAM_FS_END(FS_OP_OPENHINT,hFile); |
| if ( hFile > 0) |
| { |
| NVRAM_FS_START(FS_OP_GETFILESIZE); |
| Ret = FS_GetFileSize(hFile, &size); |
| NVRAM_FS_END(FS_OP_GETFILESIZE,Ret); |
| if (Ret != FS_NO_ERROR) |
| { |
| size = 0; |
| } |
| |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| nvram_util_give_mutex(g_nvram_fs_mutex); |
| return (size - NVRAM_LDI_HEADER_SIZE); |
| } |
| else |
| { |
| nvram_util_give_mutex(g_nvram_fs_mutex); |
| return hFile; |
| } |
| #else |
| NVRAM_FS_PARAM_CMPT_T nvram_param; |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| SGPT_CTRL_START_T start; |
| #endif |
| |
| nvram_query_file_name(nvram_folder, nvramname, filename); |
| /* Add NVRAM GPT timeout assert start timer*/ |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| start.u2Tick= NVRAM_READ_GPT_TIMEOUT; |
| start.pfCallback=nvram_gpt_timeout_callback; |
| start.vPara=NULL; |
| #endif |
| |
| nvram_util_take_mutex(g_nvram_fs_mutex); |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start); //start timer |
| #endif |
| |
| nvram_param.opid_map = 0; |
| nvram_param.ret[0] = 0; |
| nvram_param.ret[1] = 0; |
| |
| //FS_Open |
| nvram_param.opid_map |= NVRAM_FS_CMPT_OPEN; |
| nvram_param.Flag = FS_READ_ONLY; |
| //FS_GetFileSize |
| nvram_param.opid_map |= NVRAM_FS_CMPT_GETFILESIZE; |
| nvram_param.FileSize = &size; |
| nvram_param.DataPtr = NULL; |
| nvram_param.Read = NULL; |
| //FS_Close |
| nvram_param.opid_map |= NVRAM_FS_CMPT_CLOSE; |
| NVRAM_FS_START_EX(FS_OP_CMPTREAD,filename); |
| Ret = FS_CMPT_Read(filename, &nvram_param); |
| NVRAM_FS_END(FS_OP_CMPTREAD,Ret); |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_STOP, (DCL_CTRL_DATA_T*)NULL); //stop timer |
| #endif |
| |
| nvram_util_give_mutex(g_nvram_fs_mutex); |
| |
| if (nvram_param.opid_map == nvram_param.ret[0]) |
| { |
| return (size - NVRAM_LDI_HEADER_SIZE); |
| } |
| else |
| { |
| return nvram_param.ret[1]; |
| } |
| #endif |
| } |
| |
| #if (defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__)) || defined(__NVRAM_BIN_REGION_SIMULATION__) |
| |
| #ifdef __NVRAM_CHECK_FILE_AND_RECOVER__ |
| |
| static kal_int32 nvram_drv_fat_read_file(const kal_wchar* filename, void *DataPtr, kal_uint32 *Readlen) |
| { |
| kal_int32 result = 0; |
| FS_HANDLE hFile = 0; |
| kal_uint32 len; |
| kal_int32 Ret = 0; |
| do |
| { |
| NVRAM_FS_START_EX(FS_OP_OPEN,filename); |
| hFile = FS_Open(filename, FS_READ_ONLY | FS_OPEN_NO_DIR | FS_OPEN_SHARED); |
| NVRAM_FS_END(FS_OP_OPEN,hFile); |
| if (hFile == FS_FILE_NOT_FOUND) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Open fail at %d,hFile=%d\r\n",__FUNCTION__,__LINE__,hFile); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_EMPTY_RECORD; |
| break; |
| } |
| else if (hFile <= FS_NO_ERROR) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Open fail at %d,hFile=%d\r\n",__FUNCTION__,__LINE__,hFile); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_FATAL_ERROR; |
| break; |
| } |
| |
| /* check if a empty record */ |
| NVRAM_FS_START(FS_OP_GETFILESIZE); |
| result = FS_GetFileSize(hFile, &len); |
| NVRAM_FS_END(FS_OP_GETFILESIZE,result); |
| if ((result == FS_NO_ERROR) && (len == 0)) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_GetFileSize fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| nvram_fat_last_line = __LINE__; |
| result = NVRAM_DRV_EMPTY_RECORD; |
| break; |
| } |
| NVRAM_FS_START(FS_OP_SEEK); |
| result = FS_Seek(hFile, 0, FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| if (FS_NO_ERROR > result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s ->FS_Seek fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| NVRAM_FS_START(FS_OP_READ); |
| result = FS_Read(hFile, DataPtr, len, Readlen); |
| NVRAM_FS_END(FS_OP_READ,result); |
| if (hFile > FS_NO_ERROR) |
| { |
| NVRAM_FS_START(FS_OP_CLOSE); |
| Ret = FS_Close(hFile); |
| NVRAM_FS_END(FS_OP_CLOSE,Ret); |
| } |
| }while(0); |
| |
| return result; |
| } |
| #endif |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_auto_recover |
| * DESCRIPTION |
| * file auto-recover, only for smart phone. |
| * PARAMETERS |
| * filename [IN] full path of the data item |
| * rec_index [IN] which record to read (start) |
| * rec_amount [IN] how many record to read at once |
| * rec_size [IN] size of record |
| * buffer [IN/OUT] buffer of check sum |
| * type [IN] read content or checksum |
| * ismsp [IN] to indicate that the records protected by hw |
| * RETURNS |
| * = 0: success |
| * > 0: NVRAM error code |
| * < 0: FS error code |
| *****************************************************************************/ |
| kal_int32 nvram_drv_fat_auto_recover( |
| kal_char *nvramname, |
| nvram_folder_enum nvram_folder /* folder index */ |
| ) |
| |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| kal_int32 result = 0; |
| kal_wchar filename[NVRAM_MAX_PATH_LEN]; |
| kal_char cfilename[NVRAM_FILE_LEN + 1]; |
| kal_wchar wcfilename[NVRAM_FILE_LEN + 1]; |
| void *dummy_ptr = (void*)&result; |
| FS_HANDLE fhdl = FS_INVALID_FILE_HANDLE; |
| #ifdef __NVRAM_CHECK_FILE_AND_RECOVER__ |
| kal_wchar *Cali_filelistname = NULL; |
| kal_wchar *Imei_filelistname = NULL; |
| nvram_folder_enum folder_index; |
| kal_uint32 len = 0; |
| kal_int32 temp_count = 0; |
| #endif |
| nvram_ldi_header nv_header; |
| kal_uint32 header_buffer_size = 0; |
| nvram_ltable_entry_struct *ldi = NULL; |
| kal_int32 ret = 0; |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| nvram_util_take_mutex(g_nvram_fs_mutex); |
| nvram_query_file_name(nvram_folder, nvramname, filename); |
| #if defined(__NVRAM_BIN_REGION_SIMULATION__) |
| { |
| kal_wchar *s_filename = (kal_wchar *)get_ctrl_buffer(NVRAM_MAX_PATH_LEN * sizeof(kal_wchar)); |
| kal_wsprintf(s_filename, "%s\\%s", "Z:\\BIN_REGION", nvramname); |
| NVRAM_FS_START_EX(FS_OP_MOVE,s_filename); |
| result = FS_Move(s_filename, filename, (FS_MOVE_COPY | FS_MOVE_OVERWRITE), NULL, NULL, 0); |
| NVRAM_FS_END(FS_OP_MOVE,result); |
| free_ctrl_buffer(s_filename); |
| s_filename = NULL; |
| }while(0); |
| #else |
| #ifdef __NVRAM_CHECK_FILE_AND_RECOVER__ |
| if(is_nvram_in_ota_flow) |
| { |
| if(is_nvram_first_restore) |
| { |
| Cali_filelistname = (kal_wchar *)get_ctrl_buffer(NVRAM_MAX_PATH_LEN * sizeof(kal_wchar)); |
| Imei_filelistname = (kal_wchar *)get_ctrl_buffer(NVRAM_MAX_PATH_LEN * sizeof(kal_wchar)); |
| if(Cali_filelistname == NULL) |
| { |
| kal_prompt_trace(MOD_NVRAM, "%s Can not get the memory from control buffer @line %d\n\r",__FUNCTION__,__LINE__); |
| } |
| if(Imei_filelistname == NULL) |
| { |
| kal_prompt_trace(MOD_NVRAM, "%s Can not get the memory from control buffer @line %d\n\r",__FUNCTION__,__LINE__); |
| } |
| folder_index = nvram_query_folder_index(NVRAM_CATEGORY_CALIBRAT); |
| nvram_query_file_name(folder_index, "FILELIST", Cali_filelistname); |
| |
| folder_index = nvram_query_folder_index(NVRAM_CATEGORY_IMPORTANT); |
| nvram_query_file_name(folder_index, "FILELIST", Imei_filelistname); |
| |
| //delete FILELIST in Calibrate and IMEI folder |
| NVRAM_FS_START_EX(FS_OP_XDELETE,Cali_filelistname); |
| ret = MD_FS_Delete((const kal_wchar*)Cali_filelistname); |
| NVRAM_FS_END(FS_OP_XDELETE,ret); |
| NVRAM_FS_START_EX(FS_OP_XDELETE, Imei_filelistname); |
| ret = MD_FS_Delete((const kal_wchar*)Imei_filelistname); |
| NVRAM_FS_END(FS_OP_XDELETE,ret); |
| |
| //Restore FILELIST from bin region |
| NVRAM_FS_START_EX(FS_OP_RESTORE,Cali_filelistname); |
| result = MD_FS_Restore((const kal_wchar*)Cali_filelistname, dummy_ptr, 4); |
| NVRAM_FS_END(FS_OP_RESTORE,result); |
| if(result >= 0) |
| { |
| //read filelist from bin region to buf |
| result = nvram_drv_fat_read_file((const kal_wchar* )Cali_filelistname, (void *)CALI_FileListBuf,&len); |
| if(result == 0) |
| { |
| Cali_filelist_found = KAL_TRUE; |
| for(temp_count = 0; temp_count < len; temp_count++) |
| { |
| if(CALI_FileListBuf[temp_count] == 0x00) |
| { |
| CALI_FileListBuf[temp_count] = 0xd; |
| } |
| } |
| } |
| } |
| NVRAM_FS_START_EX(FS_OP_RESTORE, Imei_filelistname); |
| result = MD_FS_Restore((const kal_wchar*)Imei_filelistname, dummy_ptr, 4); |
| NVRAM_FS_END(FS_OP_RESTORE,result); |
| if(result >= 0) |
| { |
| //read filelist from bin region to buf |
| result = nvram_drv_fat_read_file((const kal_wchar* )Imei_filelistname, (void *)IMEI_FileListBuf,&len); |
| if(result == 0) |
| { |
| Imei_filelist_found = KAL_TRUE; |
| |
| for(temp_count = 0; temp_count < len; temp_count++) |
| { |
| if(IMEI_FileListBuf[temp_count] == 0x00) |
| { |
| IMEI_FileListBuf[temp_count] = 0xd; |
| } |
| } |
| } |
| } |
| is_nvram_first_restore = KAL_FALSE; |
| free_ctrl_buffer(Cali_filelistname); |
| free_ctrl_buffer(Imei_filelistname); |
| Cali_filelistname = NULL; |
| Imei_filelistname = NULL; |
| } |
| if((NVRAM_NVD_IMPT == nvram_folder) &&(Imei_filelist_found == KAL_TRUE)) |
| { |
| if(NULL != strstr((const char *)IMEI_FileListBuf,(const char *)nvramname)) |
| { |
| NVRAM_FS_START_EX(FS_OP_RESTORE, filename); |
| result = MD_FS_Restore((const kal_wchar*)filename, dummy_ptr, 4); |
| NVRAM_FS_END(FS_OP_RESTORE,result); |
| } |
| else |
| { |
| result = NVRAM_DRV_FATAL_ERROR; |
| } |
| } |
| else if((NVRAM_NVD_CALI == nvram_folder)&&(Cali_filelist_found == KAL_TRUE)) |
| { |
| if(NULL != strstr((const char *)CALI_FileListBuf,(const char *)nvramname)) |
| { |
| NVRAM_FS_START_EX(FS_OP_RESTORE, filename); |
| result = MD_FS_Restore((const kal_wchar*)filename, dummy_ptr, 4); |
| NVRAM_FS_END(FS_OP_RESTORE,result); |
| } |
| else |
| { |
| result = NVRAM_DRV_FATAL_ERROR; |
| } |
| } |
| else |
| { |
| result = NVRAM_DRV_FATAL_ERROR; |
| } |
| } |
| else |
| { |
| NVRAM_FS_START_EX(FS_OP_RESTORE, filename); |
| result = MD_FS_Restore((const kal_wchar*)filename, dummy_ptr, 4); |
| NVRAM_FS_END(FS_OP_RESTORE,result); |
| } |
| #else |
| NVRAM_FS_START_EX(FS_OP_RESTORE, filename); |
| result = MD_FS_Restore((const kal_wchar*)filename, dummy_ptr, 4); |
| NVRAM_FS_END(FS_OP_RESTORE,result); |
| #endif |
| kal_mem_set(&nv_header, 0x0, sizeof(nv_header)); |
| if(result == NVRAM_DRV_OK) |
| { |
| NVRAM_FS_START_EX(FS_OP_OPEN, filename); |
| fhdl = FS_Open(filename, FS_READ_ONLY | FS_OPEN_SHARED |FS_OPEN_NO_DIR); |
| NVRAM_FS_END(FS_OP_OPEN,result); |
| if(fhdl > FS_NO_ERROR) |
| { |
| NVRAM_FS_START(FS_OP_READ); |
| result = FS_Read(fhdl, &nv_header, NVRAM_LDI_HEADER_SIZE, &header_buffer_size); |
| NVRAM_FS_END(FS_OP_READ,result); |
| } |
| |
| if((fhdl > FS_NO_ERROR) && (result == NVRAM_DRV_OK)) |
| { |
| NVRAM_FS_START(FS_OP_SEEK); |
| ret = FS_Seek(fhdl, 0, FS_FILE_BEGIN); |
| NVRAM_FS_END(FS_OP_SEEK,result); |
| } |
| if((fhdl > FS_NO_ERROR) && (strcmp(nv_header.nv_ota_header.header,"LDI"))){ |
| ldi = NULL; |
| kal_mem_set(cfilename,0,NVRAM_FILE_LEN + 1); |
| kal_mem_set(wcfilename,0,(NVRAM_FILE_LEN + 1)*sizeof(kal_wchar)); |
| nvram_query_file_name_by_path((kal_wchar *)filename, wcfilename); |
| kal_dchar2char((WCHAR *)wcfilename, cfilename); |
| nvram_util_get_data_item_by_fileprefix(&ldi, cfilename); |
| if(ldi != NULL) |
| { |
| nvram_prepare_data_header(ldi, (kal_uint8 *)(&nv_header)); |
| NVRAM_FS_START(FS_OP_WRITE); |
| result = FS_Write(fhdl, (void *)(&nv_header), NVRAM_LDI_HEADER_SIZE, &header_buffer_size); |
| NVRAM_FS_END(FS_OP_WRITE,result); |
| } |
| } |
| if(fhdl > FS_NO_ERROR) { |
| NVRAM_FS_START(FS_OP_CLOSE); |
| ret = FS_Close(fhdl); |
| NVRAM_FS_END(FS_OP_CLOSE,ret); |
| } |
| } |
| #endif |
| |
| nvram_util_give_mutex(g_nvram_fs_mutex); |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| { |
| ldi = NULL; |
| kal_mem_set(cfilename,0,NVRAM_FILE_LEN + 1); |
| kal_mem_set(wcfilename,0,(NVRAM_FILE_LEN + 1)*sizeof(kal_wchar)); |
| |
| nvram_query_file_name_by_path((kal_wchar *)filename, wcfilename); |
| kal_dchar2char((WCHAR *)wcfilename, cfilename); |
| nvram_util_get_data_item_by_fileprefix(&ldi, cfilename); |
| |
| if(ldi == NULL) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]Can't find LID entry for %s in the LID table\r\n",cfilename); |
| if(nvram_ptr->state == NVRAM_STATE_READY) |
| { |
| kal_prompt_trace(MOD_NVRAM, "cfilename:%s\n\r", cfilename); |
| kal_prompt_trace(MOD_NVRAM, "Can't find LID entry in the LID table:\n\r"); |
| NVRAM_EXT_ASSERT(KAL_FALSE,0 , NVRAM_LOC_LID_PTR_IS_NULL_3, ldi); |
| }else |
| { |
| kal_prompt_trace(MOD_NVRAM, "cfilename:%s\n\r", cfilename); |
| return NVRAM_DRV_FATAL_ERROR; |
| } |
| } |
| |
| if((!NVRAM_IS_ATTR_RAW_DATA(ldi->attr)) && NVRAM_RD_WITH_CACHE(ldi->LID)) |
| { |
| unmask_valid_bit_by_ltable_entry(ldi, 0, (ldi->total_records + 1)); |
| } |
| } |
| #endif |
| return result; |
| } |
| #endif |
| |
| #ifdef __NVRAM_LID_CACHE__ |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_write_cache_section |
| * DESCRIPTION |
| * write record(s) to FAT. |
| * PARAMETERS |
| * buffer [?] |
| * nvramname [?] |
| * section_number [IN] |
| * size [IN] |
| * initialize [IN] true for reset, false for normal write. |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| nvram_drv_status_enum nvram_drv_fat_write_cache_section( |
| const kal_uint8 *buffer, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| nvram_ltable_entry_struct *ldi) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| |
| kal_uint32 openOption = FS_READ_WRITE | FS_OPEN_NO_DIR; |
| kal_uint32 remainLen = 0; |
| kal_uint8 *chksum = NULL; |
| kal_uint32 max_rec_amount = 0; |
| kal_uint32 section_size = 0; |
| kal_uint32 working_buffer_size = 0; |
| kal_uint8 *working_buffer = NULL; |
| kal_int32 result = NVRAM_IO_ERRNO_OK; |
| kal_bool encrypt_data = KAL_FALSE; |
| kal_uint32 i = 0; |
| kal_uint16 temp_rec_index = rec_index; |
| kal_uint32 cache_offset = 0; |
| kal_uint32 temp_cache_offset = 0; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| SGPT_CTRL_START_T start; |
| #endif |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| /* NVRAM GPT timeout assert start timer */ |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| start.u2Tick= NVRAM_WRITE_GPT_TIMEOUT; |
| start.pfCallback=nvram_gpt_timeout_callback; |
| start.vPara=NULL; |
| #endif |
| |
| //nvram_util_take_mutex(g_nvram_fs_mutex); |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start); //start timer |
| #endif |
| |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| /* set the attribute to empty before write data |
| sometime the files may be read only if the nvram lock is turn on |
| ex: software update when nvram lock is turned on |
| But it is not a good solution here, we should unlock it in io layer */ |
| |
| |
| openOption |= FS_CREATE; |
| #if !defined(_NAND_FLASH_BOOTING_) && !defined(__FS_SYSDRV_ON_NAND__) && !defined(__EMMC_BOOTING__) |
| openOption |= FS_PROTECTION_MODE; /* boot from NAND and single bank NOR don't support this */ |
| #endif |
| |
| #if defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__) |
| if (ldi->attr & NVRAM_ATTR_COMMITTED) { |
| openOption |= FS_COMMITTED; |
| } |
| #endif |
| |
| //Get appdenix header info |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) { |
| ldi->append_buffer = get_ctrl_buffer(rec_amount * nvram_chksum_size); |
| } |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if ((ldi->attr & NVRAM_ATTR_MSP)||(ldi->attr & NVRAM_ATTR_CONFIDENTIAL)) { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| encrypt_data = KAL_TRUE; |
| } |
| #else |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| encrypt_data = KAL_TRUE; |
| } |
| #endif |
| |
| section_size = rec_size + nvram_chksum_size + remainLen; |
| working_buffer_size = section_size * rec_amount; |
| if (working_buffer_size > MAX_NVRAM_RECORD_SIZE) { |
| working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| } |
| |
| working_buffer = (kal_uint8*) get_ctrl_buffer(working_buffer_size); |
| chksum = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size); |
| |
| /* we can write data into FS directly, we don't need another buffer*/ |
| if (!(ldi->attr & NVRAM_ATTR_MSP) && !(ldi->attr & NVRAM_ATTR_CONFIDENTIAL) && |
| #if defined(__MTK_TARGET__) && defined(__NVRAM_IMPORTANT_PARTITIONS__) |
| !(ldi->attr & NVRAM_ATTR_COMMITTED) && |
| #endif |
| buffer != NVRAM_EF_ZERO_DEFAULT && buffer != NVRAM_EF_FF_DEFAULT) |
| { |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->get_lid_record_cache_offset fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| for(i = 0;i < rec_amount;i++) |
| { |
| nvram_memset(working_buffer, (kal_uint8) NVRAM_EF_ZERO_DEFAULT_VALUE, working_buffer_size); |
| if ((i == 0) || (ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, buffer + i * rec_size, rec_size, chksum); |
| } |
| |
| if (ldi->attr & NVRAM_ATTR_MULTI_DEFAULT) |
| { |
| kal_mem_cpy(working_buffer, (void *)(buffer + i * rec_size), rec_size); |
| }else |
| { |
| kal_mem_cpy(working_buffer, (void *)buffer, rec_size); |
| } |
| |
| //write data & checksum |
| kal_mem_cpy((void *)(working_buffer + rec_size), (void *)chksum, nvram_chksum_size); |
| |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, working_buffer, section_size, (cache_offset + i * section_size)))) { |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| |
| mask_dirty_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| } |
| goto final; |
| } |
| |
| //working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| //MAX_NVRAM_RECORD_SIZE = (NVRAM_CUSTOM_CFG_MAX_RECORD_SECTOR_NUM * NVRAM_RECORD_SECTOR_SIZE) |
| // = (16 or 4) * 512 |
| |
| #ifdef __NVRAM_LARGE_RECORD_SIZE__ |
| /* size too large , we need to operate block by block */ |
| if (section_size > working_buffer_size) |
| { |
| /* we need to prepare extra working buffer; |
| and due to msp need 16-bytes alignment, therefore |
| we set the working buffer to 16-bytes alignment also */ |
| kal_uint8 *tmpchksum = NULL; |
| kal_int32 j,cs_idx; |
| |
| working_buffer_size = NVRAM_MSP_ALIGNMENT_FLOOR(working_buffer_size) - NVRAM_MSP_ALIGNMENT; |
| tmpchksum = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size); |
| |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) { |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| if (tmpchksum) |
| { |
| free_ctrl_buffer(tmpchksum); |
| tmpchksum = NULL; |
| } |
| goto final; |
| } |
| |
| for (i = 0 ; i < rec_amount; i++) |
| { |
| temp_cache_offset = cache_offset + i*section_size; |
| for (j = 0; j < rec_size; j += working_buffer_size) |
| { |
| kal_int32 byte_in_block = rec_size - j; |
| kal_bool last_block = KAL_FALSE; |
| |
| if (byte_in_block > working_buffer_size) { |
| byte_in_block = working_buffer_size; |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) { |
| nvram_drv_fat_prepare_data(working_buffer, buffer, j, byte_in_block); |
| } |
| else { |
| nvram_drv_fat_prepare_data(working_buffer, buffer, i * rec_size + j, byte_in_block); |
| } |
| } |
| else /* last block */ |
| { |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) { |
| nvram_drv_fat_prepare_data(working_buffer, buffer, j, byte_in_block); |
| } |
| else { |
| nvram_drv_fat_prepare_data(working_buffer, buffer, i * rec_size + j, byte_in_block); |
| } |
| last_block = KAL_TRUE; |
| } |
| |
| if (i == 0 || ldi->attr & NVRAM_ATTR_MULTI_DEFAULT) { |
| if (j == 0) { |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| } |
| kal_mem_set(tmpchksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, working_buffer, byte_in_block, tmpchksum); |
| for(cs_idx= 0; cs_idx < nvram_chksum_size;cs_idx++) { |
| chksum[cs_idx] += tmpchksum[cs_idx]; |
| } |
| } |
| |
| /* last block */ |
| if (last_block) { |
| kal_mem_cpy(working_buffer + byte_in_block, chksum, nvram_chksum_size); |
| kal_mem_set(working_buffer + byte_in_block + nvram_chksum_size, 0, remainLen); |
| byte_in_block += (nvram_chksum_size + remainLen); |
| } |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) { |
| //custom_nvram_encrypt(nvram_ptr->secret_key, working_buffer, byte_in_block, rec_size); |
| nvram_AES_encrypt(working_buffer, byte_in_block); |
| } |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if (ldi->attr & NVRAM_ATTR_MSP) { |
| |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer, byte_in_block, nvram_ptr->secret_key, working_buffer); |
| } |
| #endif |
| |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, working_buffer, byte_in_block, temp_cache_offset))) { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| if (tmpchksum) |
| { |
| free_ctrl_buffer(tmpchksum); |
| tmpchksum = NULL; |
| } |
| goto final; |
| } |
| |
| temp_cache_offset = temp_cache_offset + byte_in_block; |
| } |
| |
| mask_dirty_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| } |
| if (tmpchksum) |
| { |
| free_ctrl_buffer(tmpchksum); |
| tmpchksum = NULL; |
| } |
| } |
| else |
| #endif |
| { |
| kal_uint32 rec_in_block = 0; |
| max_rec_amount = working_buffer_size / section_size; |
| temp_rec_index = rec_index; |
| |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->get_lid_record_cache_offset fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| |
| for (i = 0; i < rec_amount ; i ++) { |
| /* |
| * Write several record at once to reduce io Write |
| * case a: all remain record |
| * section_number - i |
| * case b: max record we can write in one time |
| * max_rec_amount |
| * check which case is smaller |
| */ |
| |
| nvram_drv_fat_prepare_data(working_buffer + rec_in_block * section_size, buffer, i * rec_size, rec_size); |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, working_buffer + rec_in_block * section_size, rec_size, chksum); |
| |
| kal_mem_cpy(working_buffer + rec_in_block * section_size + rec_size, chksum, nvram_chksum_size); |
| |
| if (remainLen) { |
| kal_mem_set(working_buffer + rec_in_block * section_size + rec_size + nvram_chksum_size , 0x00, remainLen); |
| } |
| |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) { |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bWriteMsp == 1) { |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_W,working_buffer,NVRAM_MSP_TEST_LEN); |
| } |
| #endif |
| nvram_AES_encrypt(working_buffer + rec_in_block * section_size, section_size); |
| |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bWriteMsp == 1){ |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_W[NVRAM_MSP_TEST_LEN],working_buffer,NVRAM_MSP_TEST_LEN); |
| } |
| #endif |
| } |
| |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if (ldi->attr & NVRAM_ATTR_MSP) { |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer + rec_in_block * section_size, section_size, nvram_ptr->secret_key, working_buffer + rec_in_block * section_size); |
| } |
| #endif |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| |
| /* if this is not multi default, no need to prepare data anymore */ |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) { |
| break; |
| } |
| rec_in_block ++; |
| |
| if (rec_in_block == max_rec_amount || i == rec_amount - 1) |
| { |
| |
| result = nvram_write_data_to_cache(ldi, working_buffer, section_size * rec_in_block, cache_offset); |
| |
| if (NVRAM_IO_ERRNO_OK != result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| mask_dirty_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| mask_valid_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| cache_offset += section_size * rec_in_block; |
| temp_rec_index += rec_in_block; |
| |
| rec_in_block = 0; |
| } |
| } |
| |
| |
| /* special handling for not multi default */ |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) { |
| /* special handling for NVRAM_EF_ZERO_DEFAULT write speed up*/ |
| if((buffer == NVRAM_EF_ZERO_DEFAULT) && |
| !encrypt_data ) |
| { |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->get_lid_record_cache_offset fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| |
| for(i = 0; i < rec_amount; i++) { |
| temp_cache_offset = cache_offset + i* section_size; |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, working_buffer, section_size, temp_cache_offset))) { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| |
| mask_dirty_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index + i, 1); |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)(working_buffer + rec_size), nvram_chksum_size); |
| } |
| } |
| goto final; |
| } |
| |
| if (rec_amount > 1) { |
| for (i = 1; i < max_rec_amount && i < rec_amount; i++) { |
| kal_mem_cpy(working_buffer + section_size * i, working_buffer, section_size); |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)(working_buffer+rec_size), nvram_chksum_size); |
| } |
| } |
| } |
| |
| #ifdef __NVRAM_CRYPT_TEST__ |
| if (bWriteMsp == 1) { |
| kal_mem_cpy(&NVRAM_EF_MSP_TEST_W[NVRAM_MSP_TEST_LEN*2],working_buffer,NVRAM_MSP_TEST_LEN); |
| nvram_create_report_msp_file(KAL_TRUE); |
| } |
| #endif |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) { |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| temp_rec_index = rec_index; |
| temp_cache_offset = cache_offset; |
| for (i = 0 ; i < rec_amount ; i += max_rec_amount) { |
| rec_in_block = (rec_amount - i) > max_rec_amount ? max_rec_amount: (rec_amount - i); |
| |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, working_buffer, section_size * rec_in_block, temp_cache_offset))) { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| mask_dirty_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| mask_valid_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| |
| |
| temp_rec_index = temp_rec_index + rec_in_block; |
| temp_cache_offset = cache_offset + section_size * rec_in_block; |
| } |
| } |
| |
| } |
| |
| final: |
| |
| if(result == NVRAM_IO_ERRNO_OK) |
| { |
| do |
| { |
| //write-back appdenix header info |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) |
| { |
| if(ldi->append_offset == 0) { |
| ldi->append_offset = nvram_appendix_header_offset(ldi); |
| } |
| |
| if(ldi->append_offset > 0) { |
| |
| if(NVRAM_IO_ERRNO_OK != (result = get_lid_cache_base_address(ldi, &cache_offset))) { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->get_lid_cache_base_address fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| |
| cache_offset = cache_offset + (ldi->append_offset + NVRAM_LDI_APPENDIX_HEADER_SIZE + ((rec_index - 1) * nvram_chksum_size)); |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, (kal_uint8*)ldi->append_buffer, (rec_amount * nvram_chksum_size), cache_offset))) { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| } |
| |
| } |
| }while(0); |
| } |
| |
| if(ldi->append_buffer) { |
| free_ctrl_buffer(ldi->append_buffer); |
| ldi->append_buffer = NULL; |
| } |
| |
| if (working_buffer) { |
| free_ctrl_buffer(working_buffer); |
| working_buffer = NULL; |
| } |
| |
| if (chksum) |
| { |
| free_ctrl_buffer(chksum); |
| chksum = NULL; |
| } |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_STOP, (DCL_CTRL_DATA_T*)NULL); //stop timer |
| #endif |
| |
| if (NVRAM_IO_ERRNO_OK != result) { |
| nvram_fat_last_err = result; |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| return result; |
| } |
| |
| nvram_cache_enqueue(ldi, rec_index, rec_amount, openOption); |
| |
| send_event_to_nvram_cache(); |
| |
| return NVRAM_DRV_OK; |
| } |
| |
| |
| /***************************************************************************** |
| * FUNCTION |
| * nvram_drv_fat_write_multiRec_to_cache |
| * DESCRIPTION |
| * write record(s) to FAT. |
| * PARAMETERS |
| * buffer [?] |
| * nvramname [?] |
| * section_number [IN] |
| * size [IN] |
| * initialize [IN] true for reset, false for normal write. |
| * RETURNS |
| * void |
| *****************************************************************************/ |
| nvram_drv_status_enum nvram_drv_fat_write_multiRec_to_cache( |
| const kal_uint8 *buffer, |
| kal_uint16 rec_index, |
| kal_uint16 rec_amount, |
| kal_uint32 rec_size, |
| nvram_ltable_entry_struct *ldi) |
| { |
| /*----------------------------------------------------------------*/ |
| /* Local Variables */ |
| /*----------------------------------------------------------------*/ |
| |
| kal_uint32 openOption = FS_READ_WRITE | FS_OPEN_NO_DIR; |
| kal_uint32 remainLen = 0; |
| kal_uint8 *chksum = NULL; |
| kal_uint32 max_rec_amount; |
| kal_uint32 section_size; |
| kal_uint32 working_buffer_size; |
| kal_uint8 *working_buffer = NULL; |
| kal_int32 result = NVRAM_IO_ERRNO_OK; |
| kal_uint32 i; |
| kal_uint32 cache_offset = 0; |
| kal_uint32 temp_cache_offset = 0; |
| kal_uint16 temp_rec_index = rec_index; |
| kal_uint32 rec_in_block = 0; |
| nvram_ldi_ota_header ota_header; |
| kal_uint32 nvram_chksum_size = 0; |
| nvram_lid_chksum_info lid_chksum_info = {0}; |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| SGPT_CTRL_START_T start; |
| #endif |
| |
| /*----------------------------------------------------------------*/ |
| /* Code Body */ |
| /*----------------------------------------------------------------*/ |
| |
| /* NVRAM GPT timeout assert start timer */ |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| start.u2Tick= NVRAM_WRITE_GPT_TIMEOUT; |
| start.pfCallback=nvram_gpt_timeout_callback; |
| start.vPara=NULL; |
| #endif |
| |
| //nvram_util_take_mutex(g_nvram_fs_mutex); |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_START, (DCL_CTRL_DATA_T*)&start); //start timer |
| #endif |
| |
| nvram_get_lid_chksum_algo_info(ldi, &lid_chksum_info, KAL_FALSE, KAL_FALSE); |
| nvram_chksum_size = lid_chksum_info.algo_info.chksum_algo_length; |
| |
| /* set the attribute to empty before write data |
| sometime the files may be read only if the nvram lock is turn on |
| ex: software update when nvram lock is turned on |
| But it is not a good solution here, we should unlock it in io layer */ |
| |
| |
| openOption |= FS_CREATE; |
| #if !defined(_NAND_FLASH_BOOTING_) && !defined(__FS_SYSDRV_ON_NAND__) && !defined(__EMMC_BOOTING__) |
| openOption |= FS_PROTECTION_MODE; /* boot from NAND and single bank NOR don't support this */ |
| #endif |
| |
| #if defined(__CCCIFS_SUPPORT__) && defined(__MTK_TARGET__) |
| if (ldi->attr & NVRAM_ATTR_COMMITTED) { |
| openOption |= FS_COMMITTED; |
| } |
| #endif |
| |
| if (!nvram_util_has_file_created(ldi)) |
| { |
| //prepare header data and write header |
| //nvram_prepare_data_header(ldi, ldi_hd_buffer); |
| if (KAL_FALSE == nvram_write_data_header(ldi, LDI_HEADER_ALL_SECTION)) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_header fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_ERROR_LOC_NVCACHE_ERRNO_WRITE_HEADER_FAIL; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| } |
| |
| //Get appdenix header info |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) { |
| ldi->append_buffer = get_ctrl_buffer(rec_amount * nvram_chksum_size); |
| } |
| |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if ((ldi->attr & NVRAM_ATTR_MSP)||(ldi->attr & NVRAM_ATTR_CONFIDENTIAL)) { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| } |
| #else |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) { |
| /* 16 byte alignment */ |
| remainLen = NVRAM_MSP_ALIGNMENT_REMAINDER(rec_size + nvram_chksum_size); |
| } |
| #endif |
| |
| section_size = rec_size + nvram_chksum_size + remainLen; |
| working_buffer_size = section_size * rec_amount; |
| if (working_buffer_size > MAX_NVRAM_RECORD_SIZE) { |
| working_buffer_size = MAX_NVRAM_RECORD_SIZE; |
| } |
| |
| working_buffer = (kal_uint8*) get_ctrl_buffer(working_buffer_size); |
| chksum = (kal_uint8*) get_ctrl_buffer(nvram_chksum_size); |
| |
| if(NVRAM_IO_ERRNO_OK !=(result = get_lid_record_cache_offset(ldi, rec_index, section_size, &cache_offset))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->get_lid_record_cache_offset fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| temp_cache_offset = cache_offset; |
| |
| if (!(ldi->attr & NVRAM_ATTR_MSP) && !(ldi->attr & NVRAM_ATTR_CONFIDENTIAL) && |
| buffer != NVRAM_EF_ZERO_DEFAULT && buffer != NVRAM_EF_FF_DEFAULT) |
| { |
| |
| for(i = 0; i < rec_amount; i++) |
| { |
| if (ldi->attr & NVRAM_ATTR_MULTI_DEFAULT) |
| { |
| //rec_index start from 1 |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, buffer + (i+rec_index-1)*rec_size, rec_size,chksum); |
| kal_mem_cpy(working_buffer + i*(rec_size + nvram_chksum_size), buffer + (i+rec_index-1)*rec_size, rec_size); |
| kal_mem_cpy(working_buffer + i*(rec_size + nvram_chksum_size)+rec_size, chksum, nvram_chksum_size); |
| } |
| else |
| { |
| if (i==0) |
| { |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, buffer, rec_size,chksum); |
| } |
| kal_mem_cpy(working_buffer + i*(rec_size + nvram_chksum_size), buffer, rec_size); |
| kal_mem_cpy(working_buffer + i*(rec_size + nvram_chksum_size)+rec_size, chksum, nvram_chksum_size); |
| } |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| |
| if (i == (rec_amount - 1)) |
| { |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, working_buffer, section_size * rec_amount, cache_offset))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| |
| mask_dirty_bit_by_ltable_entry(ldi, rec_index, rec_amount); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index, rec_amount); |
| |
| } |
| } |
| goto final; |
| } |
| |
| rec_in_block = 0; |
| max_rec_amount = working_buffer_size / section_size; |
| |
| for (i = 0; i < rec_amount; i ++) |
| { |
| nvram_drv_fat_prepare_data(working_buffer + rec_in_block * section_size, buffer, (i+rec_index-1) * rec_size, rec_size); |
| kal_mem_set(chksum, 0, nvram_chksum_size); |
| nvram_util_caculate_checksum(ldi, working_buffer + rec_in_block * section_size, rec_size, chksum); |
| |
| kal_mem_cpy(working_buffer + rec_in_block * section_size + rec_size, chksum, nvram_chksum_size); |
| |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)chksum, nvram_chksum_size); |
| } |
| |
| if (remainLen) |
| { |
| kal_mem_set(working_buffer + rec_in_block * section_size + rec_size + nvram_chksum_size , 0x00, remainLen); |
| } |
| if (ldi->attr & NVRAM_ATTR_CONFIDENTIAL) |
| { |
| //custom_nvram_encrypt(nvram_ptr->secret_key, working_buffer + rec_in_block * section_size, rec_size, rec_size); |
| nvram_AES_encrypt(working_buffer + rec_in_block * section_size, section_size); |
| } |
| #ifdef __NVRAM_BIND_TO_CHIP_CIPHER__ |
| if (ldi->attr & NVRAM_ATTR_MSP) |
| { |
| /* this solution is only for work arround */ |
| #if (defined(__SMART_PHONE_MODEM__) || defined(__CCCIFS_SUPPORT__)) |
| kal_uint8 *working_buffer2 = (kal_uint8*) get_ctrl_buffer(section_size); |
| kal_uint8 *working_buffer3 = (kal_uint8*) get_ctrl_buffer(section_size); |
| //copy the original data from working_buffer to working_buffer2 |
| memcpy(working_buffer2, working_buffer + rec_in_block * section_size, section_size); |
| |
| do |
| { |
| nvram_trace_to_file(__LINE__, 999, 0, 0, 0, 0); |
| nvram_trace_to_file(nvram_ptr->secret_key[0], nvram_ptr->secret_key[1], nvram_ptr->secret_key[2], nvram_ptr->secret_key[3], 0, 0); |
| nvram_trace_to_file(working_buffer[rec_in_block*section_size], working_buffer[rec_in_block*section_size + 1], working_buffer[rec_in_block*section_size + 2], working_buffer[rec_in_block*section_size + 3], 0, 0); |
| |
| //encrypt working_buffer |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer + rec_in_block * section_size, section_size, nvram_ptr->secret_key, working_buffer + rec_in_block * section_size); |
| nvram_trace_to_file(working_buffer[rec_in_block*section_size], working_buffer[rec_in_block*section_size + 1], working_buffer[rec_in_block*section_size + 2], working_buffer[rec_in_block*section_size + 3], 0, 0); |
| |
| //copy the encrypted data from working_buffer to working_buffer3 |
| memcpy(working_buffer3, working_buffer + rec_in_block * section_size, section_size); |
| //decrypt the working_buffer3 |
| SST_Secure_Algo(NVRAM_MSP_DECRYPT, (kal_uint32)working_buffer3, section_size, nvram_ptr->secret_key, working_buffer3); |
| |
| //compare the data between the working_buffer2 & working_buffer3 |
| if (memcmp(working_buffer2, working_buffer3, section_size) == 0) |
| { |
| //encrypt PASS |
| break; |
| } |
| else |
| { |
| //encrypt FAIL, try again, WTF |
| memcpy(working_buffer + rec_in_block * section_size, working_buffer2, section_size); |
| } |
| }while(1); |
| |
| free_ctrl_buffer(working_buffer2); |
| free_ctrl_buffer(working_buffer3); |
| working_buffer2 = NULL; |
| working_buffer3 = NULL; |
| #else |
| SST_Secure_Algo(NVRAM_MSP_ENCRYPT, (kal_uint32)working_buffer + rec_in_block * section_size, section_size, nvram_ptr->secret_key, working_buffer + rec_in_block * section_size); |
| |
| #endif |
| } |
| #endif |
| |
| /* if this is not multi default, no need to prepare data anymore */ |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| break; |
| } |
| |
| rec_in_block ++; |
| |
| if (rec_in_block == max_rec_amount || i == rec_amount - 1) |
| { |
| result = nvram_write_data_to_cache(ldi, working_buffer, section_size * rec_in_block, temp_cache_offset); |
| if (NVRAM_IO_ERRNO_OK != result) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->vram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| |
| mask_dirty_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| mask_valid_bit_by_ltable_entry(ldi, temp_rec_index, rec_in_block); |
| temp_cache_offset += section_size * rec_in_block; |
| temp_rec_index += rec_in_block; |
| |
| rec_in_block = 0; |
| } |
| } |
| |
| /* special handling for not multi default */ |
| if (!(ldi->attr & NVRAM_ATTR_MULTI_DEFAULT)) |
| { |
| for (i = 0; i < rec_amount; i++) |
| { |
| //record integrated checksum |
| if((ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) && ldi->append_buffer) { |
| kal_mem_cpy((void *)(ldi->append_buffer + (i* nvram_chksum_size)), (void *)(working_buffer+rec_size), nvram_chksum_size); |
| } |
| temp_cache_offset = cache_offset + section_size * i; |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, working_buffer, section_size, temp_cache_offset))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| goto final; |
| } |
| mask_dirty_bit_by_ltable_entry(ldi, rec_index+i, 1); |
| mask_valid_bit_by_ltable_entry(ldi, rec_index+i, 1); |
| } |
| } |
| |
| final: |
| |
| if(result == NVRAM_IO_ERRNO_OK) |
| { |
| do |
| { |
| //write-back appdenix header info |
| if(ldi->attr & NVRAM_ATTR_CHKSUM_INTEGRATE) |
| { |
| //Write appendix header |
| nvram_prepare_appendix_header(NVRAM_APPEND_TYPE_CHKSUM, (nvram_ldi_appendix_header*)(&ota_header), ldi, NVRAM_LDI_APPENDIX_HEADER_SIZE); |
| |
| if(NVRAM_IO_ERRNO_OK != (result = get_lid_cache_base_address(ldi, &cache_offset))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->get_lid_cache_base_address fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, &ota_header, NVRAM_LDI_APPENDIX_HEADER_SIZE, (cache_offset + ldi->append_offset)))) |
| { |
| kal_prompt_trace(MOD_NVRAM, "NVRAM appendix header write fail:0x%x\n\r", result); |
| kal_prompt_trace(MOD_NVRAM, "category:0x%x, attr:0x%x\n\r", ldi->category, ldi->attr); |
| kal_prompt_trace(MOD_NVRAM, "fileprefix:%s, fileverno:%s\n\r", ldi->fileprefix, ldi->fileverno); |
| kal_prompt_trace(MOD_NVRAM, "cache_offset:%d\n\r", cache_offset); |
| |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"NVRAM appendix header write fail:0x%x\r\n", result); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"category:0x%08X, attr:0x%08X\r\n", ldi->category, ldi->attr); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"fileprefix:%s, fileverno:%s\r\n", ldi->fileprefix, ldi->fileverno); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"cache_offset:%d\r\n", cache_offset); |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| if(NVRAM_IS_ATTR_FAULT_ASSERT(ldi->attr)) |
| { |
| if(ldi->append_buffer) |
| { |
| free_ctrl_buffer(ldi->append_buffer); |
| ldi->append_buffer = NULL; |
| } |
| if (working_buffer) |
| { |
| free_ctrl_buffer(working_buffer); |
| working_buffer = NULL; |
| } |
| NVRAM_EXT_ASSERT(KAL_FALSE, (kal_uint32)result, NVRAM_ERROR_LOC_NVCACHE_ERRNO_WRITE_HEADER_FAIL, ldi->LID); |
| } |
| } |
| |
| //write-back appdenix header info |
| if(ldi->append_offset == 0) |
| { |
| ldi->append_offset = nvram_appendix_header_offset(ldi); |
| } |
| |
| if(ldi->append_offset > 0) |
| { |
| |
| cache_offset = cache_offset + (ldi->append_offset + NVRAM_LDI_APPENDIX_HEADER_SIZE + ((rec_index - 1) * nvram_chksum_size)); |
| |
| if (NVRAM_IO_ERRNO_OK != (result = nvram_write_data_to_cache(ldi, (kal_uint8*)ldi->append_buffer, (rec_amount * nvram_chksum_size), cache_offset))) |
| { |
| NVRAM_DEBUG_DUMP(NVRAM_CRITICAL_DUMP,"[Error]%s->nvram_write_data_to_cache fail at %d,result=%d\r\n",__FUNCTION__,__LINE__,result); |
| result = NVRAM_DRV_INVALID_RECORD_ID; |
| nvram_fat_last_line = __LINE__; |
| break; |
| } |
| } |
| |
| } |
| }while(0); |
| } |
| |
| if(ldi->append_buffer) |
| { |
| free_ctrl_buffer(ldi->append_buffer); |
| ldi->append_buffer = NULL; |
| } |
| if (working_buffer) |
| { |
| free_ctrl_buffer(working_buffer); |
| working_buffer = NULL; |
| } |
| |
| if (chksum) |
| { |
| free_ctrl_buffer(chksum); |
| chksum = NULL; |
| } |
| |
| #if defined(__NVRAM_ACCESS_TIMEOUT_ASSERT__) |
| DclSGPT_Control(nvram_gpt_handle, SGPT_CMD_STOP, (DCL_CTRL_DATA_T*)NULL); //stop timer |
| #endif |
| |
| if (NVRAM_IO_ERRNO_OK != result) { |
| nvram_fat_last_err = result; |
| MD_TRC_FUNC_NVRAM_DRV_FAT_THROW_EXCEPTION(nvram_fat_last_err, nvram_fat_last_line); |
| return result; |
| } |
| |
| nvram_cache_enqueue(ldi, rec_index, rec_amount, openOption); |
| |
| send_event_to_nvram_cache(); |
| |
| return NVRAM_DRV_OK; |
| } |
| #endif |
| |