summaryrefslogtreecommitdiff
path: root/firmware/drivers/fat.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/fat.c')
-rw-r--r--firmware/drivers/fat.c78
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 {
115static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster); 115static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster);
116static int get_bpb(struct bpb *bpb); 116static int get_bpb(struct bpb *bpb);
117static int bpb_is_sane(struct bpb *bpb); 117static int bpb_is_sane(struct bpb *bpb);
118static int flush_fat(struct bpb *bpb);
119static void *cache_fat_sector(struct bpb *bpb, int secnum); 118static void *cache_fat_sector(struct bpb *bpb, int secnum);
120static int update_entry(struct bpb *bpb, int entry, unsigned int val); 119#ifdef DISK_WRITE
121static unsigned int getcurrdostime(unsigned short *dosdate, 120static unsigned int getcurrdostime(unsigned short *dosdate,
122 unsigned short *dostime, 121 unsigned short *dostime,
123 unsigned char *dostenth); 122 unsigned char *dostenth);
124static int create_dos_name(unsigned char *name, unsigned char *newname); 123static int create_dos_name(unsigned char *name, unsigned char *newname);
124#endif
125 125
126static unsigned char *fat_cache[256]; 126static unsigned char *fat_cache[256];
127static int fat_cache_dirty[256]; 127static int fat_cache_dirty[256];
@@ -189,7 +189,7 @@ static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster)
189 189
190static int get_bpb(struct bpb *bpb) 190static 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
368static int update_entry(struct bpb *bpb, int entry, unsigned int val) 370static 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
397static int read_entry(struct bpb *bpb, int entry) 400static 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
433static int flush_fat(struct bpb *bpb) 437static 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
784static int parse_direntry(struct fat_direntry *de, char *buf) 789static 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
813int 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
824int 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
806int fat_opendir(struct bpb *bpb, 864int 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 }