diff options
-rw-r--r-- | firmware/drivers/fat.c | 217 | ||||
-rw-r--r-- | firmware/drivers/fat.h | 19 | ||||
-rw-r--r-- | firmware/test/fat/ata-sim.c | 19 | ||||
-rw-r--r-- | firmware/test/fat/main.c | 21 | ||||
-rw-r--r-- | firmware/test/fat/test.sh | 39 |
5 files changed, 208 insertions, 107 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 40f9c47fa7..4c3e410c1a 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -455,11 +455,13 @@ static int update_fat_entry(unsigned int entry, unsigned int val) | |||
455 | 455 | ||
456 | LDEBUGF("update_fat_entry(%x,%x)\n",entry,val); | 456 | LDEBUGF("update_fat_entry(%x,%x)\n",entry,val); |
457 | 457 | ||
458 | #ifdef TEST_FAT | ||
458 | if (entry==val) | 459 | if (entry==val) |
459 | panicf("Creating FAT loop: %x,%x\n",entry,val); | 460 | panicf("Creating FAT loop: %x,%x\n",entry,val); |
460 | 461 | ||
461 | if ( entry < 2 ) | 462 | if ( entry < 2 ) |
462 | panicf("Updating reserved FAT entry %d.\n",entry); | 463 | panicf("Updating reserved FAT entry %d.\n",entry); |
464 | #endif | ||
463 | 465 | ||
464 | sec = cache_fat_sector(sector); | 466 | sec = cache_fat_sector(sector); |
465 | if (!sec) | 467 | if (!sec) |
@@ -636,6 +638,12 @@ static int add_dir_entry(struct fat_dir* dir, | |||
636 | if (sec_cnt >= fat_bpb.bpb_secperclus) | 638 | if (sec_cnt >= fat_bpb.bpb_secperclus) |
637 | { | 639 | { |
638 | int oldcluster; | 640 | int oldcluster; |
641 | |||
642 | /* we're not adding a whole new sector | ||
643 | just for the end-of-dir marker */ | ||
644 | if ( need_to_update_last_empty_marker ) | ||
645 | break; | ||
646 | |||
639 | if (!currdir) | 647 | if (!currdir) |
640 | currdir = sec2cluster(fat_bpb.rootdirsector); | 648 | currdir = sec2cluster(fat_bpb.rootdirsector); |
641 | oldcluster = currdir; | 649 | oldcluster = currdir; |
@@ -647,17 +655,35 @@ static int add_dir_entry(struct fat_dir* dir, | |||
647 | { | 655 | { |
648 | /* end of dir, add new cluster */ | 656 | /* end of dir, add new cluster */ |
649 | LDEBUGF("Adding cluster to dir\n"); | 657 | LDEBUGF("Adding cluster to dir\n"); |
650 | currdir = find_free_cluster(fat_bpb.fsinfo.nextfree); | 658 | currdir = find_free_cluster(oldcluster+1); |
651 | if (!currdir) { | 659 | if (!currdir) { |
652 | DEBUGF("add_dir_entry(): Disk full!\n"); | 660 | DEBUGF("add_dir_entry(): Disk full!\n"); |
653 | return -1; | 661 | return -1; |
654 | } | 662 | } |
655 | update_fat_entry(oldcluster, currdir); | 663 | update_fat_entry(oldcluster, currdir); |
664 | update_fat_entry(currdir, FAT_EOF_MARK); | ||
656 | new = true; | 665 | new = true; |
657 | memset(buf, 0, sizeof buf); | 666 | memset(buf, 0, sizeof buf); |
667 | |||
668 | /* clear remaining sectors in this cluster */ | ||
669 | if (fat_bpb.bpb_secperclus > 1) { | ||
670 | int i; | ||
671 | sec = cluster2sec(currdir); | ||
672 | for (i=1; i<fat_bpb.bpb_secperclus; i++ ) { | ||
673 | err = ata_write_sectors(sec + fat_bpb.startsector + i, | ||
674 | 1, buf); | ||
675 | if (err) { | ||
676 | DEBUGF( "add_dir_entry() - " | ||
677 | " Couldn't write dir" | ||
678 | " sector (error code %d)\n", err); | ||
679 | return -3; | ||
680 | } | ||
681 | } | ||
682 | } | ||
658 | } | 683 | } |
659 | LDEBUGF("new cluster is %x\n", currdir); | 684 | LDEBUGF("new cluster is %x\n", currdir); |
660 | sec = cluster2sec(currdir); | 685 | sec = cluster2sec(currdir); |
686 | sec_cnt = 0; | ||
661 | } | 687 | } |
662 | 688 | ||
663 | if (!new) { | 689 | if (!new) { |
@@ -714,6 +740,7 @@ static int add_dir_entry(struct fat_dir* dir, | |||
714 | /* We must fill in the first entry | 740 | /* We must fill in the first entry |
715 | in the next sector */ | 741 | in the next sector */ |
716 | need_to_update_last_empty_marker = true; | 742 | need_to_update_last_empty_marker = true; |
743 | LDEBUGF("need_to_update_last_empty\n"); | ||
717 | } | 744 | } |
718 | } | 745 | } |
719 | else | 746 | else |
@@ -907,13 +934,13 @@ int fat_open(unsigned int startcluster, | |||
907 | { | 934 | { |
908 | file->firstcluster = startcluster; | 935 | file->firstcluster = startcluster; |
909 | file->lastcluster = startcluster; | 936 | file->lastcluster = startcluster; |
910 | file->lastsector = cluster2sec(startcluster); | 937 | file->lastsector = 0; |
911 | file->sectornum = 0; | 938 | file->sectornum = 0; |
912 | 939 | ||
913 | /* remember where the file's dir entry is located */ | 940 | /* remember where the file's dir entry is located */ |
914 | file->dirsector = dir->cached_sec; | 941 | file->dirsector = dir->cached_sec; |
915 | file->direntry = (dir->entry % DIR_ENTRIES_PER_SECTOR) - 1; | 942 | file->direntry = (dir->entry % DIR_ENTRIES_PER_SECTOR) - 1; |
916 | LDEBUGF("fat_open: entry %d\n",file->direntry); | 943 | LDEBUGF("fat_open(%x), entry %d\n",startcluster,file->direntry); |
917 | return 0; | 944 | return 0; |
918 | } | 945 | } |
919 | 946 | ||
@@ -952,7 +979,7 @@ int fat_closewrite(struct fat_file *file, int size) | |||
952 | int next, last = file->lastcluster; | 979 | int next, last = file->lastcluster; |
953 | int endcluster = last; | 980 | int endcluster = last; |
954 | 981 | ||
955 | LDEBUGF("fat_closewrite()\n"); | 982 | LDEBUGF("fat_closewrite(%d)\n",size); |
956 | 983 | ||
957 | last = get_next_cluster(last); | 984 | last = get_next_cluster(last); |
958 | while ( last && last != FAT_EOF_MARK ) { | 985 | while ( last && last != FAT_EOF_MARK ) { |
@@ -961,10 +988,32 @@ int fat_closewrite(struct fat_file *file, int size) | |||
961 | last = next; | 988 | last = next; |
962 | } | 989 | } |
963 | 990 | ||
964 | update_fat_entry(endcluster, FAT_EOF_MARK); | 991 | if ( !size ) { |
992 | /* empty file */ | ||
993 | update_fat_entry(file->firstcluster, 0); | ||
994 | file->firstcluster = 0; | ||
995 | } | ||
996 | else | ||
997 | update_fat_entry(endcluster, FAT_EOF_MARK); | ||
965 | update_dir_entry(file, size); | 998 | update_dir_entry(file, size); |
966 | flush_fat(); | 999 | flush_fat(); |
967 | 1000 | ||
1001 | #ifdef TEST_FAT | ||
1002 | { | ||
1003 | /* debug */ | ||
1004 | int count = 0; | ||
1005 | int len; | ||
1006 | for ( next = file->firstcluster; next; | ||
1007 | next = get_next_cluster(next) ) | ||
1008 | LDEBUGF("cluster %d: %x\n", count++, next); | ||
1009 | len = count * fat_bpb.bpb_secperclus * SECTOR_SIZE; | ||
1010 | LDEBUGF("File is %d clusters (chainlen=%d, size=%d)\n", | ||
1011 | count, len, size ); | ||
1012 | if ( len > size + fat_bpb.bpb_secperclus * SECTOR_SIZE) | ||
1013 | panicf("Cluster chain is too long\n"); | ||
1014 | } | ||
1015 | #endif | ||
1016 | |||
968 | return 0; | 1017 | return 0; |
969 | } | 1018 | } |
970 | 1019 | ||
@@ -999,33 +1048,41 @@ int fat_read( struct fat_file *file, int sectorcount, void* buf ) | |||
999 | if ( sector == -1 ) | 1048 | if ( sector == -1 ) |
1000 | return 0; | 1049 | return 0; |
1001 | 1050 | ||
1002 | first = last = sector; | ||
1003 | |||
1004 | /* find sequential sectors and read/write them all at once */ | 1051 | /* find sequential sectors and read/write them all at once */ |
1005 | for (i=0; i<sectorcount && sector>=0; i++ ) { | 1052 | for (i=0; i<sectorcount && sector>=0; i++ ) { |
1006 | numsec++; | 1053 | numsec++; |
1007 | if ( numsec >= fat_bpb.bpb_secperclus ) { | 1054 | if ( numsec > fat_bpb.bpb_secperclus ) { |
1008 | cluster = get_next_cluster(cluster); | 1055 | cluster = get_next_cluster(cluster); |
1009 | if (!cluster) { | 1056 | if (!cluster) { |
1010 | /* reading past end-of-file */ | 1057 | /* reading past end-of-file */ |
1011 | sector = -1; | 1058 | sector = -1; |
1012 | } | 1059 | } |
1013 | 1060 | ||
1014 | if (cluster) { | 1061 | if (cluster) { |
1015 | sector = cluster2sec(cluster); | 1062 | sector = cluster2sec(cluster); |
1016 | LDEBUGF("cluster2sec(%x) == %x\n",cluster,sector); | 1063 | LDEBUGF("cluster2sec(%x) == %x\n",cluster,sector); |
1017 | if (sector<0) | 1064 | if (sector<0) |
1018 | return -1; | 1065 | return -1; |
1019 | numsec=0; | 1066 | numsec=1; |
1020 | } | 1067 | } |
1021 | } | 1068 | } |
1022 | else | 1069 | else { |
1023 | sector++; | 1070 | if (sector) |
1024 | 1071 | sector++; | |
1025 | if ( (sector != last+1) || /* not sequential any more? */ | 1072 | else { |
1073 | sector = cluster2sec(file->firstcluster); | ||
1074 | numsec=1; | ||
1075 | } | ||
1076 | } | ||
1077 | |||
1078 | if (!first) | ||
1079 | first = sector; | ||
1080 | |||
1081 | if ( ((sector != first) && (sector != last+1)) || | ||
1082 | /* not sequential any more? */ | ||
1026 | (i == sectorcount-1) || /* last sector requested? */ | 1083 | (i == sectorcount-1) || /* last sector requested? */ |
1027 | (last-first+1 == 256) ) { /* max 256 sectors per ata request */ | 1084 | (sector-first+1 == 256) ) { /* max 256 sectors per ata request */ |
1028 | int count = last - first + 1; | 1085 | int count = sector - first + 1; |
1029 | int start = first + fat_bpb.startsector; | 1086 | int start = first + fat_bpb.startsector; |
1030 | LDEBUGF("s=%x, l=%x, f=%x, i=%d\n",sector,last,first,i); | 1087 | LDEBUGF("s=%x, l=%x, f=%x, i=%d\n",sector,last,first,i); |
1031 | err = ata_read_sectors(start, count, buf); | 1088 | err = ata_read_sectors(start, count, buf); |
@@ -1035,10 +1092,10 @@ int fat_read( struct fat_file *file, int sectorcount, void* buf ) | |||
1035 | return -2; | 1092 | return -2; |
1036 | } | 1093 | } |
1037 | ((char*)buf) += count * SECTOR_SIZE; | 1094 | ((char*)buf) += count * SECTOR_SIZE; |
1038 | first = sector; | 1095 | first = 0; |
1039 | } | 1096 | } |
1040 | last = sector; | 1097 | last = sector; |
1041 | } | 1098 | } |
1042 | 1099 | ||
1043 | file->lastcluster = cluster; | 1100 | file->lastcluster = cluster; |
1044 | file->lastsector = sector; | 1101 | file->lastsector = sector; |
@@ -1047,7 +1104,41 @@ int fat_read( struct fat_file *file, int sectorcount, void* buf ) | |||
1047 | return sectorcount; | 1104 | return sectorcount; |
1048 | } | 1105 | } |
1049 | 1106 | ||
1050 | int fat_write( struct fat_file *file, int sectorcount, void* buf ) | 1107 | int next_write_cluster(struct fat_file* file, int oldcluster, int* newsector) |
1108 | { | ||
1109 | int cluster; | ||
1110 | int sector; | ||
1111 | |||
1112 | LDEBUGF("next_write_cluster(%x,%x)\n",file->firstcluster, oldcluster); | ||
1113 | |||
1114 | cluster = get_next_cluster(oldcluster); | ||
1115 | if (!cluster) { | ||
1116 | if (oldcluster) | ||
1117 | cluster = find_free_cluster(oldcluster+1); | ||
1118 | else | ||
1119 | cluster = find_free_cluster(fat_bpb.fsinfo.nextfree); | ||
1120 | |||
1121 | if (cluster) { | ||
1122 | if (oldcluster) | ||
1123 | update_fat_entry(oldcluster, cluster); | ||
1124 | else | ||
1125 | file->firstcluster = cluster; | ||
1126 | } | ||
1127 | else { | ||
1128 | DEBUGF("next_write_sector(): Disk full!\n"); | ||
1129 | return 0; | ||
1130 | } | ||
1131 | } | ||
1132 | sector = cluster2sec(cluster); | ||
1133 | if (sector<0) | ||
1134 | return 0; | ||
1135 | |||
1136 | *newsector = sector; | ||
1137 | return cluster; | ||
1138 | } | ||
1139 | |||
1140 | int fat_readwrite( struct fat_file *file, int sectorcount, | ||
1141 | void* buf, bool write ) | ||
1051 | { | 1142 | { |
1052 | int cluster = file->lastcluster; | 1143 | int cluster = file->lastcluster; |
1053 | int sector = file->lastsector; | 1144 | int sector = file->lastsector; |
@@ -1062,53 +1153,50 @@ int fat_write( struct fat_file *file, int sectorcount, void* buf ) | |||
1062 | return 0; | 1153 | return 0; |
1063 | 1154 | ||
1064 | /* find sequential sectors and write them all at once */ | 1155 | /* find sequential sectors and write them all at once */ |
1065 | for (i=0; i<sectorcount && sector>=0; i++ ) { | 1156 | for (i=0; i<sectorcount; i++ ) { |
1066 | numsec++; | 1157 | numsec++; |
1067 | 1158 | if ( numsec > fat_bpb.bpb_secperclus || !cluster ) { | |
1068 | /* find a new cluster */ | 1159 | if (write) |
1069 | if ( numsec >= fat_bpb.bpb_secperclus || !cluster) { | 1160 | cluster = next_write_cluster(file, cluster, §or); |
1070 | int oldcluster = cluster; | 1161 | else { |
1071 | cluster = get_next_cluster(cluster); | 1162 | cluster = get_next_cluster(cluster); |
1072 | if (!cluster) { | 1163 | sector = cluster2sec(cluster); |
1073 | if (!oldcluster) | 1164 | } |
1074 | cluster = find_free_cluster(fat_bpb.fsinfo.nextfree); | 1165 | if (!cluster) |
1075 | else | 1166 | sector = -1; |
1076 | cluster = find_free_cluster(oldcluster+1); | 1167 | numsec=1; |
1077 | 1168 | } | |
1078 | if (cluster) { | 1169 | else { |
1079 | if ( !oldcluster ) | 1170 | if (sector) |
1080 | file->firstcluster = cluster; | 1171 | sector++; |
1081 | else | 1172 | else { |
1082 | update_fat_entry(oldcluster, cluster); | 1173 | sector = cluster2sec(file->firstcluster); |
1083 | } | 1174 | numsec=1; |
1084 | else { | ||
1085 | sector = -1; | ||
1086 | DEBUGF("fat_write(): Disk full!\n"); | ||
1087 | } | ||
1088 | } | 1175 | } |
1176 | } | ||
1089 | 1177 | ||
1090 | if (cluster) { | 1178 | if (!first) |
1091 | sector = cluster2sec(cluster); | 1179 | first = sector; |
1092 | LDEBUGF("cluster2sec(%x) == %x\n",cluster,sector); | ||
1093 | if (sector<0) | ||
1094 | return -1; | ||
1095 | numsec=0; | ||
1096 | 1180 | ||
1097 | if (!oldcluster) | 1181 | if ( ((sector != first) && (sector != last+1)) || /* not sequential */ |
1098 | first = last = sector; | 1182 | (i == sectorcount-1) || /* last sector requested */ |
1183 | (sector-first+1 == 256) ) { /* max 256 sectors per ata request */ | ||
1184 | int count = sector - first + 1; | ||
1185 | int start = first + fat_bpb.startsector; | ||
1186 | LDEBUGF("s=%x, l=%x, f=%x, i=%d\n",sector,last,first,i); | ||
1187 | if (write) | ||
1188 | err = ata_write_sectors(start, count, buf); | ||
1189 | else | ||
1190 | err = ata_read_sectors(start, count, buf); | ||
1191 | if (err) { | ||
1192 | DEBUGF( "fat_readwrite() - Couldn't read sector %d" | ||
1193 | " (error code %d)\n", sector,err); | ||
1194 | return -2; | ||
1099 | } | 1195 | } |
1196 | ((char*)buf) += count * SECTOR_SIZE; | ||
1197 | first = 0; | ||
1100 | } | 1198 | } |
1101 | else | 1199 | last = sector; |
1102 | sector++; | ||
1103 | |||
1104 | /* we start simple: one sector at a time */ | ||
1105 | err = ata_write_sectors(sector, 1, buf); | ||
1106 | if (err) { | ||
1107 | DEBUGF( "fat_write() - Couldn't write sector %d" | ||
1108 | " (error code %d)\n", sector,err); | ||
1109 | return -2; | ||
1110 | } | ||
1111 | ((char*)buf) += SECTOR_SIZE; | ||
1112 | } | 1200 | } |
1113 | 1201 | ||
1114 | file->lastcluster = cluster; | 1202 | file->lastcluster = cluster; |
@@ -1118,15 +1206,6 @@ int fat_write( struct fat_file *file, int sectorcount, void* buf ) | |||
1118 | return sectorcount; | 1206 | return sectorcount; |
1119 | } | 1207 | } |
1120 | 1208 | ||
1121 | int fat_readwrite( struct fat_file *file, int sectorcount, | ||
1122 | void* buf, bool write ) | ||
1123 | { | ||
1124 | if (write) | ||
1125 | return fat_write(file, sectorcount, buf); | ||
1126 | else | ||
1127 | return fat_read(file, sectorcount, buf); | ||
1128 | } | ||
1129 | |||
1130 | int fat_seek(struct fat_file *file, int seeksector ) | 1209 | int fat_seek(struct fat_file *file, int seeksector ) |
1131 | { | 1210 | { |
1132 | int cluster = file->firstcluster; | 1211 | int cluster = file->firstcluster; |
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h index 1316202a6c..6ed68ad8d8 100644 --- a/firmware/drivers/fat.h +++ b/firmware/drivers/fat.h | |||
@@ -46,15 +46,6 @@ struct fat_direntry | |||
46 | #define FAT_ATTR_DIRECTORY 0x10 | 46 | #define FAT_ATTR_DIRECTORY 0x10 |
47 | #define FAT_ATTR_ARCHIVE 0x20 | 47 | #define FAT_ATTR_ARCHIVE 0x20 |
48 | 48 | ||
49 | struct fat_dir | ||
50 | { | ||
51 | int entry; | ||
52 | int cached_sec; | ||
53 | int num_sec; | ||
54 | unsigned char cached_buf[SECTOR_SIZE]; | ||
55 | int startcluster; | ||
56 | }; | ||
57 | |||
58 | struct fat_file | 49 | struct fat_file |
59 | { | 50 | { |
60 | int firstcluster; /* first cluster in file */ | 51 | int firstcluster; /* first cluster in file */ |
@@ -65,6 +56,16 @@ struct fat_file | |||
65 | int direntry; /* dir entry index in sector */ | 56 | int direntry; /* dir entry index in sector */ |
66 | }; | 57 | }; |
67 | 58 | ||
59 | struct fat_dir | ||
60 | { | ||
61 | int entry; | ||
62 | int cached_sec; | ||
63 | int num_sec; | ||
64 | unsigned char cached_buf[SECTOR_SIZE]; | ||
65 | int startcluster; | ||
66 | }; | ||
67 | |||
68 | |||
68 | extern int fat_mount(int startsector); | 69 | extern int fat_mount(int startsector); |
69 | 70 | ||
70 | extern int fat_create_dir(unsigned int currdir, char *name); | 71 | extern int fat_create_dir(unsigned int currdir, char *name); |
diff --git a/firmware/test/fat/ata-sim.c b/firmware/test/fat/ata-sim.c index a64e0a4d4d..661cc79a1f 100644 --- a/firmware/test/fat/ata-sim.c +++ b/firmware/test/fat/ata-sim.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include <stdlib.h> | 2 | #include <stdlib.h> |
3 | #include <string.h> | 3 | #include <string.h> |
4 | #include "debug.h" | 4 | #include "debug.h" |
5 | #include "panic.h" | ||
5 | 6 | ||
6 | #define BLOCK_SIZE 512 | 7 | #define BLOCK_SIZE 512 |
7 | 8 | ||
@@ -9,7 +10,10 @@ static FILE* file; | |||
9 | 10 | ||
10 | int ata_read_sectors(unsigned long start, unsigned char count, void* buf) | 11 | int ata_read_sectors(unsigned long start, unsigned char count, void* buf) |
11 | { | 12 | { |
12 | DEBUGF("[Reading block 0x%lx]\n",start); | 13 | int i; |
14 | for (i=0; i<count; i++ ) | ||
15 | DEBUGF("[Reading block 0x%lx]\n",start+i); | ||
16 | |||
13 | if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) { | 17 | if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) { |
14 | perror("fseek"); | 18 | perror("fseek"); |
15 | return -1; | 19 | return -1; |
@@ -17,6 +21,7 @@ int ata_read_sectors(unsigned long start, unsigned char count, void* buf) | |||
17 | if(!fread(buf,BLOCK_SIZE,count,file)) { | 21 | if(!fread(buf,BLOCK_SIZE,count,file)) { |
18 | printf("Failed reading %d blocks starting at block 0x%lx\n",count,start); | 22 | printf("Failed reading %d blocks starting at block 0x%lx\n",count,start); |
19 | perror("fread"); | 23 | perror("fread"); |
24 | panicf("Disk error\n"); | ||
20 | return -2; | 25 | return -2; |
21 | } | 26 | } |
22 | return 0; | 27 | return 0; |
@@ -24,20 +29,22 @@ int ata_read_sectors(unsigned long start, unsigned char count, void* buf) | |||
24 | 29 | ||
25 | int ata_write_sectors(unsigned long start, unsigned char count, void* buf) | 30 | int ata_write_sectors(unsigned long start, unsigned char count, void* buf) |
26 | { | 31 | { |
27 | DEBUGF("[Writing block 0x%lx]\n",start); | 32 | int i; |
33 | for (i=0; i<count; i++ ) | ||
34 | DEBUGF("[Writing block 0x%lx]\n",start+i); | ||
28 | 35 | ||
29 | if (start == 0) { | 36 | if (start == 0) |
30 | DEBUGF("Holy crap! You're writing on sector 0!\n"); | 37 | panicf("Writing on sector 0!\n"); |
31 | exit(0); | ||
32 | } | ||
33 | 38 | ||
34 | if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) { | 39 | if(fseek(file,start*BLOCK_SIZE,SEEK_SET)) { |
35 | perror("fseek"); | 40 | perror("fseek"); |
36 | return -1; | 41 | return -1; |
42 | panicf("Disk error\n"); | ||
37 | } | 43 | } |
38 | if(!fwrite(buf,BLOCK_SIZE,count,file)) { | 44 | if(!fwrite(buf,BLOCK_SIZE,count,file)) { |
39 | perror("fwrite"); | 45 | perror("fwrite"); |
40 | return -2; | 46 | return -2; |
47 | panicf("Disk error\n"); | ||
41 | } | 48 | } |
42 | return 0; | 49 | return 0; |
43 | } | 50 | } |
diff --git a/firmware/test/fat/main.c b/firmware/test/fat/main.c index 708ee454c8..0259be410b 100644 --- a/firmware/test/fat/main.c +++ b/firmware/test/fat/main.c | |||
@@ -12,7 +12,7 @@ extern int ata_init(char*); | |||
12 | extern void ata_read_sectors(int, int, char*); | 12 | extern void ata_read_sectors(int, int, char*); |
13 | 13 | ||
14 | void dbg_dump_sector(int sec); | 14 | void dbg_dump_sector(int sec); |
15 | void dbg_dump_buffer(unsigned char *buf, int len); | 15 | void dbg_dump_buffer(unsigned char *buf, int len, int offset); |
16 | void dbg_console(void); | 16 | void dbg_console(void); |
17 | 17 | ||
18 | void panicf( char *fmt, ...) | 18 | void panicf( char *fmt, ...) |
@@ -31,10 +31,10 @@ void dbg_dump_sector(int sec) | |||
31 | 31 | ||
32 | ata_read_sectors(sec,1,buf); | 32 | ata_read_sectors(sec,1,buf); |
33 | DEBUGF("---< Sector %d >-----------------------------------------\n", sec); | 33 | DEBUGF("---< Sector %d >-----------------------------------------\n", sec); |
34 | dbg_dump_buffer(buf, 512); | 34 | dbg_dump_buffer(buf, 512, 0); |
35 | } | 35 | } |
36 | 36 | ||
37 | void dbg_dump_buffer(unsigned char *buf, int len) | 37 | void dbg_dump_buffer(unsigned char *buf, int len, int offset) |
38 | { | 38 | { |
39 | int i, j; | 39 | int i, j; |
40 | unsigned char c; | 40 | unsigned char c; |
@@ -42,7 +42,7 @@ void dbg_dump_buffer(unsigned char *buf, int len) | |||
42 | 42 | ||
43 | for(i = 0;i < len/16;i++) | 43 | for(i = 0;i < len/16;i++) |
44 | { | 44 | { |
45 | DEBUGF("%03x: ", i*16); | 45 | DEBUGF("%03x: ", i*16 + offset); |
46 | for(j = 0;j < 16;j++) | 46 | for(j = 0;j < 16;j++) |
47 | { | 47 | { |
48 | c = buf[i*16+j]; | 48 | c = buf[i*16+j]; |
@@ -102,7 +102,7 @@ int dbg_mkfile(char* name, int num) | |||
102 | int len = num > sizeof text ? sizeof text : num; | 102 | int len = num > sizeof text ? sizeof text : num; |
103 | 103 | ||
104 | for (i=0; i<len/CHUNKSIZE; i++ ) | 104 | for (i=0; i<len/CHUNKSIZE; i++ ) |
105 | sprintf(text+i*CHUNKSIZE,"%07x,",x++); | 105 | sprintf(text+i*CHUNKSIZE,"%c%06x,",name[1],x++); |
106 | 106 | ||
107 | if (write(fd, text, len) < 0) { | 107 | if (write(fd, text, len) < 0) { |
108 | DEBUGF("Failed writing data\n"); | 108 | DEBUGF("Failed writing data\n"); |
@@ -139,12 +139,15 @@ int dbg_chkfile(char* name) | |||
139 | if (!rc) | 139 | if (!rc) |
140 | break; | 140 | break; |
141 | for (i=0; i<rc/CHUNKSIZE; i++ ) { | 141 | for (i=0; i<rc/CHUNKSIZE; i++ ) { |
142 | sprintf(tmp,"%07x,",x++); | 142 | sprintf(tmp,"%c%06x,",name[1],x++); |
143 | if (strncmp(text+i*CHUNKSIZE,tmp,CHUNKSIZE)) { | 143 | if (strncmp(text+i*CHUNKSIZE,tmp,CHUNKSIZE)) { |
144 | DEBUGF("Mismatch in byte %d (%.4s != %.4s)\n", | 144 | DEBUGF("Mismatch in byte %x (sector %d). Expected %.8s found %.8s\n", |
145 | block*sizeof(text)+i*CHUNKSIZE, tmp, | 145 | block*sizeof(text)+i*CHUNKSIZE, |
146 | (block*sizeof(text)+i*CHUNKSIZE) / SECTOR_SIZE, | ||
147 | tmp, | ||
146 | text+i*CHUNKSIZE); | 148 | text+i*CHUNKSIZE); |
147 | dbg_dump_buffer(text+i*CHUNKSIZE - 0x20, 0x40); | 149 | dbg_dump_buffer(text+i*CHUNKSIZE - 0x20, 0x40, |
150 | block*sizeof(text)+i*CHUNKSIZE - 0x20); | ||
148 | return -1; | 151 | return -1; |
149 | } | 152 | } |
150 | } | 153 | } |
diff --git a/firmware/test/fat/test.sh b/firmware/test/fat/test.sh index 0b00d765c2..476b0e4542 100644 --- a/firmware/test/fat/test.sh +++ b/firmware/test/fat/test.sh | |||
@@ -2,32 +2,34 @@ | |||
2 | 2 | ||
3 | IMAGE=disk.img | 3 | IMAGE=disk.img |
4 | MOUNT=/mnt/dummy | 4 | MOUNT=/mnt/dummy |
5 | RESULT=result.txt | ||
5 | 6 | ||
6 | fail() { | 7 | fail() { |
7 | echo "!! Test failed. Look in result.txt for test log." | 8 | echo "!! Test failed. Look in $RESULT for test logs." |
8 | exit | 9 | exit |
9 | } | 10 | } |
10 | 11 | ||
11 | check() { | 12 | check() { |
12 | /sbin/dosfsck -r $IMAGE | tee -a result.txt | 13 | /sbin/dosfsck -r $IMAGE | tee -a $RESULT |
13 | [ $RETVAL -ne 0 ] && fail | 14 | [ $RETVAL -ne 0 ] && fail |
14 | } | 15 | } |
15 | 16 | ||
16 | try() { | 17 | try() { |
17 | ./fat $1 $2 $3 2> result.txt | 18 | ./fat $1 $2 $3 2>> $RESULT |
18 | RETVAL=$? | 19 | RETVAL=$? |
19 | [ $RETVAL -ne 0 ] && fail | 20 | [ $RETVAL -ne 0 ] && fail |
20 | } | 21 | } |
21 | 22 | ||
22 | buildimage() { | 23 | buildimage() { |
23 | umount $MOUNT | 24 | /sbin/mkdosfs -F 32 -s $1 $IMAGE > /dev/null |
24 | /sbin/mkdosfs -F 32 -s $1 disk.img >/dev/null | ||
25 | mount -o loop $IMAGE $MOUNT | 25 | mount -o loop $IMAGE $MOUNT |
26 | echo "Filling it with /etc files" | 26 | echo "Filling it with /etc files" |
27 | find /etc -type f -maxdepth 1 -exec cp {} $MOUNT \; | 27 | find /etc -type f -maxdepth 1 -exec cp {} $MOUNT \; |
28 | umount $MOUNT | ||
28 | } | 29 | } |
29 | 30 | ||
30 | runtests() { | 31 | runtests() { |
32 | rm $RESULT | ||
31 | 33 | ||
32 | echo ---Test: create a 10K file | 34 | echo ---Test: create a 10K file |
33 | try mkfile /apa.txt 10 | 35 | try mkfile /apa.txt 10 |
@@ -53,29 +55,38 @@ runtests() { | |||
53 | try mkfile /cpa.txt 0 | 55 | try mkfile /cpa.txt 0 |
54 | check | 56 | check |
55 | try chkfile /cpa.txt | 57 | try chkfile /cpa.txt |
58 | try chkfile /apa.txt | ||
59 | try chkfile /bpa.txt | ||
56 | 60 | ||
57 | echo ---Test: create 20 1k files | 61 | echo ---Test: create 10 1k files |
58 | for i in `seq 1 10`; | 62 | for i in `seq 1 10`; |
59 | do | 63 | do |
60 | echo -n $i | 64 | echo ---Test: $i/10 --- |
61 | try mkfile /rockbox.$i | 65 | try mkfile /rockbox.$i |
62 | check | 66 | check |
67 | try chkfile /bpa.txt | ||
63 | done | 68 | done |
64 | 69 | ||
65 | } | 70 | } |
66 | 71 | ||
67 | echo "Building test image A (2 sectors/cluster)" | 72 | echo "Building test image (1 sector/cluster)" |
68 | buildimage 2 | 73 | buildimage 1 |
69 | runtests | 74 | runtests |
70 | 75 | ||
71 | echo "Building test image B (8 sectors/cluster)" | 76 | echo "Building test image (4 sector/cluster)" |
77 | buildimage 4 | ||
78 | runtests | ||
79 | |||
80 | echo "Building test image (8 sectors/cluster)" | ||
72 | buildimage 8 | 81 | buildimage 8 |
73 | runtests | 82 | runtests |
74 | 83 | ||
75 | echo "Building test image B (1 sector/cluster)" | 84 | echo "Building test image (32 sectors/cluster)" |
76 | buildimage 1 | 85 | buildimage 32 |
77 | runtests | 86 | runtests |
78 | 87 | ||
79 | umount $MOUNT | 88 | echo "Building test image (128 sectors/cluster)" |
89 | buildimage 128 | ||
90 | runtests | ||
80 | 91 | ||
81 | echo "-- Test complete --" | 92 | echo "== Test completed sucessfully ==" |