diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-10-31 19:05:25 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-10-31 19:05:25 +0000 |
commit | 08356fb50a70bc44e598ff49ab61bd149060a668 (patch) | |
tree | 00a9d8d7f42a5102643b228f58ff2c85932478fb /firmware | |
parent | 0d79fa127dfc1f5650d3701a174983de8f9e5e4d (diff) | |
download | rockbox-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')
-rw-r--r-- | firmware/common/file.c | 22 | ||||
-rw-r--r-- | firmware/drivers/fat.c | 204 |
2 files changed, 114 insertions, 112 deletions
diff --git a/firmware/common/file.c b/firmware/common/file.c index 0cde938a70..3e730c2880 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c | |||
@@ -197,13 +197,9 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
197 | LDEBUGF( "readwrite(%d,%x,%d,%s)\n", | 197 | LDEBUGF( "readwrite(%d,%x,%d,%s)\n", |
198 | fd,buf,count,write?"write":"read"); | 198 | fd,buf,count,write?"write":"read"); |
199 | 199 | ||
200 | /* attempt to access past EOF? */ | 200 | /* attempt to read past EOF? */ |
201 | if (count > openfiles[fd].size - openfiles[fd].fileoffset) { | 201 | if (!write && count > openfiles[fd].size - openfiles[fd].fileoffset) |
202 | if ( write ) | 202 | count = openfiles[fd].size - openfiles[fd].fileoffset; |
203 | openfiles[fd].size = openfiles[fd].fileoffset + count; | ||
204 | else | ||
205 | count = openfiles[fd].size - openfiles[fd].fileoffset; | ||
206 | } | ||
207 | 203 | ||
208 | /* any head bytes? */ | 204 | /* any head bytes? */ |
209 | if ( openfiles[fd].cacheoffset != -1 ) { | 205 | if ( openfiles[fd].cacheoffset != -1 ) { |
@@ -253,8 +249,12 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
253 | } | 249 | } |
254 | else { | 250 | else { |
255 | if ( rc > 0 ) { | 251 | if ( rc > 0 ) { |
256 | nread += sectors * SECTOR_SIZE; | 252 | nread += rc * SECTOR_SIZE; |
257 | count -= sectors * SECTOR_SIZE; | 253 | count -= sectors * SECTOR_SIZE; |
254 | |||
255 | /* if eof, skip tail bytes */ | ||
256 | if ( rc < sectors ) | ||
257 | count = 0; | ||
258 | } | 258 | } |
259 | else { | 259 | else { |
260 | /* eof */ | 260 | /* eof */ |
@@ -285,6 +285,12 @@ static int readwrite(int fd, void* buf, int count, bool write) | |||
285 | } | 285 | } |
286 | 286 | ||
287 | openfiles[fd].fileoffset += nread; | 287 | openfiles[fd].fileoffset += nread; |
288 | LDEBUGF("fileoffset: %d\n", openfiles[fd].fileoffset); | ||
289 | |||
290 | /* adjust file size to length written */ | ||
291 | if ( write && openfiles[fd].fileoffset > openfiles[fd].size ) | ||
292 | openfiles[fd].size = openfiles[fd].fileoffset; | ||
293 | |||
288 | return nread; | 294 | return nread; |
289 | } | 295 | } |
290 | 296 | ||
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 | ||
1037 | int 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)) || | 1058 | static 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 | |||
1107 | int 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 | ||
1101 | static 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 | |||
1140 | int fat_readwrite( struct fat_file *file, int sectorcount, | 1120 | int 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, §or); | 1141 | cluster = next_write_cluster(file, cluster, §or); |
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 | ||
1209 | int fat_seek(struct fat_file *file, int seeksector ) | 1205 | int fat_seek(struct fat_file *file, int seeksector ) |