#include #include #include #include #include #include #include #include #include #include #include "mtd_part.h" #include #define NB_PART_DESCS (8) struct mtd_part_desc { char device[16]; size_t offset; size_t size; int fd; }; struct mtd_part_desc mtd_part_descs[NB_PART_DESCS]; void mtd_part_init(void) { int i; for (i=0;i=0) i++; if (i>=NB_PART_DESCS) return ERROR; mtd_part_descs[i].fd = 0; if (f=fopen("/proc/mtd","rt")) { char *newname; unsigned long size; char *p; newname = malloc(strlen(name)+3); sprintf(newname,"\"%s\"",name); sprintf(mtd_part_descs[i].device,""); while (fgets(buffer,sizeof(buffer),f)) { if (p=strchr(buffer,':')) { *p++ = '\0'; *p++; // skip space size = strtoul(p,NULL,16); if (strstr(p,newname)) { sprintf(mtd_part_descs[i].device,"/dev/%s",buffer); mtd_part_descs[i].offset = offset; break; } else offset += size; } } fclose(f); free(newname); if (strcmp(mtd_part_descs[i].device,"")) { if ((mtd_part_descs[i].fd=open(mtd_part_descs[i].device,O_RDWR))>=0) { if (ioctl(mtd_part_descs[i].fd,MEMGETINFO,&mtd_info)>=0) mtd_part_descs[i].size = mtd_info.size; return i; } else { perror("open"); mtd_part_descs[i].fd = -1; return ERROR; } } else { mtd_part_descs[i].fd = -1; return ERROR; } } else return ERROR; } size_t mtd_part_offset(int part) { if (part>=0 && part=0) return mtd_part_descs[part].offset; else return 0; } else return 0; } size_t mtd_part_size(int part) { if (part>=0 && part=0) return mtd_part_descs[part].size; else return 0; } else return 0; } int mtd_part_read(int part, caddr_t address, uint8_t *data, size_t size) { if (lseek(mtd_part_descs[part].fd,(off_t)address,SEEK_SET)>=0) { return read(mtd_part_descs[part].fd,data,size)>=0?OK:ERROR; } else return ERROR; } int mtd_part_write(int part, caddr_t address, uint8_t *data, size_t size) { if (lseek(mtd_part_descs[part].fd,(off_t)address,SEEK_SET)>=0) { return write(mtd_part_descs[part].fd,data,size)>=0?OK:ERROR; } else return ERROR; } int mtd_part_get_area(int part, caddr_t *address, size_t *size) { struct mtd_info_user mtd_info; int region_count; struct region_info_user *region_infos; caddr_t topaddr; int i; if (ioctl(mtd_part_descs[part].fd,MEMGETINFO,&mtd_info)>=0) { if (ioctl(mtd_part_descs[part].fd,MEMGETREGIONCOUNT,®ion_count)>=0 && region_count>0) { region_infos = calloc(region_count,sizeof(struct region_info_user)); for(i=0;i=region_infos[i].offset+region_infos[i].numblocks*region_infos[i].erasesize)) i++; if (i=region_infos[i].offset+region_infos[i].numblocks*region_infos[i].erasesize)) i++; if (i