blob: cff6cfef3deadae5cda048e3da430dff479b5353 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <string.h>
#include <unistd.h>
#include <linux/cpnv.h>
#include "cfg_api.h"
#include "libcpnv.h"
#define CP_NV_DEV "/dev/cpnv"
static char *cpnv_fs_mount_point[] = {"/mnt/imagefs", "/mnt/resource", "/mnt/nvrofs"};
static int cpnv_dev_fd = -1;
static int lib_init(void)
{
int fd = open(CP_NV_DEV, O_RDWR);
if (fd < 0) {
perror("open cpnv dev fd fail\n");
assert(fd > 0);
}
return fd;
}
static unsigned int cpnv_write(int direction, unsigned int NvItemID, unsigned char *NvItemData, unsigned int NvItemLen)
{
int ret;
unsigned char buffer[128];
unsigned char *tmpbuf = buffer;
size_t tmpbuf_len = sizeof(buffer);
struct cpnv_readwrite_head *phead;
//assert(NvItemID > 0);
assert(NvItemData != NULL);
assert(NvItemLen > 0);
if (cpnv_dev_fd < 0)
cpnv_dev_fd = lib_init();
if (NvItemLen + sizeof(struct cpnv_readwrite_head) > sizeof(buffer)) {
tmpbuf_len = NvItemLen + sizeof(struct cpnv_readwrite_head);
tmpbuf = malloc(tmpbuf_len);
if (tmpbuf == NULL)
return CPNV_ERROR;
}
phead = (struct cpnv_readwrite_head *)tmpbuf;
phead->direction = direction;
phead->NvItemID = NvItemID;
phead->NvItemLen = NvItemLen;
memcpy(phead->NvItemData, NvItemData, NvItemLen);
ret = write(cpnv_dev_fd, tmpbuf, tmpbuf_len);
if (ret == tmpbuf_len) {
ret = CPNV_OK;
} else {
perror("cpnv write error\n");
ret = CPNV_ERROR;
}
if (tmpbuf != buffer)
free(tmpbuf);
return ret;
}
unsigned int cpnv_NvItemWrite(unsigned int NvItemID, unsigned char *NvItemData, unsigned int NvItemLen)
{
return cpnv_write(TO_NVRW, NvItemID, NvItemData, NvItemLen);
}
void cpnv_NvItemWriteFactory(unsigned int NvItemID, unsigned char *NvItemData, unsigned int NvItemLen)
{
cpnv_write(TO_NVFAC, NvItemID, NvItemData, NvItemLen);
}
unsigned int cpnv_NvItemWriteNvro(unsigned int NvItemID, unsigned char *NvItemData, unsigned int NvItemLen)
{
return cpnv_write(TO_NVRO, NvItemID, NvItemData, NvItemLen);
}
unsigned int cpnv_NvItemRead(unsigned int NvItemID, unsigned char *NvItemData, unsigned int NvItemLen)
{
int ret;
unsigned char *tmpbuf = NvItemData;
int tmpbuf_len = NvItemLen;
//assert(NvItemID > 0);
assert(NvItemData != NULL);
assert(NvItemLen > 0);
if (cpnv_dev_fd < 0)
cpnv_dev_fd = lib_init();
if (NvItemLen < sizeof(NvItemID)) {
tmpbuf_len = sizeof(NvItemID);
tmpbuf = malloc(tmpbuf_len);
if (tmpbuf == NULL)
return CPNV_ERROR;
}
memcpy(tmpbuf, &NvItemID, sizeof(NvItemID));
ret = read(cpnv_dev_fd, tmpbuf, tmpbuf_len);
if (ret > 0) {
memcpy(NvItemData, tmpbuf, NvItemLen);
ret = CPNV_OK;
} else {
perror("cpnv read error\n");
bzero(NvItemData, NvItemLen);
ret = CPNV_ERROR;
}
if (tmpbuf != NvItemData)
free(tmpbuf);
return ret;
}
unsigned int cpnv_NvramFlush(void)
{
int ret = CPNV_OK;
if (cpnv_dev_fd < 0)
cpnv_dev_fd = lib_init();
ret = ioctl(cpnv_dev_fd, CPNV_IOIOCTL_FLUSH);
if (ret < 0) {
perror("cpnv ioctrl error\n");
ret = CPNV_ERROR;
}
return ret;
}
unsigned int cpnv_ResetNVFactory(void)
{
int ret = CPNV_OK;
if (cpnv_dev_fd < 0)
cpnv_dev_fd = lib_init();
ret = ioctl(cpnv_dev_fd, CPNV_IOIOCTL_RESETNVFACTORY);
if (ret < 0) {
perror("cpnv ioctrl error\n");
ret = CPNV_ERROR;
}
return (unsigned int)ret;
}
unsigned int cpnv_ChangeFsPartitionAttr(int partition_no, int writable)
{
char cmd[64] = {0};
int ret = 0;
if(partition_no >= FS_PARTITION_NO_MAX)
return CPNV_ERROR;
if(writable)
snprintf(cmd, 64, "/bin/mount -o remount,%s %s", "rw", cpnv_fs_mount_point[partition_no]);
else
snprintf(cmd, 64, "/bin/mount -o remount,%s %s", "ro", cpnv_fs_mount_point[partition_no]);
ret = zxic_system(cmd);
if(0 == ret)
return CPNV_OK;
else
return CPNV_ERROR;
}
unsigned int cpnv_ChangeNvRoAttr(int writable)
{
return cpnv_ChangeFsPartitionAttr(FS_NVROFS, writable);
}
unsigned int cpnv_FsGcWait(int partition_no)
{
int ret = CPNV_ERROR;
switch(partition_no)
{
case FS_IMAGEFS:
case FS_RESOURCEFS:
case FS_NVROFS:
syscall(SYSCALL_jffs2_quick_gc_wait_done, partition_no);
ret = CPNV_OK;
break;
default:
ret = CPNV_ERROR;
}
return ret;
}