xf.li | aa4d92f | 2023-09-13 00:18:58 -0700 | [diff] [blame] | 1 | #define _GNU_SOURCE |
| 2 | #include <stdio.h> |
| 3 | #include <stdlib.h> |
| 4 | #include <unistd.h> |
| 5 | #include <string.h> |
| 6 | #include <sys/types.h> |
| 7 | #include <sys/stat.h> |
| 8 | #include <fcntl.h> |
| 9 | #include <sys/vfs.h> |
| 10 | |
| 11 | |
| 12 | #include <mtd/mtd-abi.h> |
| 13 | #include <errno.h> |
| 14 | |
| 15 | #include <sys/ioctl.h> |
| 16 | #include "mtd.h" |
| 17 | |
| 18 | |
| 19 | int mtd_find(const char *i_parti_name, char *o_mtd_path, device_type_t device_type, unsigned int o_mtd_path_len) |
| 20 | { |
| 21 | FILE *fd_mtd = 0; |
| 22 | char buf[128]; |
| 23 | char *line_str; |
| 24 | |
| 25 | if (!o_mtd_path_len) |
| 26 | return -1; |
| 27 | |
| 28 | fd_mtd = fopen("/proc/mtd", "r+"); |
| 29 | if (NULL == fd_mtd) { |
| 30 | printf("fs_check open file error:%s", strerror(errno)); |
| 31 | //sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open file error:%s", strerror(errno)); |
| 32 | goto error0; |
| 33 | } |
| 34 | //printf("fs_check partition name:%s\n", i_parti_name); |
| 35 | |
| 36 | while (1) { |
| 37 | int matches = 0; |
| 38 | char mtdname[64] = {0}; |
| 39 | int mtdnum = 0; |
| 40 | unsigned int mtdsize, mtderasesize; |
| 41 | memset(buf, 0x00, sizeof(buf)); |
| 42 | line_str = fgets(buf, sizeof(buf), fd_mtd); |
| 43 | |
| 44 | if (NULL == line_str) { |
| 45 | printf("fs_check get info from mtd error:%s\n", strerror(errno)); |
| 46 | //sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get info from mtd error:%s\n", strerror(errno)); |
| 47 | goto error1; |
| 48 | } |
| 49 | //mtd5: 00100000 00020000 "fotaflag" |
| 50 | matches = sscanf(buf, "mtd%d: %x %x \"%63[^\"]", |
| 51 | &mtdnum, &mtdsize, &mtderasesize, mtdname); |
| 52 | mtdname[63] = '\0'; |
| 53 | |
| 54 | if ((matches == 4) && (strcmp(mtdname, i_parti_name) == 0)) { |
| 55 | memset(o_mtd_path, 0x00, o_mtd_path_len); |
| 56 | if (device_type == DEVICE_MTD_BLOCK) { |
| 57 | snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtdblock%d", mtdnum); |
| 58 | } else if (device_type == DEVICE_MTD) { |
| 59 | snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtd%d", mtdnum); |
| 60 | } else if (device_type == DEVICE_ZFTL) { |
| 61 | snprintf(o_mtd_path, o_mtd_path_len, "/dev/zftl%d", mtdnum); |
| 62 | } else { |
| 63 | printf("fs_check unknown device type %d\n", device_type); |
| 64 | //sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check unknown device type %d\n", device_type); |
| 65 | goto error1; |
| 66 | } |
| 67 | //printf("fs_check o_mtd_path=[%s]\n", o_mtd_path); |
| 68 | break; |
| 69 | } |
| 70 | |
| 71 | } |
| 72 | fclose(fd_mtd); |
| 73 | return 0; |
| 74 | |
| 75 | error1: |
| 76 | fclose(fd_mtd); |
| 77 | error0: |
| 78 | return -1; |
| 79 | } |
| 80 | |
| 81 | int mtd_erase_partition(const char* partition_name) |
| 82 | { |
| 83 | int ret = 0; |
| 84 | char mtd_path[MAX_PATH] = {0}; |
| 85 | int fd_mtd = -1; |
| 86 | |
| 87 | struct mtd_info_user meminfo = {0}; |
| 88 | struct erase_info_user64 erase_info = {0}; |
| 89 | |
| 90 | if (NULL == partition_name) { |
| 91 | return -1; |
| 92 | } |
| 93 | ret = mtd_find(partition_name, mtd_path, DEVICE_MTD, MAX_PATH); |
| 94 | if (ret < 0) { |
| 95 | printf("fs_check mtd_find %s failed\n", partition_name); |
| 96 | //sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd_find %s failed\n", partition_name); |
| 97 | ret = -1; |
| 98 | goto out; |
| 99 | } |
| 100 | fd_mtd = open(mtd_path, O_RDWR); |
| 101 | if (fd_mtd < 0) { |
| 102 | printf("fs_check open %s error, %s\n", partition_name, strerror(errno)); |
| 103 | //sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open %s error, %s\n", partition_name, strerror(errno)); |
| 104 | ret = -1; |
| 105 | goto out; |
| 106 | } |
| 107 | if (ioctl(fd_mtd, MEMGETINFO, &meminfo) != 0) { |
| 108 | printf("fs_check get %s info error, %s\n", partition_name, strerror(errno)); |
| 109 | //sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get %s info error, %s\n", partition_name, strerror(errno)); |
| 110 | ret = -1; |
| 111 | goto out; |
| 112 | } |
| 113 | erase_info.length = meminfo.erasesize; |
| 114 | for (erase_info.start = 0; erase_info.start < meminfo.size; erase_info.start += meminfo.erasesize) { |
| 115 | if (ioctl(fd_mtd, MEMGETBADBLOCK, &(erase_info.start)) > 0) { |
| 116 | printf("fs_check mtd, not erasing bad block at 0x%llx\n", erase_info.start); |
| 117 | continue; |
| 118 | } |
| 119 | if (ioctl(fd_mtd, MEMERASE64, &erase_info) < 0) { |
| 120 | printf("fs_check mtd, erasing failure at 0x%llx\n", erase_info.start); |
| 121 | } |
| 122 | } |
| 123 | ret = 0; |
| 124 | out: |
| 125 | if (fd_mtd >= 0) { |
| 126 | close(fd_mtd); |
| 127 | } |
| 128 | return ret; |
| 129 | } |