diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/fat.c | 78 | ||||
-rw-r--r-- | firmware/drivers/fat.h | 26 |
2 files changed, 89 insertions, 15 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 | } |
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h index b60b3d4164..a7c73c53fe 100644 --- a/firmware/drivers/fat.h +++ b/firmware/drivers/fat.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #ifndef FAT_H | 20 | #ifndef FAT_H |
21 | #define FAT_H | 21 | #define FAT_H |
22 | 22 | ||
23 | #define BLOCK_SIZE 512 | 23 | #define SECTOR_SIZE 512 |
24 | 24 | ||
25 | struct bpb | 25 | struct bpb |
26 | { | 26 | { |
@@ -71,12 +71,12 @@ struct fat_direntry | |||
71 | unsigned short crttime; /* Creation time */ | 71 | unsigned short crttime; /* Creation time */ |
72 | unsigned short crtdate; /* Creation date */ | 72 | unsigned short crtdate; /* Creation date */ |
73 | unsigned short lstaccdate; /* Last access date */ | 73 | unsigned short lstaccdate; /* Last access date */ |
74 | unsigned short fstclushi; /* High word of first cluster | ||
75 | (0 for FAT12/16) */ | ||
76 | unsigned short wrttime; /* Last write time */ | 74 | unsigned short wrttime; /* Last write time */ |
77 | unsigned short wrtdate; /* Last write date */ | 75 | unsigned short wrtdate; /* Last write date */ |
78 | unsigned short fstcluslo; /* Low word of first cluster */ | ||
79 | unsigned int filesize; /* File size in bytes */ | 76 | unsigned int filesize; /* File size in bytes */ |
77 | unsigned short fstclusterlo; | ||
78 | unsigned short fstclusterhi; | ||
79 | int firstcluster; /* fstclusterhi<<16 + fstcluslo */ | ||
80 | }; | 80 | }; |
81 | 81 | ||
82 | #define FAT_ATTR_READ_ONLY 0x01 | 82 | #define FAT_ATTR_READ_ONLY 0x01 |
@@ -91,7 +91,15 @@ struct fat_dirent | |||
91 | int entry; | 91 | int entry; |
92 | unsigned int cached_sec; | 92 | unsigned int cached_sec; |
93 | unsigned int num_sec; | 93 | unsigned int num_sec; |
94 | char cached_buf[BLOCK_SIZE]; | 94 | char cached_buf[SECTOR_SIZE]; |
95 | }; | ||
96 | |||
97 | struct fat_fileent | ||
98 | { | ||
99 | int firstcluster; /* first cluster in file */ | ||
100 | int nextcluster; /* cluster of last access */ | ||
101 | int nextsector; /* sector of last access */ | ||
102 | int sectornum; /* sector number in this cluster */ | ||
95 | }; | 103 | }; |
96 | 104 | ||
97 | extern int fat_create_file(struct bpb *bpb, | 105 | extern int fat_create_file(struct bpb *bpb, |
@@ -100,6 +108,14 @@ extern int fat_create_file(struct bpb *bpb, | |||
100 | extern int fat_create_dir(struct bpb *bpb, | 108 | extern int fat_create_dir(struct bpb *bpb, |
101 | unsigned int currdir, | 109 | unsigned int currdir, |
102 | char *name); | 110 | char *name); |
111 | extern int fat_open(struct bpb *bpb, | ||
112 | unsigned int cluster, | ||
113 | struct fat_fileent *ent); | ||
114 | extern int fat_read(struct bpb *bpb, | ||
115 | struct fat_fileent *ent, | ||
116 | int sectorcount, | ||
117 | void* buf ); | ||
118 | |||
103 | extern int fat_opendir(struct bpb *bpb, | 119 | extern int fat_opendir(struct bpb *bpb, |
104 | struct fat_dirent *ent, | 120 | struct fat_dirent *ent, |
105 | unsigned int currdir); | 121 | unsigned int currdir); |