/*************************************************************************** * Copyright (c) 2011, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: UDTA message storage implementation * * Revision History: * * $brcm_Log: $ * * ***************************************************************************/ #include "bstd.h" #include "bkni.h" #include "bdbg.h" #include "umstore.h" #include "bfdb.h" #include "bspi_flash.h" #include "ramheader.h" BDBG_MODULE(bums); /* private structure that used by message storage interface */ struct bums_data_t { bfdb_handle db; }; static struct bums_data_t umsd; /* Flash configuration. For most flashes sector size and page size should be left at default. Offset is a starting offset of database from the beginning of the flash. DB_SIZE and DB_OFFSET must be dvisible by SECTOR_SIZE This must match settings in bapp_settings.c. Later we will consolidate. */ #define FLASH_PAGE_SIZE 0x100 #define FLASH_SECTOR_SIZE 0x10000 #define FLASH_DB_SIZE FLASH_DATA_SIZE #define FLASH_DB_OFFSET (FLASH_BOOTLOADER_SIZE + FLASH_APP0_SIZE + FLASH_APP1_SIZE) #define MEM_DB_OFFSET 0 #define MEM_DB_SIZE FLASH_DB_SIZE static bfdb_err bums_add(bfdb_handle handle, uint8_t id, uint8_t * data, size_t size); static bfdb_err bums_delete_all(bfdb_handle handle, uint8_t id); void bums_print_request(unsigned char data_id, int read); void bums_open(void) { bfdb_err dberr; struct bfdb_settings dbset; bspi_settings_t spi_settings; bresult rc; rc = bspi_identify(&spi_settings); BDBG_ASSERT(rc == b_ok); dbset.page_size = spi_settings.page_size; dbset.sector_size = spi_settings.sector_size; dbset.db_offset = FLASH_DB_OFFSET; dbset.db_size = FLASH_DB_SIZE; BKNI_Memset(&umsd, 0, sizeof(struct bums_data_t)); dberr = bfdb_open(&dbset, &umsd.db); if(BFDB_OK != dberr){ BDBG_ERR(("Error:%d line:%d\n", dberr, __LINE__)); if(BFDB_LOG_ERROR == dberr){ dberr = bfdb_erase(umsd.db); if(BFDB_OK != dberr){ BDBG_ERR(("Error:%d line:%d\n", dberr, __LINE__)); } } } } void bums_close(void) { int res; /* close store handle. database does not need closing */ res = bfds_close(umsd.db->store); if(BFDS_OK == res){ umsd.db = NULL; } } int bums_read_data(unsigned char data_id, char * data, size_t size) { int err; bfdb_err dberr; err = BUMS_ERROR; bums_print_request(data_id, 1); dberr = bfdb_rewind(umsd.db, data_id); if(BFDB_OK == dberr){ dberr = bfdb_get(umsd.db, data, size); if(BFDB_OK != dberr){ BDBG_ERR(("Error:%d line:%d\n", dberr, __LINE__)); goto ExitFunc; } err = BUMS_OK; } ExitFunc: return err; } int bums_write_data(unsigned char data_id, char * data, size_t size) { int err; bfdb_err dberr; err = BUMS_ERROR; bums_print_request(data_id, 0); dberr = bums_delete_all(umsd.db, data_id); if(BFDB_OK != dberr){ BDBG_ERR(("Error:%d line:%d\n", dberr, __LINE__)); goto ExitFunc; } dberr = bums_add(umsd.db, data_id, data, size); if(BFDB_OK != dberr){ BDBG_ERR(("Error:%d line:%d\n", dberr, __LINE__)); } err = BUMS_OK; ExitFunc: return err; } int bums_delete_data(unsigned char data_id) { int err; bfdb_err dberr; err = BUMS_ERROR; bums_print_request(data_id, 2); dberr = bums_delete_all(umsd.db, data_id); if(BFDB_OK != dberr){ BDBG_ERR(("Error:%d line:%d\n", dberr, __LINE__)); goto ExitFunc; } err = BUMS_OK; ExitFunc: return err; } /* add with compact if add fails */ bfdb_err bums_add(bfdb_handle handle, uint8_t id, uint8_t * data, size_t size) { bfdb_err dberr; do { dberr = bfdb_add(handle, id, data, size); if(BFDB_LOG_FULL == dberr){ dberr = bfdb_compact(handle); if(BFDB_OK == dberr){ dberr = BFDB_LOG_FULL; } } } while(BFDB_LOG_FULL == dberr); return dberr; } bfdb_err bums_delete_all(bfdb_handle handle, uint8_t id) { bfdb_err dberr; dberr = bfdb_rewind(handle, id); switch(dberr){ case BFDB_OK: /* we have records in database, delete them */ do{ dberr = bfdb_delete(handle); if(BFDB_OK != dberr){ BDBG_ERR(("Error:%d line:%d\n", dberr, __LINE__)); goto ExitFunc; } dberr = bfdb_next(handle, id); }while(BFDB_OK == dberr); case BFDB_RECORD_NOT_FOUND: dberr = BFDB_OK; break; default: BDBG_ERR(("Error:%d line:%d\n", dberr, __LINE__)); } ExitFunc: return dberr; } static char * request_string[] = { "CA_SYS_ID", }; void bums_print_request(unsigned char data_id, int read) { int idx; char * action; idx = data_id - BUMS_ID_START; if(idx > (BUMS_ID_LAST - BUMS_ID_START)){ BDBG_ERR(("Incorrect ID requested")); } switch(read){ case 0: action = "write"; break; case 1: action = "read"; break; case 2: action = "erase"; break; } BKNI_Printf("Request to %s %s\n", action, request_string[idx]); } bfdb_handle bast_getdb(void) { return umsd.db; }