diff options
Diffstat (limited to 'firmware/drivers/fat.c')
-rw-r--r-- | firmware/drivers/fat.c | 78 |
1 files changed, 68 insertions, 10 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 596166ec11..fe5cef878d 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c | |||
@@ -115,13 +115,13 @@ struct fsinfo { | |||
115 | static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster); | 115 | static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster); |
116 | static int get_bpb(struct bpb *bpb); | 116 | static int get_bpb(struct bpb *bpb); |
117 | static int bpb_is_sane(struct bpb *bpb); | 117 | static int bpb_is_sane(struct bpb *bpb); |
118 | static int flush_fat(struct bpb *bpb); | ||
119 | static void *cache_fat_sector(struct bpb *bpb, int secnum); | 118 | static void *cache_fat_sector(struct bpb *bpb, int secnum); |
120 | static int update_entry(struct bpb *bpb, int entry, unsigned int val); | 119 | #ifdef DISK_WRITE |
121 | static unsigned int getcurrdostime(unsigned short *dosdate, | 120 | static unsigned int getcurrdostime(unsigned short *dosdate, |
122 | unsigned short *dostime, | 121 | unsigned short *dostime, |
123 | unsigned char *dostenth); | 122 | unsigned char *dostenth); |
124 | static int create_dos_name(unsigned char *name, unsigned char *newname); | 123 | static int create_dos_name(unsigned char *name, unsigned char *newname); |
124 | #endif | ||
125 | 125 | ||
126 | static unsigned char *fat_cache[256]; | 126 | static unsigned char *fat_cache[256]; |
127 | static int fat_cache_dirty[256]; | 127 | static int fat_cache_dirty[256]; |
@@ -189,7 +189,7 @@ static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster) | |||
189 | 189 | ||
190 | static int get_bpb(struct bpb *bpb) | 190 | static int get_bpb(struct bpb *bpb) |
191 | { | 191 | { |
192 | unsigned char buf[BLOCK_SIZE]; | 192 | unsigned char buf[SECTOR_SIZE]; |
193 | int err; | 193 | int err; |
194 | int datasec; | 194 | int datasec; |
195 | int countofclusters; | 195 | int countofclusters; |
@@ -284,8 +284,9 @@ static int bpb_is_sane(struct bpb *bpb) | |||
284 | { | 284 | { |
285 | if(bpb->bpb_bytspersec != 512) | 285 | if(bpb->bpb_bytspersec != 512) |
286 | { | 286 | { |
287 | DEBUG1( "bpb_is_sane() - Warning: sector size is not 512 (%i)\n", | 287 | DEBUG1( "bpb_is_sane() - Error: sector size is not 512 (%i)\n", |
288 | bpb->bpb_bytspersec); | 288 | bpb->bpb_bytspersec); |
289 | return -1; | ||
289 | } | 290 | } |
290 | if(bpb->bpb_secperclus * bpb->bpb_bytspersec > 32768) | 291 | if(bpb->bpb_secperclus * bpb->bpb_bytspersec > 32768) |
291 | { | 292 | { |
@@ -365,6 +366,7 @@ static void *cache_fat_sector(struct bpb *bpb, int secnum) | |||
365 | return sec; | 366 | return sec; |
366 | } | 367 | } |
367 | 368 | ||
369 | #ifdef DISK_WRITE | ||
368 | static int update_entry(struct bpb *bpb, int entry, unsigned int val) | 370 | static int update_entry(struct bpb *bpb, int entry, unsigned int val) |
369 | { | 371 | { |
370 | unsigned long *sec; | 372 | unsigned long *sec; |
@@ -393,6 +395,7 @@ static int update_entry(struct bpb *bpb, int entry, unsigned int val) | |||
393 | 395 | ||
394 | return 0; | 396 | return 0; |
395 | } | 397 | } |
398 | #endif | ||
396 | 399 | ||
397 | static int read_entry(struct bpb *bpb, int entry) | 400 | static int read_entry(struct bpb *bpb, int entry) |
398 | { | 401 | { |
@@ -430,6 +433,7 @@ static int get_next_cluster(struct bpb *bpb, unsigned int cluster) | |||
430 | return next_cluster; | 433 | return next_cluster; |
431 | } | 434 | } |
432 | 435 | ||
436 | #ifdef DISK_WRITE | ||
433 | static int flush_fat(struct bpb *bpb) | 437 | static int flush_fat(struct bpb *bpb) |
434 | { | 438 | { |
435 | int i; | 439 | int i; |
@@ -495,7 +499,7 @@ static int add_dir_entry(struct bpb *bpb, | |||
495 | unsigned int currdir, | 499 | unsigned int currdir, |
496 | struct fat_direntry *de) | 500 | struct fat_direntry *de) |
497 | { | 501 | { |
498 | unsigned char buf[BLOCK_SIZE]; | 502 | unsigned char buf[SECTOR_SIZE]; |
499 | unsigned char *eptr; | 503 | unsigned char *eptr; |
500 | int i; | 504 | int i; |
501 | int err; | 505 | int err; |
@@ -577,7 +581,7 @@ static int add_dir_entry(struct bpb *bpb, | |||
577 | else | 581 | else |
578 | { | 582 | { |
579 | /* Look for a free slot */ | 583 | /* Look for a free slot */ |
580 | for(i = 0;i < BLOCK_SIZE;i+=32) | 584 | for(i = 0;i < SECTOR_SIZE;i+=32) |
581 | { | 585 | { |
582 | firstbyte = buf[i]; | 586 | firstbyte = buf[i]; |
583 | if(firstbyte == 0xe5 || firstbyte == 0) | 587 | if(firstbyte == 0xe5 || firstbyte == 0) |
@@ -610,7 +614,7 @@ static int add_dir_entry(struct bpb *bpb, | |||
610 | if(firstbyte == 0) | 614 | if(firstbyte == 0) |
611 | { | 615 | { |
612 | i += 32; | 616 | i += 32; |
613 | if(i < BLOCK_SIZE) | 617 | if(i < SECTOR_SIZE) |
614 | { | 618 | { |
615 | buf[i] = 0; | 619 | buf[i] = 0; |
616 | /* We are done */ | 620 | /* We are done */ |
@@ -780,8 +784,9 @@ int fat_create_file(struct bpb *bpb, unsigned int currdir, char *name) | |||
780 | err = add_dir_entry(bpb, currdir, &de); | 784 | err = add_dir_entry(bpb, currdir, &de); |
781 | return err; | 785 | return err; |
782 | } | 786 | } |
787 | #endif | ||
783 | 788 | ||
784 | static int parse_direntry(struct fat_direntry *de, char *buf) | 789 | static int parse_direntry(struct fat_direntry *de, unsigned char *buf) |
785 | { | 790 | { |
786 | /* is this a long filename entry? */ | 791 | /* is this a long filename entry? */ |
787 | if ( ( buf[FATDIR_ATTR] & FAT_ATTR_LONG_NAME_MASK ) == | 792 | if ( ( buf[FATDIR_ATTR] & FAT_ATTR_LONG_NAME_MASK ) == |
@@ -798,11 +803,64 @@ static int parse_direntry(struct fat_direntry *de, char *buf) | |||
798 | de->wrtdate = BYTES2INT16(buf,FATDIR_WRTDATE); | 803 | de->wrtdate = BYTES2INT16(buf,FATDIR_WRTDATE); |
799 | de->wrttime = BYTES2INT16(buf,FATDIR_WRTTIME); | 804 | de->wrttime = BYTES2INT16(buf,FATDIR_WRTTIME); |
800 | de->filesize = BYTES2INT32(buf,FATDIR_FILESIZE); | 805 | de->filesize = BYTES2INT32(buf,FATDIR_FILESIZE); |
806 | de->firstcluster = BYTES2INT16(buf,FATDIR_FSTCLUSLO) | | ||
807 | (BYTES2INT16(buf,FATDIR_FSTCLUSHI) << 16); | ||
801 | strncpy(de->name, &buf[FATDIR_NAME], 11); | 808 | strncpy(de->name, &buf[FATDIR_NAME], 11); |
802 | 809 | ||
803 | return 1; | 810 | return 1; |
804 | } | 811 | } |
805 | 812 | ||
813 | int fat_open(struct bpb *bpb, | ||
814 | unsigned int startcluster, | ||
815 | struct fat_fileent *ent) | ||
816 | { | ||
817 | ent->firstcluster = startcluster; | ||
818 | ent->nextcluster = startcluster; | ||
819 | ent->nextsector = cluster2sec(bpb,startcluster); | ||
820 | ent->sectornum = 0; | ||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | int fat_read(struct bpb *bpb, | ||
825 | struct fat_fileent *ent, | ||
826 | int sectorcount, | ||
827 | void* buf ) | ||
828 | { | ||
829 | int cluster = ent->nextcluster; | ||
830 | int sector = ent->nextsector; | ||
831 | int numsec = ent->sectornum; | ||
832 | int err, i; | ||
833 | |||
834 | for ( i=0; i<sectorcount; i++ ) { | ||
835 | err = ata_read_sectors(sector,1,(char*)buf+(i*SECTOR_SIZE)); | ||
836 | if(err) { | ||
837 | DEBUG2( "fat_read() - Couldn't read sector %d" | ||
838 | " (error code %i)\n", sector,err); | ||
839 | return -1; | ||
840 | } | ||
841 | |||
842 | numsec++; | ||
843 | if ( numsec >= bpb->bpb_secperclus ) { | ||
844 | cluster = get_next_cluster(bpb,cluster); | ||
845 | if (!cluster) | ||
846 | break; /* end of file */ | ||
847 | |||
848 | sector = cluster2sec(bpb,cluster); | ||
849 | if (sector<0) | ||
850 | return -1; | ||
851 | numsec=0; | ||
852 | } | ||
853 | else | ||
854 | sector++; | ||
855 | } | ||
856 | ent->nextcluster = cluster; | ||
857 | ent->nextsector = sector; | ||
858 | ent->sectornum = numsec; | ||
859 | |||
860 | return sectorcount; | ||
861 | } | ||
862 | |||
863 | |||
806 | int fat_opendir(struct bpb *bpb, | 864 | int fat_opendir(struct bpb *bpb, |
807 | struct fat_dirent *ent, | 865 | struct fat_dirent *ent, |
808 | unsigned int currdir) | 866 | unsigned int currdir) |
@@ -848,7 +906,7 @@ int fat_getnext(struct bpb *bpb, | |||
848 | while(!done) | 906 | while(!done) |
849 | { | 907 | { |
850 | /* Look for a free slot */ | 908 | /* Look for a free slot */ |
851 | for(i = ent->entry;i < BLOCK_SIZE/32;i++) | 909 | for(i = ent->entry;i < SECTOR_SIZE/32;i++) |
852 | { | 910 | { |
853 | firstbyte = ent->cached_buf[i*32]; | 911 | firstbyte = ent->cached_buf[i*32]; |
854 | if(firstbyte == 0xe5) | 912 | if(firstbyte == 0xe5) |
@@ -865,7 +923,7 @@ int fat_getnext(struct bpb *bpb, | |||
865 | } | 923 | } |
866 | 924 | ||
867 | /* Next sector? */ | 925 | /* Next sector? */ |
868 | if(i < BLOCK_SIZE/32) | 926 | if(i < SECTOR_SIZE/32) |
869 | { | 927 | { |
870 | i++; | 928 | i++; |
871 | } | 929 | } |