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