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