summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-10-30 16:16:47 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-10-30 16:16:47 +0000
commitd2df3c01dc34157fe3c0d414df7c68687f6aaedc (patch)
tree47255fe8e397cd0fbef87438f5978a82e5140ba8
parentb4cf6a1a0be3b76184e2c6a4551c052d8abdaa32 (diff)
downloadrockbox-d2df3c01dc34157fe3c0d414df7c68687f6aaedc.tar.gz
rockbox-d2df3c01dc34157fe3c0d414df7c68687f6aaedc.zip
Improved find_free_cluster(). Split readwrite() in two to simplify debugging.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2783 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/fat.c175
1 files changed, 113 insertions, 62 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 89b322e10a..40f9c47fa7 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -429,14 +429,15 @@ static int find_free_cluster(int startcluster)
429 int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; 429 int offset = startcluster % CLUSTERS_PER_FAT_SECTOR;
430 int i; 430 int i;
431 431
432 for (i = sector; i<fat_bpb.fatsize; i++) { 432 for (i = 0; i<fat_bpb.fatsize; i++) {
433 int j; 433 int j;
434 unsigned int* fat = cache_fat_sector(i); 434 int nr = (i + sector) % fat_bpb.fatsize;
435 unsigned int* fat = cache_fat_sector(nr);
435 if ( !fat ) 436 if ( !fat )
436 break; 437 break;
437 for (j = offset; j < CLUSTERS_PER_FAT_SECTOR; j++) 438 for (j = offset; j < CLUSTERS_PER_FAT_SECTOR; j++)
438 if (!(SWAB32(fat[j]) & 0x0fffffff)) { 439 if (!(SWAB32(fat[j]) & 0x0fffffff)) {
439 int c = i * CLUSTERS_PER_FAT_SECTOR + j; 440 int c = nr * CLUSTERS_PER_FAT_SECTOR + j;
440 LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c); 441 LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c);
441 fat_bpb.fsinfo.nextfree = c; 442 fat_bpb.fsinfo.nextfree = c;
442 return c; 443 return c;
@@ -472,8 +473,10 @@ static int update_fat_entry(unsigned int entry, unsigned int val)
472 if (!(SWAB32(sec[offset]) & 0x0fffffff)) 473 if (!(SWAB32(sec[offset]) & 0x0fffffff))
473 fat_bpb.fsinfo.freecount--; 474 fat_bpb.fsinfo.freecount--;
474 } 475 }
475 else 476 else {
476 fat_bpb.fsinfo.freecount++; 477 if (SWAB32(sec[offset]) & 0x0fffffff)
478 fat_bpb.fsinfo.freecount++;
479 }
477 480
478 /* don't change top 4 bits */ 481 /* don't change top 4 bits */
479 sec[offset] &= SWAB32(0xf0000000); 482 sec[offset] &= SWAB32(0xf0000000);
@@ -503,7 +506,6 @@ static int get_next_cluster(unsigned int cluster)
503 int next_cluster; 506 int next_cluster;
504 507
505 next_cluster = read_fat_entry(cluster); 508 next_cluster = read_fat_entry(cluster);
506 LDEBUGF("get_next_cluster(%x) == %x\n",cluster,next_cluster);
507 509
508 /* is this last cluster in chain? */ 510 /* is this last cluster in chain? */
509 if ( next_cluster >= FAT_EOF_MARK ) 511 if ( next_cluster >= FAT_EOF_MARK )
@@ -630,6 +632,7 @@ static int add_dir_entry(struct fat_dir* dir,
630 632
631 while(!done) 633 while(!done)
632 { 634 {
635 bool new = false;
633 if (sec_cnt >= fat_bpb.bpb_secperclus) 636 if (sec_cnt >= fat_bpb.bpb_secperclus)
634 { 637 {
635 int oldcluster; 638 int oldcluster;
@@ -646,26 +649,27 @@ static int add_dir_entry(struct fat_dir* dir,
646 LDEBUGF("Adding cluster to dir\n"); 649 LDEBUGF("Adding cluster to dir\n");
647 currdir = find_free_cluster(fat_bpb.fsinfo.nextfree); 650 currdir = find_free_cluster(fat_bpb.fsinfo.nextfree);
648 if (!currdir) { 651 if (!currdir) {
649 currdir = find_free_cluster(0); 652 DEBUGF("add_dir_entry(): Disk full!\n");
650 if (!currdir) { 653 return -1;
651 DEBUGF("add_dir_entry(): Disk full!\n");
652 return -1;
653 }
654 } 654 }
655 update_fat_entry(oldcluster, currdir); 655 update_fat_entry(oldcluster, currdir);
656 new = true;
657 memset(buf, 0, sizeof buf);
656 } 658 }
657 LDEBUGF("new cluster is %x\n", currdir); 659 LDEBUGF("new cluster is %x\n", currdir);
658 sec = cluster2sec(currdir); 660 sec = cluster2sec(currdir);
659 } 661 }
660 662
661 LDEBUGF("Reading sector %x...\n", sec); 663 if (!new) {
662 /* Read the next sector in the current dir */ 664 LDEBUGF("Reading sector %x...\n", sec);
663 err = ata_read_sectors(sec + fat_bpb.startsector,1,buf); 665 /* Read the next sector in the current dir */
664 if (err) 666 err = ata_read_sectors(sec + fat_bpb.startsector,1,buf);
665 { 667 if (err)
666 DEBUGF( "add_dir_entry() - Couldn't read dir sector" 668 {
667 " (error code %d)\n", err); 669 DEBUGF( "add_dir_entry() - Couldn't read dir sector"
668 return -2; 670 " (error code %d)\n", err);
671 return -2;
672 }
669 } 673 }
670 674
671 if (need_to_update_last_empty_marker) 675 if (need_to_update_last_empty_marker)
@@ -981,8 +985,7 @@ int fat_remove(struct fat_file* file)
981 return 0; 985 return 0;
982} 986}
983 987
984int fat_readwrite( struct fat_file *file, int sectorcount, 988int fat_read( struct fat_file *file, int sectorcount, void* buf )
985 void* buf, bool write )
986{ 989{
987 int cluster = file->lastcluster; 990 int cluster = file->lastcluster;
988 int sector = file->lastsector; 991 int sector = file->lastsector;
@@ -990,48 +993,22 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
990 int first=0, last=0; 993 int first=0, last=0;
991 int err, i; 994 int err, i;
992 995
993 LDEBUGF( "fat_readwrite(file:%x,count:%d,buf:%x,%s)\n", 996 LDEBUGF( "fat_read(file:%x,count:%d,buf:%x)\n",
994 cluster,sectorcount,buf,write?"write":"read"); 997 cluster,sectorcount,buf);
995 LDEBUGF( "fat_readwrite: c=%x s=%x n=%d\n", cluster,sector,numsec); 998 LDEBUGF( "fat_read: c=%x s=%x n=%d\n", cluster,sector,numsec);
996 if ( sector == -1 ) 999 if ( sector == -1 )
997 return 0; 1000 return 0;
998 1001
999 if (!write) 1002 first = last = sector;
1000 first = last = sector;
1001 1003
1002 /* find sequential sectors and read/write them all at once */ 1004 /* find sequential sectors and read/write them all at once */
1003 for (i=0; i<sectorcount && sector>=0; i++ ) { 1005 for (i=0; i<sectorcount && sector>=0; i++ ) {
1004 numsec++; 1006 numsec++;
1005 if ( numsec >= fat_bpb.bpb_secperclus || !cluster) { 1007 if ( numsec >= fat_bpb.bpb_secperclus ) {
1006 int oldcluster = cluster;
1007 cluster = get_next_cluster(cluster); 1008 cluster = get_next_cluster(cluster);
1008 if (!cluster) { 1009 if (!cluster) {
1009 if ( write ) { 1010 /* reading past end-of-file */
1010 if (!oldcluster) /* new file */ 1011 sector = -1;
1011 cluster = find_free_cluster(fat_bpb.fsinfo.nextfree);
1012 else /* writing past end-of-file */
1013 cluster = find_free_cluster(oldcluster+1);
1014 if (!cluster) {
1015 /* no free cluster found after last,
1016 search from beginning */
1017 cluster = find_free_cluster(0);
1018 if (!cluster) {
1019 /* no free clusters. disk is full. */
1020 sector = -1;
1021 DEBUGF("fat_readwrite(): Disk full!\n");
1022 }
1023 }
1024 if ( cluster ) {
1025 if ( !oldcluster )
1026 file->firstcluster = cluster;
1027 else
1028 update_fat_entry(oldcluster, cluster);
1029 }
1030 }
1031 else {
1032 /* reading past end-of-file */
1033 sector = -1;
1034 }
1035 } 1012 }
1036 1013
1037 if (cluster) { 1014 if (cluster) {
@@ -1045,21 +1022,15 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
1045 else 1022 else
1046 sector++; 1023 sector++;
1047 1024
1048 if (write && !first)
1049 first = last = sector;
1050
1051 if ( (sector != last+1) || /* not sequential any more? */ 1025 if ( (sector != last+1) || /* not sequential any more? */
1052 (i == sectorcount-1) || /* last sector requested? */ 1026 (i == sectorcount-1) || /* last sector requested? */
1053 (last-first+1 == 256) ) { /* max 256 sectors per ata request */ 1027 (last-first+1 == 256) ) { /* max 256 sectors per ata request */
1054 int count = last - first + 1; 1028 int count = last - first + 1;
1055 int start = first + fat_bpb.startsector; 1029 int start = first + fat_bpb.startsector;
1056 LDEBUGF("s=%x, l=%x, f=%x, i=%d\n",sector,last,first,i); 1030 LDEBUGF("s=%x, l=%x, f=%x, i=%d\n",sector,last,first,i);
1057 if (write) 1031 err = ata_read_sectors(start, count, buf);
1058 err = ata_write_sectors(start, count, buf);
1059 else
1060 err = ata_read_sectors(start, count, buf);
1061 if (err) { 1032 if (err) {
1062 DEBUGF( "fat_readwrite() - Couldn't read sector %d" 1033 DEBUGF( "fat_read() - Couldn't read sector %d"
1063 " (error code %d)\n", sector,err); 1034 " (error code %d)\n", sector,err);
1064 return -2; 1035 return -2;
1065 } 1036 }
@@ -1076,6 +1047,86 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
1076 return sectorcount; 1047 return sectorcount;
1077} 1048}
1078 1049
1050int fat_write( struct fat_file *file, int sectorcount, void* buf )
1051{
1052 int cluster = file->lastcluster;
1053 int sector = file->lastsector;
1054 int numsec = file->sectornum;
1055 int first=0, last=0;
1056 int err, i;
1057
1058 LDEBUGF( "fat_write(file:%x,count:%d,buf:%x)\n",
1059 cluster,sectorcount,buf);
1060 LDEBUGF( "fat_write: c=%x s=%x n=%d\n", cluster,sector,numsec);
1061 if ( sector == -1 )
1062 return 0;
1063
1064 /* find sequential sectors and write them all at once */
1065 for (i=0; i<sectorcount && sector>=0; i++ ) {
1066 numsec++;
1067
1068 /* find a new cluster */
1069 if ( numsec >= fat_bpb.bpb_secperclus || !cluster) {
1070 int oldcluster = cluster;
1071 cluster = get_next_cluster(cluster);
1072 if (!cluster) {
1073 if (!oldcluster)
1074 cluster = find_free_cluster(fat_bpb.fsinfo.nextfree);
1075 else
1076 cluster = find_free_cluster(oldcluster+1);
1077
1078 if (cluster) {
1079 if ( !oldcluster )
1080 file->firstcluster = cluster;
1081 else
1082 update_fat_entry(oldcluster, cluster);
1083 }
1084 else {
1085 sector = -1;
1086 DEBUGF("fat_write(): Disk full!\n");
1087 }
1088 }
1089
1090 if (cluster) {
1091 sector = cluster2sec(cluster);
1092 LDEBUGF("cluster2sec(%x) == %x\n",cluster,sector);
1093 if (sector<0)
1094 return -1;
1095 numsec=0;
1096
1097 if (!oldcluster)
1098 first = last = sector;
1099 }
1100 }
1101 else
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 }
1113
1114 file->lastcluster = cluster;
1115 file->lastsector = sector;
1116 file->sectornum = numsec;
1117
1118 return sectorcount;
1119}
1120
1121int 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
1079int fat_seek(struct fat_file *file, int seeksector ) 1130int fat_seek(struct fat_file *file, int seeksector )
1080{ 1131{
1081 int cluster = file->firstcluster; 1132 int cluster = file->firstcluster;