summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-10-31 19:05:25 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-10-31 19:05:25 +0000
commit08356fb50a70bc44e598ff49ab61bd149060a668 (patch)
tree00a9d8d7f42a5102643b228f58ff2c85932478fb /firmware/drivers
parent0d79fa127dfc1f5650d3701a174983de8f9e5e4d (diff)
downloadrockbox-08356fb50a70bc44e598ff49ab61bd149060a668.tar.gz
rockbox-08356fb50a70bc44e598ff49ab61bd149060a668.zip
More graceful handling when running out of space.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2793 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/fat.c204
1 files changed, 100 insertions, 104 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 4c3e410c1a..884311c1f5 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -153,6 +153,7 @@ struct bpb
153 int rootdirsector; 153 int rootdirsector;
154 int firstdatasector; 154 int firstdatasector;
155 int startsector; 155 int startsector;
156 int dataclusters;
156 struct fsinfo fsinfo; 157 struct fsinfo fsinfo;
157}; 158};
158 159
@@ -227,7 +228,6 @@ int fat_mount(int startsector)
227 unsigned char buf[SECTOR_SIZE]; 228 unsigned char buf[SECTOR_SIZE];
228 int err; 229 int err;
229 int datasec; 230 int datasec;
230 int countofclusters;
231 int i; 231 int i;
232 232
233 for(i = 0;i < FAT_CACHE_SIZE;i++) 233 for(i = 0;i < FAT_CACHE_SIZE;i++)
@@ -280,7 +280,7 @@ int fat_mount(int startsector)
280 280
281 /* Determine FAT type */ 281 /* Determine FAT type */
282 datasec = fat_bpb.totalsectors - fat_bpb.firstdatasector; 282 datasec = fat_bpb.totalsectors - fat_bpb.firstdatasector;
283 countofclusters = datasec / fat_bpb.bpb_secperclus; 283 fat_bpb.dataclusters = datasec / fat_bpb.bpb_secperclus;
284 284
285#ifdef TEST_FAT 285#ifdef TEST_FAT
286 /* 286 /*
@@ -289,7 +289,7 @@ int fat_mount(int startsector)
289 */ 289 */
290 if ( fat_bpb.bpb_fatsz16 ) 290 if ( fat_bpb.bpb_fatsz16 )
291#else 291#else
292 if ( countofclusters < 65525 ) 292 if ( fat_bpb.dataclusters < 65525 )
293#endif 293#endif
294 { 294 {
295 DEBUGF("This is not FAT32. Go away!\n"); 295 DEBUGF("This is not FAT32. Go away!\n");
@@ -330,6 +330,8 @@ int fat_mount(int startsector)
330 fat_bpb.fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE); 330 fat_bpb.fsinfo.nextfree = BYTES2INT32(buf, FSINFO_NEXTFREE);
331 LDEBUGF("Freecount: %x\n",fat_bpb.fsinfo.freecount); 331 LDEBUGF("Freecount: %x\n",fat_bpb.fsinfo.freecount);
332 LDEBUGF("Nextfree: %x\n",fat_bpb.fsinfo.nextfree); 332 LDEBUGF("Nextfree: %x\n",fat_bpb.fsinfo.nextfree);
333 LDEBUGF("Cluster count: %x\n",fat_bpb.dataclusters);
334 LDEBUGF("FAT sectors: %x\n",fat_bpb.fatsize);
333 335
334 return 0; 336 return 0;
335} 337}
@@ -342,12 +344,13 @@ static int bpb_is_sane(void)
342 fat_bpb.bpb_bytspersec); 344 fat_bpb.bpb_bytspersec);
343 return -1; 345 return -1;
344 } 346 }
345 if(fat_bpb.bpb_secperclus * fat_bpb.bpb_bytspersec > 32768) 347 if(fat_bpb.bpb_secperclus * fat_bpb.bpb_bytspersec > 128*1024)
346 { 348 {
347 DEBUGF( "bpb_is_sane() - Warning: cluster size is larger than 32K " 349 DEBUGF( "bpb_is_sane() - Error: cluster size is larger than 128K "
348 "(%d * %d = %d)\n", 350 "(%d * %d = %d)\n",
349 fat_bpb.bpb_bytspersec, fat_bpb.bpb_secperclus, 351 fat_bpb.bpb_bytspersec, fat_bpb.bpb_secperclus,
350 fat_bpb.bpb_bytspersec * fat_bpb.bpb_secperclus); 352 fat_bpb.bpb_bytspersec * fat_bpb.bpb_secperclus);
353 return -2;
351 } 354 }
352 if (fat_bpb.bpb_rsvdseccnt != 32) 355 if (fat_bpb.bpb_rsvdseccnt != 32)
353 { 356 {
@@ -369,7 +372,7 @@ static int bpb_is_sane(void)
369 { 372 {
370 DEBUGF( "bpb_is_sane() - Error: Last word is not " 373 DEBUGF( "bpb_is_sane() - Error: Last word is not "
371 "0xaa55 (0x%04x)\n", fat_bpb.last_word); 374 "0xaa55 (0x%04x)\n", fat_bpb.last_word);
372 return -4; 375 return -3;
373 } 376 }
374 377
375 if (fat_bpb.fsinfo.freecount > 378 if (fat_bpb.fsinfo.freecount >
@@ -378,7 +381,7 @@ static int bpb_is_sane(void)
378 { 381 {
379 DEBUGF( "bpb_is_sane() - Error: FSInfo.Freecount > disk size " 382 DEBUGF( "bpb_is_sane() - Error: FSInfo.Freecount > disk size "
380 "(0x%04x)\n", fat_bpb.fsinfo.freecount); 383 "(0x%04x)\n", fat_bpb.fsinfo.freecount);
381 return -5; 384 return -4;
382 } 385 }
383 386
384 return 0; 387 return 0;
@@ -429,19 +432,27 @@ static int find_free_cluster(int startcluster)
429 int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; 432 int offset = startcluster % CLUSTERS_PER_FAT_SECTOR;
430 int i; 433 int i;
431 434
435 /* don't waste time scanning if the disk is already full */
436 if (!fat_bpb.fsinfo.freecount)
437 return 0;
438
432 for (i = 0; i<fat_bpb.fatsize; i++) { 439 for (i = 0; i<fat_bpb.fatsize; i++) {
433 int j; 440 int j;
434 int nr = (i + sector) % fat_bpb.fatsize; 441 int nr = (i + sector) % fat_bpb.fatsize;
435 unsigned int* fat = cache_fat_sector(nr); 442 unsigned int* fat = cache_fat_sector(nr);
436 if ( !fat ) 443 if ( !fat )
437 break; 444 break;
438 for (j = offset; j < CLUSTERS_PER_FAT_SECTOR; j++) 445 for (j = offset; j < CLUSTERS_PER_FAT_SECTOR; j++) {
439 if (!(SWAB32(fat[j]) & 0x0fffffff)) { 446 if (!(SWAB32(fat[j]) & 0x0fffffff)) {
440 int c = nr * CLUSTERS_PER_FAT_SECTOR + j; 447 int c = nr * CLUSTERS_PER_FAT_SECTOR + j;
448 if ( c > fat_bpb.dataclusters+1 ) /* nr 0 is unused */
449 break;
441 LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c); 450 LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c);
442 fat_bpb.fsinfo.nextfree = c; 451 fat_bpb.fsinfo.nextfree = c;
443 return c; 452 return c;
444 } 453 }
454 }
455 offset = 0;
445 } 456 }
446 LDEBUGF("find_free_cluster(%x) == 0\n",startcluster); 457 LDEBUGF("find_free_cluster(%x) == 0\n",startcluster);
447 return 0; /* 0 is an illegal cluster number */ 458 return 0; /* 0 is an illegal cluster number */
@@ -687,7 +698,6 @@ static int add_dir_entry(struct fat_dir* dir,
687 } 698 }
688 699
689 if (!new) { 700 if (!new) {
690 LDEBUGF("Reading sector %x...\n", sec);
691 /* Read the next sector in the current dir */ 701 /* Read the next sector in the current dir */
692 err = ata_read_sectors(sec + fat_bpb.startsector,1,buf); 702 err = ata_read_sectors(sec + fat_bpb.startsector,1,buf);
693 if (err) 703 if (err)
@@ -979,8 +989,9 @@ int fat_closewrite(struct fat_file *file, int size)
979 int next, last = file->lastcluster; 989 int next, last = file->lastcluster;
980 int endcluster = last; 990 int endcluster = last;
981 991
982 LDEBUGF("fat_closewrite(%d)\n",size); 992 LDEBUGF("fat_closewrite(size=%d, last=%x)\n",size, last);
983 993
994 /* truncate trailing clusters */
984 last = get_next_cluster(last); 995 last = get_next_cluster(last);
985 while ( last && last != FAT_EOF_MARK ) { 996 while ( last && last != FAT_EOF_MARK ) {
986 next = get_next_cluster(last); 997 next = get_next_cluster(last);
@@ -988,13 +999,20 @@ int fat_closewrite(struct fat_file *file, int size)
988 last = next; 999 last = next;
989 } 1000 }
990 1001
991 if ( !size ) { 1002 /* if no cluster was written, size is 0 */
1003 if (!endcluster)
1004 size = 0;
1005
1006 if (!size) {
992 /* empty file */ 1007 /* empty file */
993 update_fat_entry(file->firstcluster, 0); 1008 if ( file->firstcluster ) {
994 file->firstcluster = 0; 1009 update_fat_entry(file->firstcluster, 0);
1010 file->firstcluster = 0;
1011 }
995 } 1012 }
996 else 1013 else
997 update_fat_entry(endcluster, FAT_EOF_MARK); 1014 update_fat_entry(endcluster, FAT_EOF_MARK);
1015
998 update_dir_entry(file, size); 1016 update_dir_entry(file, size);
999 flush_fat(); 1017 flush_fat();
1000 1018
@@ -1011,6 +1029,8 @@ int fat_closewrite(struct fat_file *file, int size)
1011 count, len, size ); 1029 count, len, size );
1012 if ( len > size + fat_bpb.bpb_secperclus * SECTOR_SIZE) 1030 if ( len > size + fat_bpb.bpb_secperclus * SECTOR_SIZE)
1013 panicf("Cluster chain is too long\n"); 1031 panicf("Cluster chain is too long\n");
1032 if ( len < size )
1033 panicf("Cluster chain is too short\n");
1014 } 1034 }
1015#endif 1035#endif
1016 1036
@@ -1034,84 +1054,19 @@ int fat_remove(struct fat_file* file)
1034 return 0; 1054 return 0;
1035} 1055}
1036 1056
1037int fat_read( struct fat_file *file, int sectorcount, void* buf )
1038{
1039 int cluster = file->lastcluster;
1040 int sector = file->lastsector;
1041 int numsec = file->sectornum;
1042 int first=0, last=0;
1043 int err, i;
1044
1045 LDEBUGF( "fat_read(file:%x,count:%d,buf:%x)\n",
1046 cluster,sectorcount,buf);
1047 LDEBUGF( "fat_read: c=%x s=%x n=%d\n", cluster,sector,numsec);
1048 if ( sector == -1 )
1049 return 0;
1050
1051 /* find sequential sectors and read/write them all at once */
1052 for (i=0; i<sectorcount && sector>=0; i++ ) {
1053 numsec++;
1054 if ( numsec > fat_bpb.bpb_secperclus ) {
1055 cluster = get_next_cluster(cluster);
1056 if (!cluster) {
1057 /* reading past end-of-file */
1058 sector = -1;
1059 }
1060
1061 if (cluster) {
1062 sector = cluster2sec(cluster);
1063 LDEBUGF("cluster2sec(%x) == %x\n",cluster,sector);
1064 if (sector<0)
1065 return -1;
1066 numsec=1;
1067 }
1068 }
1069 else {
1070 if (sector)
1071 sector++;
1072 else {
1073 sector = cluster2sec(file->firstcluster);
1074 numsec=1;
1075 }
1076 }
1077
1078 if (!first)
1079 first = sector;
1080 1057
1081 if ( ((sector != first) && (sector != last+1)) || 1058static int next_write_cluster(struct fat_file* file,
1082 /* not sequential any more? */ 1059 int oldcluster,
1083 (i == sectorcount-1) || /* last sector requested? */ 1060 int* newsector)
1084 (sector-first+1 == 256) ) { /* max 256 sectors per ata request */
1085 int count = sector - first + 1;
1086 int start = first + fat_bpb.startsector;
1087 LDEBUGF("s=%x, l=%x, f=%x, i=%d\n",sector,last,first,i);
1088 err = ata_read_sectors(start, count, buf);
1089 if (err) {
1090 DEBUGF( "fat_read() - Couldn't read sector %d"
1091 " (error code %d)\n", sector,err);
1092 return -2;
1093 }
1094 ((char*)buf) += count * SECTOR_SIZE;
1095 first = 0;
1096 }
1097 last = sector;
1098 }
1099
1100 file->lastcluster = cluster;
1101 file->lastsector = sector;
1102 file->sectornum = numsec;
1103
1104 return sectorcount;
1105}
1106
1107int next_write_cluster(struct fat_file* file, int oldcluster, int* newsector)
1108{ 1061{
1109 int cluster; 1062 int cluster = 0;
1110 int sector; 1063 int sector;
1111 1064
1112 LDEBUGF("next_write_cluster(%x,%x)\n",file->firstcluster, oldcluster); 1065 LDEBUGF("next_write_cluster(%x,%x)\n",file->firstcluster, oldcluster);
1113 1066
1114 cluster = get_next_cluster(oldcluster); 1067 if (oldcluster)
1068 cluster = get_next_cluster(oldcluster);
1069
1115 if (!cluster) { 1070 if (!cluster) {
1116 if (oldcluster) 1071 if (oldcluster)
1117 cluster = find_free_cluster(oldcluster+1); 1072 cluster = find_free_cluster(oldcluster+1);
@@ -1123,9 +1078,15 @@ int next_write_cluster(struct fat_file* file, int oldcluster, int* newsector)
1123 update_fat_entry(oldcluster, cluster); 1078 update_fat_entry(oldcluster, cluster);
1124 else 1079 else
1125 file->firstcluster = cluster; 1080 file->firstcluster = cluster;
1081 update_fat_entry(cluster, FAT_EOF_MARK);
1126 } 1082 }
1127 else { 1083 else {
1128 DEBUGF("next_write_sector(): Disk full!\n"); 1084#ifdef TEST_FAT
1085 if (fat_bpb.fsinfo.freecount>0)
1086 panicf("There is free space, but find_free_cluster() "
1087 "didn't find it!\n");
1088#endif
1089 DEBUGF("next_write_cluster(): Disk full!\n");
1129 return 0; 1090 return 0;
1130 } 1091 }
1131 } 1092 }
@@ -1137,6 +1098,25 @@ int next_write_cluster(struct fat_file* file, int oldcluster, int* newsector)
1137 return cluster; 1098 return cluster;
1138} 1099}
1139 1100
1101static bool transfer( int start, int count, char* buf, bool write )
1102{
1103 int err;
1104
1105 LDEBUGF("transfer(s=%x, c=%x)\n",start, count);
1106 if (write)
1107 err = ata_write_sectors(start, count, buf);
1108 else
1109 err = ata_read_sectors(start, count, buf);
1110 if (err) {
1111 DEBUGF( "transfer() - Couldn't %s sector %x"
1112 " (error code %d)\n",
1113 write ? "write":"read", start, err);
1114 return false;
1115 }
1116 return true;
1117}
1118
1119
1140int fat_readwrite( struct fat_file *file, int sectorcount, 1120int fat_readwrite( struct fat_file *file, int sectorcount,
1141 void* buf, bool write ) 1121 void* buf, bool write )
1142{ 1122{
@@ -1144,7 +1124,7 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
1144 int sector = file->lastsector; 1124 int sector = file->lastsector;
1145 int numsec = file->sectornum; 1125 int numsec = file->sectornum;
1146 int first=0, last=0; 1126 int first=0, last=0;
1147 int err, i; 1127 int i;
1148 1128
1149 LDEBUGF( "fat_write(file:%x,count:%d,buf:%x)\n", 1129 LDEBUGF( "fat_write(file:%x,count:%d,buf:%x)\n",
1150 cluster,sectorcount,buf); 1130 cluster,sectorcount,buf);
@@ -1153,23 +1133,31 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
1153 return 0; 1133 return 0;
1154 1134
1155 /* find sequential sectors and write them all at once */ 1135 /* find sequential sectors and write them all at once */
1156 for (i=0; i<sectorcount; i++ ) { 1136 for (i=0; (i < sectorcount) && (sector > -1); i++ ) {
1157 numsec++; 1137 numsec++;
1158 if ( numsec > fat_bpb.bpb_secperclus || !cluster ) { 1138 if ( numsec > fat_bpb.bpb_secperclus || !cluster ) {
1139 int oldcluster = cluster;
1159 if (write) 1140 if (write)
1160 cluster = next_write_cluster(file, cluster, &sector); 1141 cluster = next_write_cluster(file, cluster, &sector);
1161 else { 1142 else {
1162 cluster = get_next_cluster(cluster); 1143 cluster = get_next_cluster(cluster);
1163 sector = cluster2sec(cluster); 1144 sector = cluster2sec(cluster);
1164 } 1145 }
1165 if (!cluster) 1146 if (!cluster) {
1166 sector = -1; 1147 sector = -1;
1148 if ( write ) {
1149 /* set file->lastcluster to last available cluster,
1150 so we can terminate the file in closewrite() */
1151 cluster = oldcluster;
1152 }
1153 }
1167 numsec=1; 1154 numsec=1;
1168 } 1155 }
1169 else { 1156 else {
1170 if (sector) 1157 if (sector)
1171 sector++; 1158 sector++;
1172 else { 1159 else {
1160 /* look up first sector of file */
1173 sector = cluster2sec(file->firstcluster); 1161 sector = cluster2sec(file->firstcluster);
1174 numsec=1; 1162 numsec=1;
1175 } 1163 }
@@ -1179,23 +1167,27 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
1179 first = sector; 1167 first = sector;
1180 1168
1181 if ( ((sector != first) && (sector != last+1)) || /* not sequential */ 1169 if ( ((sector != first) && (sector != last+1)) || /* not sequential */
1182 (i == sectorcount-1) || /* last sector requested */ 1170 (last-first+1 == 256) ) { /* max 256 sectors per ata request */
1183 (sector-first+1 == 256) ) { /* max 256 sectors per ata request */ 1171 int count = last - first + 1;
1184 int count = sector - first + 1; 1172 if (!transfer( first + fat_bpb.startsector, count, buf, write ))
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; 1173 return -2;
1195 } 1174
1196 ((char*)buf) += count * SECTOR_SIZE; 1175 ((char*)buf) += count * SECTOR_SIZE;
1197 first = 0; 1176 first = sector;
1177 }
1178 else {
1179 /* last sector requested */
1180 if (i >= sectorcount-1) {
1181 int count = sector - first + 1;
1182 if (!transfer( first + fat_bpb.startsector,
1183 count, buf, write ))
1184 return -2;
1185
1186 ((char*)buf) += count * SECTOR_SIZE;
1187 first = sector;
1188 }
1198 } 1189 }
1190
1199 last = sector; 1191 last = sector;
1200 } 1192 }
1201 1193
@@ -1203,7 +1195,11 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
1203 file->lastsector = sector; 1195 file->lastsector = sector;
1204 file->sectornum = numsec; 1196 file->sectornum = numsec;
1205 1197
1206 return sectorcount; 1198 /* if eof, don't report last block as read/written */
1199 if (sector == -1)
1200 i--;
1201
1202 return i;
1207} 1203}
1208 1204
1209int fat_seek(struct fat_file *file, int seeksector ) 1205int fat_seek(struct fat_file *file, int seeksector )