diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/fat.c | 209 | ||||
-rw-r--r-- | firmware/drivers/fat.h | 7 |
2 files changed, 117 insertions, 99 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 5cc47be2cf..5ca422063b 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -106,9 +106,9 @@ | |||
106 | #define FAT_EOF_MARK 0x0ffffff8 | 106 | #define FAT_EOF_MARK 0x0ffffff8 |
107 | 107 | ||
108 | struct fsinfo { | 108 | struct fsinfo { |
109 | int freecount; /* last known free cluster count */ | 109 | unsigned int freecount; /* last known free cluster count */ |
110 | int nextfree; /* first cluster to start looking for free clusters, | 110 | unsigned int nextfree; /* first cluster to start looking for free |
111 | or 0xffffffff for no hint */ | 111 | clusters, or 0xffffffff for no hint */ |
112 | }; | 112 | }; |
113 | /* fsinfo offsets */ | 113 | /* fsinfo offsets */ |
114 | #define FSINFO_FREECOUNT 488 | 114 | #define FSINFO_FREECOUNT 488 |
@@ -118,7 +118,7 @@ struct bpb | |||
118 | { | 118 | { |
119 | char bs_oemname[9]; /* OEM string, ending with \0 */ | 119 | char bs_oemname[9]; /* OEM string, ending with \0 */ |
120 | int bpb_bytspersec; /* Bytes per sectory, typically 512 */ | 120 | int bpb_bytspersec; /* Bytes per sectory, typically 512 */ |
121 | int bpb_secperclus; /* Sectors per cluster */ | 121 | unsigned int bpb_secperclus; /* Sectors per cluster */ |
122 | int bpb_rsvdseccnt; /* Number of reserved sectors */ | 122 | int bpb_rsvdseccnt; /* Number of reserved sectors */ |
123 | int bpb_numfats; /* Number of FAT structures, typically 2 */ | 123 | int bpb_numfats; /* Number of FAT structures, typically 2 */ |
124 | int bpb_rootentcnt; /* Number of dir entries in the root */ | 124 | int bpb_rootentcnt; /* Number of dir entries in the root */ |
@@ -148,12 +148,12 @@ struct bpb | |||
148 | int bpb_bkbootsec; | 148 | int bpb_bkbootsec; |
149 | 149 | ||
150 | /* variables for internal use */ | 150 | /* variables for internal use */ |
151 | int fatsize; | 151 | unsigned int fatsize; |
152 | int totalsectors; | 152 | unsigned int totalsectors; |
153 | int rootdirsector; | 153 | unsigned int rootdirsector; |
154 | int firstdatasector; | 154 | unsigned int firstdatasector; |
155 | int startsector; | 155 | unsigned int startsector; |
156 | int dataclusters; | 156 | unsigned int dataclusters; |
157 | struct fsinfo fsinfo; | 157 | struct fsinfo fsinfo; |
158 | }; | 158 | }; |
159 | 159 | ||
@@ -187,7 +187,7 @@ static struct fat_cache_entry fat_cache[FAT_CACHE_SIZE]; | |||
187 | static unsigned char lastsector[SECTOR_SIZE]; | 187 | static unsigned char lastsector[SECTOR_SIZE]; |
188 | static unsigned char lastsector2[SECTOR_SIZE]; | 188 | static unsigned char lastsector2[SECTOR_SIZE]; |
189 | 189 | ||
190 | static int sec2cluster(int sec) | 190 | static int sec2cluster(unsigned int sec) |
191 | { | 191 | { |
192 | if ( sec < fat_bpb.firstdatasector ) | 192 | if ( sec < fat_bpb.firstdatasector ) |
193 | { | 193 | { |
@@ -236,7 +236,7 @@ int fat_mount(int startsector) | |||
236 | unsigned char buf[SECTOR_SIZE]; | 236 | unsigned char buf[SECTOR_SIZE]; |
237 | int err; | 237 | int err; |
238 | int datasec; | 238 | int datasec; |
239 | int i; | 239 | unsigned int i; |
240 | 240 | ||
241 | for(i = 0;i < FAT_CACHE_SIZE;i++) | 241 | for(i = 0;i < FAT_CACHE_SIZE;i++) |
242 | { | 242 | { |
@@ -336,7 +336,30 @@ int fat_mount(int startsector) | |||
336 | } | 336 | } |
337 | fat_bpb.fsinfo.freecount = BYTES2INT32(buf, FSINFO_FREECOUNT); | 337 | fat_bpb.fsinfo.freecount = BYTES2INT32(buf, FSINFO_FREECOUNT); |
338 | fat_bpb.fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE); | 338 | fat_bpb.fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE); |
339 | LDEBUGF("Freecount: %x\n",fat_bpb.fsinfo.freecount); | 339 | |
340 | /* calculate freecount if unset */ | ||
341 | if ( fat_bpb.fsinfo.freecount == 0xffffffff ) | ||
342 | { | ||
343 | int free = 0; | ||
344 | for (i = 0; i<fat_bpb.fatsize; i++) { | ||
345 | unsigned int j; | ||
346 | unsigned int* fat = cache_fat_sector(i); | ||
347 | for (j = 0; j < CLUSTERS_PER_FAT_SECTOR; j++) { | ||
348 | unsigned int c = i * CLUSTERS_PER_FAT_SECTOR + j; | ||
349 | if ( c > fat_bpb.dataclusters+1 ) /* nr 0 is unused */ | ||
350 | break; | ||
351 | |||
352 | if (!(SWAB32(fat[j]) & 0x0fffffff)) { | ||
353 | free++; | ||
354 | if ( fat_bpb.fsinfo.nextfree == 0xffffffff ) | ||
355 | fat_bpb.fsinfo.nextfree = c; | ||
356 | } | ||
357 | } | ||
358 | } | ||
359 | fat_bpb.fsinfo.freecount = free; | ||
360 | } | ||
361 | |||
362 | LDEBUGF("Freecount: %d\n",fat_bpb.fsinfo.freecount); | ||
340 | LDEBUGF("Nextfree: %x\n",fat_bpb.fsinfo.nextfree); | 363 | LDEBUGF("Nextfree: %x\n",fat_bpb.fsinfo.nextfree); |
341 | LDEBUGF("Cluster count: %x\n",fat_bpb.dataclusters); | 364 | LDEBUGF("Cluster count: %x\n",fat_bpb.dataclusters); |
342 | LDEBUGF("Sectors per cluster: %d\n",fat_bpb.bpb_secperclus); | 365 | LDEBUGF("Sectors per cluster: %d\n",fat_bpb.bpb_secperclus); |
@@ -450,22 +473,22 @@ static unsigned int find_free_cluster(unsigned int startcluster) | |||
450 | { | 473 | { |
451 | unsigned int sector = startcluster / CLUSTERS_PER_FAT_SECTOR; | 474 | unsigned int sector = startcluster / CLUSTERS_PER_FAT_SECTOR; |
452 | unsigned int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; | 475 | unsigned int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; |
453 | int i; | 476 | unsigned int i; |
454 | 477 | ||
455 | /* don't waste time scanning if the disk is already full */ | 478 | /* don't waste time scanning if the disk is already full */ |
456 | if (!fat_bpb.fsinfo.freecount) | 479 | if (!fat_bpb.fsinfo.freecount) |
457 | return 0; | 480 | return 0; |
458 | 481 | ||
459 | for (i = 0; i<fat_bpb.fatsize; i++) { | 482 | for (i = 0; i<fat_bpb.fatsize; i++) { |
460 | int j; | 483 | unsigned int j; |
461 | int nr = (i + sector) % fat_bpb.fatsize; | 484 | unsigned int nr = (i + sector) % fat_bpb.fatsize; |
462 | unsigned int* fat = cache_fat_sector(nr); | 485 | unsigned int* fat = cache_fat_sector(nr); |
463 | if ( !fat ) | 486 | if ( !fat ) |
464 | break; | 487 | break; |
465 | for (j = 0; j < CLUSTERS_PER_FAT_SECTOR; j++) { | 488 | for (j = 0; j < CLUSTERS_PER_FAT_SECTOR; j++) { |
466 | int k = (j + offset) % CLUSTERS_PER_FAT_SECTOR; | 489 | int k = (j + offset) % CLUSTERS_PER_FAT_SECTOR; |
467 | if (!(SWAB32(fat[k]) & 0x0fffffff)) { | 490 | if (!(SWAB32(fat[k]) & 0x0fffffff)) { |
468 | int c = nr * CLUSTERS_PER_FAT_SECTOR + k; | 491 | unsigned int c = nr * CLUSTERS_PER_FAT_SECTOR + k; |
469 | if ( c > fat_bpb.dataclusters+1 ) /* nr 0 is unused */ | 492 | if ( c > fat_bpb.dataclusters+1 ) /* nr 0 is unused */ |
470 | continue; | 493 | continue; |
471 | LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c); | 494 | LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c); |
@@ -646,42 +669,41 @@ static int add_dir_entry(struct fat_dir* dir, | |||
646 | { | 669 | { |
647 | unsigned char buf[SECTOR_SIZE]; | 670 | unsigned char buf[SECTOR_SIZE]; |
648 | int err; | 671 | int err; |
649 | int sector=0; | 672 | unsigned int sector; |
650 | bool update_last = false; | 673 | bool update_last = false; |
651 | bool done = false; | 674 | bool done = false; |
652 | bool eof = false; | 675 | bool eof = false; |
653 | 676 | ||
654 | LDEBUGF( "add_dir_entry(%x,%s,%x)\n", | 677 | LDEBUGF( "add_dir_entry(%s,%x)\n", |
655 | dir->startcluster, de->name, file->firstcluster); | 678 | de->name, file->firstcluster); |
656 | 679 | ||
657 | err=fat_seek(&dir->file, 0); | 680 | err=fat_seek(&dir->file, 0); |
658 | if (err<0) | 681 | if (err<0) |
659 | return -1; | 682 | return -1; |
660 | 683 | ||
661 | while(!done) | 684 | for (sector=0; !done; sector++) |
662 | { | 685 | { |
663 | err = 0; | 686 | err = 0; |
664 | if (!eof) { | 687 | if (!eof) { |
665 | err = fat_readwrite(&dir->file, 1, buf, false); | 688 | err = fat_readwrite(&dir->file, 1, buf, false); |
666 | sector++; | ||
667 | } | 689 | } |
668 | if (err==0) { | 690 | if (err==0) { |
669 | /* eof: add new sector */ | 691 | /* eof: add new sector */ |
670 | eof = true; | 692 | eof = true; |
671 | 693 | ||
672 | /* don't add a new sector only for the last-entry marker */ | ||
673 | if (update_last) | ||
674 | break; | ||
675 | |||
676 | memset(buf, 0, sizeof buf); | 694 | memset(buf, 0, sizeof buf); |
677 | LDEBUGF("Adding new sector to dir\n"); | 695 | LDEBUGF("Adding new sector to dir\n"); |
678 | err=fat_seek(&dir->file, sector-1); | 696 | err=fat_seek(&dir->file, sector); |
679 | if (err<0) | 697 | if (err<0) |
680 | return -2; | 698 | return -5; |
681 | err = fat_readwrite(&dir->file, 1, buf, true); | 699 | |
682 | if (err<1) | 700 | /* add sectors (we must clear the whole cluster) */ |
683 | return -3; | 701 | do { |
684 | } | 702 | err = fat_readwrite(&dir->file, 1, buf, true); |
703 | if (err<1) | ||
704 | return -3; | ||
705 | } while (dir->file.sectornum < (int)fat_bpb.bpb_secperclus); | ||
706 | } | ||
685 | if (err<0) { | 707 | if (err<0) { |
686 | DEBUGF( "add_dir_entry() - Couldn't read dir" | 708 | DEBUGF( "add_dir_entry() - Couldn't read dir" |
687 | " (error code %d)\n", err); | 709 | " (error code %d)\n", err); |
@@ -690,24 +712,23 @@ static int add_dir_entry(struct fat_dir* dir, | |||
690 | 712 | ||
691 | if (update_last) | 713 | if (update_last) |
692 | { | 714 | { |
693 | /* All we need to do is to set the first entry to 0 */ | 715 | /* buffer is already cleared, |
694 | LDEBUGF("Clearing the first entry in sector %d\n", sector); | 716 | we just need to flag for sector update */ |
695 | buf[0] = 0; | ||
696 | done = true; | 717 | done = true; |
697 | } | 718 | } |
698 | else | 719 | else |
699 | { | 720 | { |
700 | int i; | 721 | unsigned int i; |
701 | /* Look for a free slot */ | 722 | /* Look for a free slot */ |
702 | for (i = 0; i < SECTOR_SIZE; i += DIR_ENTRY_SIZE) | 723 | for (i = 0; i < DIR_ENTRIES_PER_SECTOR; i++) |
703 | { | 724 | { |
704 | unsigned char firstbyte = buf[i]; | 725 | unsigned char firstbyte = buf[i*DIR_ENTRY_SIZE]; |
705 | if (firstbyte == 0xe5 || firstbyte == 0) | 726 | if (firstbyte == 0xe5 || firstbyte == 0) |
706 | { | 727 | { |
707 | unsigned char* eptr; | 728 | unsigned char* eptr; |
708 | LDEBUGF("Found free entry %d in sector %d\n", | 729 | LDEBUGF("Found free entry %d in sector %d (%x)\n", |
709 | i/DIR_ENTRY_SIZE, sector); | 730 | i, sector, dir->file.lastsector); |
710 | eptr = &buf[i]; | 731 | eptr = &buf[i*DIR_ENTRY_SIZE]; |
711 | memset(eptr, 0, DIR_ENTRY_SIZE); | 732 | memset(eptr, 0, DIR_ENTRY_SIZE); |
712 | strncpy(&eptr[FATDIR_NAME], de->name, 11); | 733 | strncpy(&eptr[FATDIR_NAME], de->name, 11); |
713 | eptr[FATDIR_ATTR] = de->attr; | 734 | eptr[FATDIR_ATTR] = de->attr; |
@@ -715,16 +736,16 @@ static int add_dir_entry(struct fat_dir* dir, | |||
715 | 736 | ||
716 | /* remember where the dir entry is located */ | 737 | /* remember where the dir entry is located */ |
717 | file->dirsector = dir->file.lastsector; | 738 | file->dirsector = dir->file.lastsector; |
718 | file->direntry = i/DIR_ENTRY_SIZE; | 739 | file->direntry = i; |
719 | 740 | ||
720 | /* Advance the last_empty_entry marker */ | 741 | /* advance the last_empty_entry marker? */ |
721 | if (firstbyte == 0) | 742 | if (firstbyte == 0) |
722 | { | 743 | { |
723 | i += DIR_ENTRY_SIZE; | 744 | i++; |
724 | if (i < SECTOR_SIZE) | 745 | if (i < DIR_ENTRIES_PER_SECTOR) |
725 | { | 746 | { |
726 | buf[i] = 0; | 747 | /* next entry is now last */ |
727 | /* We are done */ | 748 | buf[i*DIR_ENTRY_SIZE] = 0; |
728 | done = true; | 749 | done = true; |
729 | } | 750 | } |
730 | else | 751 | else |
@@ -737,17 +758,19 @@ static int add_dir_entry(struct fat_dir* dir, | |||
737 | } | 758 | } |
738 | else | 759 | else |
739 | done = true; | 760 | done = true; |
740 | |||
741 | err=fat_seek(&dir->file, sector-1); | ||
742 | if (err<0) | ||
743 | return -5; | ||
744 | err = fat_readwrite(&dir->file, 1, buf, true); | ||
745 | if (err<1) | ||
746 | return -6; | ||
747 | break; | 761 | break; |
748 | } | 762 | } |
749 | } | 763 | } |
750 | } | 764 | } |
765 | if (done || update_last) { | ||
766 | /* update sector */ | ||
767 | err=fat_seek(&dir->file, sector); | ||
768 | if (err<0) | ||
769 | return -5; | ||
770 | err = fat_readwrite(&dir->file, 1, buf, true); | ||
771 | if (err<1) | ||
772 | return -6; | ||
773 | } | ||
751 | } | 774 | } |
752 | 775 | ||
753 | return 0; | 776 | return 0; |
@@ -852,7 +875,7 @@ static int update_file_size( struct fat_file* file, int size ) | |||
852 | int err; | 875 | int err; |
853 | 876 | ||
854 | LDEBUGF("update_file_size(cluster:%x entry:%d sector:%x size:%d)\n", | 877 | LDEBUGF("update_file_size(cluster:%x entry:%d sector:%x size:%d)\n", |
855 | file->firstcluster,file->direntry,sector,size); | 878 | file->firstcluster, file->direntry, file->dirsector, size); |
856 | 879 | ||
857 | if ( file->direntry >= DIR_ENTRIES_PER_SECTOR ) | 880 | if ( file->direntry >= DIR_ENTRIES_PER_SECTOR ) |
858 | panicf("update_file_size(): Illegal entry %d!\n",file->direntry); | 881 | panicf("update_file_size(): Illegal entry %d!\n",file->direntry); |
@@ -931,7 +954,7 @@ int fat_open(unsigned int startcluster, | |||
931 | 954 | ||
932 | /* remember where the file's dir entry is located */ | 955 | /* remember where the file's dir entry is located */ |
933 | if ( dir ) { | 956 | if ( dir ) { |
934 | file->dirsector = dir->cached_sec; | 957 | file->dirsector = dir->sector; |
935 | file->direntry = dir->entry - 1; | 958 | file->direntry = dir->entry - 1; |
936 | } | 959 | } |
937 | LDEBUGF("fat_open(%x), entry %d\n",startcluster,file->direntry); | 960 | LDEBUGF("fat_open(%x), entry %d\n",startcluster,file->direntry); |
@@ -1089,7 +1112,7 @@ static int next_write_cluster(struct fat_file* file, | |||
1089 | return cluster; | 1112 | return cluster; |
1090 | } | 1113 | } |
1091 | 1114 | ||
1092 | static bool transfer( int start, int count, char* buf, bool write ) | 1115 | static bool transfer( unsigned int start, int count, char* buf, bool write ) |
1093 | { | 1116 | { |
1094 | int err; | 1117 | int err; |
1095 | 1118 | ||
@@ -1132,7 +1155,7 @@ int fat_readwrite( struct fat_file *file, int sectorcount, | |||
1132 | /* find sequential sectors and write them all at once */ | 1155 | /* find sequential sectors and write them all at once */ |
1133 | for (i=0; (i < sectorcount) && (sector > -1); i++ ) { | 1156 | for (i=0; (i < sectorcount) && (sector > -1); i++ ) { |
1134 | numsec++; | 1157 | numsec++; |
1135 | if ( numsec > fat_bpb.bpb_secperclus || !cluster ) { | 1158 | if ( numsec > (int)fat_bpb.bpb_secperclus || !cluster ) { |
1136 | int oldcluster = cluster; | 1159 | int oldcluster = cluster; |
1137 | if (write) | 1160 | if (write) |
1138 | cluster = next_write_cluster(file, cluster, §or); | 1161 | cluster = next_write_cluster(file, cluster, §or); |
@@ -1217,7 +1240,8 @@ int fat_seek(struct fat_file *file, unsigned int seeksector ) | |||
1217 | for (i=0; i<clusternum; i++) { | 1240 | for (i=0; i<clusternum; i++) { |
1218 | cluster = get_next_cluster(cluster); | 1241 | cluster = get_next_cluster(cluster); |
1219 | if (!cluster) { | 1242 | if (!cluster) { |
1220 | DEBUGF("Seeking beyond the end of the file!\n"); | 1243 | DEBUGF("Seeking beyond the end of the file! " |
1244 | "(sector %d, cluster %d)\n", seeksector, i); | ||
1221 | return -1; | 1245 | return -1; |
1222 | } | 1246 | } |
1223 | } | 1247 | } |
@@ -1252,14 +1276,8 @@ int fat_opendir(struct fat_dir *dir, unsigned int startcluster) | |||
1252 | return -1; | 1276 | return -1; |
1253 | } | 1277 | } |
1254 | 1278 | ||
1255 | err = fat_readwrite(&dir->file, 1, dir->cached_buf, false); | ||
1256 | if (err<1) | ||
1257 | return -2; | ||
1258 | |||
1259 | dir->entry = 0; | 1279 | dir->entry = 0; |
1260 | dir->cached_sec = dir->file.lastsector; | 1280 | dir->sector = 0; |
1261 | dir->num_sec = 0; | ||
1262 | dir->startcluster = startcluster; | ||
1263 | 1281 | ||
1264 | return 0; | 1282 | return 0; |
1265 | } | 1283 | } |
@@ -1273,12 +1291,34 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) | |||
1273 | int longarray[20]; | 1291 | int longarray[20]; |
1274 | int longs=0; | 1292 | int longs=0; |
1275 | int sectoridx=0; | 1293 | int sectoridx=0; |
1294 | static unsigned char cached_buf[SECTOR_SIZE]; | ||
1276 | 1295 | ||
1277 | while(!done) | 1296 | while(!done) |
1278 | { | 1297 | { |
1279 | for (i = dir->entry; i < SECTOR_SIZE/DIR_ENTRY_SIZE; i++) | 1298 | if ( dir->entry >= DIR_ENTRIES_PER_SECTOR || !dir->sector ) |
1299 | { | ||
1300 | err = fat_readwrite(&dir->file, 1, cached_buf, false); | ||
1301 | if (err==0) { | ||
1302 | /* eof */ | ||
1303 | entry->name[0] = 0; | ||
1304 | break; | ||
1305 | } | ||
1306 | if (err<0) { | ||
1307 | DEBUGF( "fat_getnext() - Couldn't read dir" | ||
1308 | " (error code %d)\n", err); | ||
1309 | return -1; | ||
1310 | } | ||
1311 | dir->sector = dir->file.lastsector; | ||
1312 | dir->entry = 0; | ||
1313 | } | ||
1314 | |||
1315 | for (i = dir->entry % DIR_ENTRIES_PER_SECTOR; | ||
1316 | i < DIR_ENTRIES_PER_SECTOR; i++) | ||
1280 | { | 1317 | { |
1281 | firstbyte = dir->cached_buf[i*DIR_ENTRY_SIZE]; | 1318 | unsigned int entrypos = i * DIR_ENTRY_SIZE; |
1319 | |||
1320 | firstbyte = cached_buf[entrypos]; | ||
1321 | dir->entry++; | ||
1282 | 1322 | ||
1283 | if (firstbyte == 0xe5) { | 1323 | if (firstbyte == 0xe5) { |
1284 | /* free entry */ | 1324 | /* free entry */ |
@@ -1293,13 +1333,13 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) | |||
1293 | } | 1333 | } |
1294 | 1334 | ||
1295 | /* longname entry? */ | 1335 | /* longname entry? */ |
1296 | if ( ( dir->cached_buf[i*DIR_ENTRY_SIZE + FATDIR_ATTR] & | 1336 | if ( ( cached_buf[entrypos + FATDIR_ATTR] & |
1297 | FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) { | 1337 | FAT_ATTR_LONG_NAME_MASK ) == FAT_ATTR_LONG_NAME ) { |
1298 | longarray[longs++] = i*DIR_ENTRY_SIZE + sectoridx; | 1338 | longarray[longs++] = entrypos + sectoridx; |
1299 | } | 1339 | } |
1300 | else { | 1340 | else { |
1301 | if ( parse_direntry(entry, | 1341 | if ( parse_direntry(entry, |
1302 | &dir->cached_buf[i*DIR_ENTRY_SIZE]) ) { | 1342 | &cached_buf[entrypos]) ) { |
1303 | 1343 | ||
1304 | /* don't return volume id entry */ | 1344 | /* don't return volume id entry */ |
1305 | if ( entry->attr == FAT_ATTR_VOLUME_ID ) | 1345 | if ( entry->attr == FAT_ATTR_VOLUME_ID ) |
@@ -1310,7 +1350,7 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) | |||
1310 | int j,k,l=0; | 1350 | int j,k,l=0; |
1311 | /* iterate backwards through the dir entries */ | 1351 | /* iterate backwards through the dir entries */ |
1312 | for (j=longs-1; j>=0; j--) { | 1352 | for (j=longs-1; j>=0; j--) { |
1313 | unsigned char* ptr = dir->cached_buf; | 1353 | unsigned char* ptr = cached_buf; |
1314 | int index = longarray[j]; | 1354 | int index = longarray[j]; |
1315 | /* current or cached sector? */ | 1355 | /* current or cached sector? */ |
1316 | if ( sectoridx >= SECTOR_SIZE ) { | 1356 | if ( sectoridx >= SECTOR_SIZE ) { |
@@ -1342,6 +1382,7 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) | |||
1342 | } | 1382 | } |
1343 | done = true; | 1383 | done = true; |
1344 | sectoridx = 0; | 1384 | sectoridx = 0; |
1385 | i++; | ||
1345 | break; | 1386 | break; |
1346 | } | 1387 | } |
1347 | } | 1388 | } |
@@ -1349,31 +1390,11 @@ int fat_getnext(struct fat_dir *dir, struct fat_direntry *entry) | |||
1349 | 1390 | ||
1350 | /* save this sector, for longname use */ | 1391 | /* save this sector, for longname use */ |
1351 | if ( sectoridx ) | 1392 | if ( sectoridx ) |
1352 | memcpy( lastsector2, dir->cached_buf, SECTOR_SIZE ); | 1393 | memcpy( lastsector2, cached_buf, SECTOR_SIZE ); |
1353 | else | 1394 | else |
1354 | memcpy( lastsector, dir->cached_buf, SECTOR_SIZE ); | 1395 | memcpy( lastsector, cached_buf, SECTOR_SIZE ); |
1355 | sectoridx += SECTOR_SIZE; | 1396 | sectoridx += SECTOR_SIZE; |
1356 | 1397 | ||
1357 | if ( i < SECTOR_SIZE/DIR_ENTRY_SIZE ) { | ||
1358 | i++; | ||
1359 | } | ||
1360 | else { | ||
1361 | err = fat_readwrite(&dir->file, 1, dir->cached_buf, false); | ||
1362 | if (err==0) { | ||
1363 | /* eof */ | ||
1364 | entry->name[0] = 0; | ||
1365 | return 0; | ||
1366 | } | ||
1367 | if (err<0) { | ||
1368 | DEBUGF( "fat_getnext() - Couldn't read dir" | ||
1369 | " (error code %d)\n", err); | ||
1370 | return -1; | ||
1371 | } | ||
1372 | i = 0; | ||
1373 | dir->cached_sec = dir->file.lastsector; | ||
1374 | } | ||
1375 | |||
1376 | dir->entry = i; | ||
1377 | } | 1398 | } |
1378 | return 0; | 1399 | return 0; |
1379 | } | 1400 | } |
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h index 4e5397f806..f05acf3c8f 100644 --- a/firmware/drivers/fat.h +++ b/firmware/drivers/fat.h | |||
@@ -59,11 +59,8 @@ struct fat_file | |||
59 | 59 | ||
60 | struct fat_dir | 60 | struct fat_dir |
61 | { | 61 | { |
62 | int entry; | 62 | unsigned int entry; |
63 | int cached_sec; | 63 | int sector; |
64 | int num_sec; | ||
65 | unsigned char cached_buf[SECTOR_SIZE]; | ||
66 | int startcluster; | ||
67 | struct fat_file file; | 64 | struct fat_file file; |
68 | }; | 65 | }; |
69 | 66 | ||