|  | #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; | 
|  | } | 
|  |  |