summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-04-27 19:37:41 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-04-27 19:37:41 +0000
commite8bcc01edf28922d215111c1b43ff01d1c033a29 (patch)
tree569b3a2e9759526f70efdf33f9441bd725213553
parent31500d182486e2893dc64136c4638552cab1813c (diff)
downloadrockbox-e8bcc01edf28922d215111c1b43ff01d1c033a29.zip
rockbox-e8bcc01edf28922d215111c1b43ff01d1c033a29.tar.gz
rockbox-e8bcc01edf28922d215111c1b43ff01d1c033a29.tar.bz2
rockbox-e8bcc01edf28922d215111c1b43ff01d1c033a29.tar.xz
Added fat_open() and fat_read().
Renamed BLOCK_SIZE to SECTOR_SIZE. Added #ifdef DISK_WRITE to all write code. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@269 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/drivers/fat.c78
-rw-r--r--firmware/drivers/fat.h26
2 files changed, 89 insertions, 15 deletions
diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c
index 596166e..fe5cef8 100644
--- a/firmware/drivers/fat.c
+++ b/firmware/drivers/fat.c
@@ -115,13 +115,13 @@ struct fsinfo {
static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster);
static int get_bpb(struct bpb *bpb);
static int bpb_is_sane(struct bpb *bpb);
-static int flush_fat(struct bpb *bpb);
static void *cache_fat_sector(struct bpb *bpb, int secnum);
-static int update_entry(struct bpb *bpb, int entry, unsigned int val);
+#ifdef DISK_WRITE
static unsigned int getcurrdostime(unsigned short *dosdate,
unsigned short *dostime,
unsigned char *dostenth);
static int create_dos_name(unsigned char *name, unsigned char *newname);
+#endif
static unsigned char *fat_cache[256];
static int fat_cache_dirty[256];
@@ -189,7 +189,7 @@ static int first_sector_of_cluster(struct bpb *bpb, unsigned int cluster)
static int get_bpb(struct bpb *bpb)
{
- unsigned char buf[BLOCK_SIZE];
+ unsigned char buf[SECTOR_SIZE];
int err;
int datasec;
int countofclusters;
@@ -284,8 +284,9 @@ static int bpb_is_sane(struct bpb *bpb)
{
if(bpb->bpb_bytspersec != 512)
{
- DEBUG1( "bpb_is_sane() - Warning: sector size is not 512 (%i)\n",
+ DEBUG1( "bpb_is_sane() - Error: sector size is not 512 (%i)\n",
bpb->bpb_bytspersec);
+ return -1;
}
if(bpb->bpb_secperclus * bpb->bpb_bytspersec > 32768)
{
@@ -365,6 +366,7 @@ static void *cache_fat_sector(struct bpb *bpb, int secnum)
return sec;
}
+#ifdef DISK_WRITE
static int update_entry(struct bpb *bpb, int entry, unsigned int val)
{
unsigned long *sec;
@@ -393,6 +395,7 @@ static int update_entry(struct bpb *bpb, int entry, unsigned int val)
return 0;
}
+#endif
static int read_entry(struct bpb *bpb, int entry)
{
@@ -430,6 +433,7 @@ static int get_next_cluster(struct bpb *bpb, unsigned int cluster)
return next_cluster;
}
+#ifdef DISK_WRITE
static int flush_fat(struct bpb *bpb)
{
int i;
@@ -495,7 +499,7 @@ static int add_dir_entry(struct bpb *bpb,
unsigned int currdir,
struct fat_direntry *de)
{
- unsigned char buf[BLOCK_SIZE];
+ unsigned char buf[SECTOR_SIZE];
unsigned char *eptr;
int i;
int err;
@@ -577,7 +581,7 @@ static int add_dir_entry(struct bpb *bpb,
else
{
/* Look for a free slot */
- for(i = 0;i < BLOCK_SIZE;i+=32)
+ for(i = 0;i < SECTOR_SIZE;i+=32)
{
firstbyte = buf[i];
if(firstbyte == 0xe5 || firstbyte == 0)
@@ -610,7 +614,7 @@ static int add_dir_entry(struct bpb *bpb,
if(firstbyte == 0)
{
i += 32;
- if(i < BLOCK_SIZE)
+ if(i < SECTOR_SIZE)
{
buf[i] = 0;
/* We are done */
@@ -780,8 +784,9 @@ int fat_create_file(struct bpb *bpb, unsigned int currdir, char *name)
err = add_dir_entry(bpb, currdir, &de);
return err;
}
+#endif
-static int parse_direntry(struct fat_direntry *de, char *buf)
+static int parse_direntry(struct fat_direntry *de, unsigned char *buf)
{
/* is this a long filename entry? */
if ( ( buf[FATDIR_ATTR] & FAT_ATTR_LONG_NAME_MASK ) ==
@@ -798,11 +803,64 @@ static int parse_direntry(struct fat_direntry *de, char *buf)
de->wrtdate = BYTES2INT16(buf,FATDIR_WRTDATE);
de->wrttime = BYTES2INT16(buf,FATDIR_WRTTIME);
de->filesize = BYTES2INT32(buf,FATDIR_FILESIZE);
+ de->firstcluster = BYTES2INT16(buf,FATDIR_FSTCLUSLO) |
+ (BYTES2INT16(buf,FATDIR_FSTCLUSHI) << 16);
strncpy(de->name, &buf[FATDIR_NAME], 11);
return 1;
}
+int fat_open(struct bpb *bpb,
+ unsigned int startcluster,
+ struct fat_fileent *ent)
+{
+ ent->firstcluster = startcluster;
+ ent->nextcluster = startcluster;
+ ent->nextsector = cluster2sec(bpb,startcluster);
+ ent->sectornum = 0;
+ return 0;
+}
+
+int fat_read(struct bpb *bpb,
+ struct fat_fileent *ent,
+ int sectorcount,
+ void* buf )
+{
+ int cluster = ent->nextcluster;
+ int sector = ent->nextsector;
+ int numsec = ent->sectornum;
+ int err, i;
+
+ for ( i=0; i<sectorcount; i++ ) {
+ err = ata_read_sectors(sector,1,(char*)buf+(i*SECTOR_SIZE));
+ if(err) {
+ DEBUG2( "fat_read() - Couldn't read sector %d"
+ " (error code %i)\n", sector,err);
+ return -1;
+ }
+
+ numsec++;
+ if ( numsec >= bpb->bpb_secperclus ) {
+ cluster = get_next_cluster(bpb,cluster);
+ if (!cluster)
+ break; /* end of file */
+
+ sector = cluster2sec(bpb,cluster);
+ if (sector<0)
+ return -1;
+ numsec=0;
+ }
+ else
+ sector++;
+ }
+ ent->nextcluster = cluster;
+ ent->nextsector = sector;
+ ent->sectornum = numsec;
+
+ return sectorcount;
+}
+
+
int fat_opendir(struct bpb *bpb,
struct fat_dirent *ent,
unsigned int currdir)
@@ -848,7 +906,7 @@ int fat_getnext(struct bpb *bpb,
while(!done)
{
/* Look for a free slot */
- for(i = ent->entry;i < BLOCK_SIZE/32;i++)
+ for(i = ent->entry;i < SECTOR_SIZE/32;i++)
{
firstbyte = ent->cached_buf[i*32];
if(firstbyte == 0xe5)
@@ -865,7 +923,7 @@ int fat_getnext(struct bpb *bpb,
}
/* Next sector? */
- if(i < BLOCK_SIZE/32)
+ if(i < SECTOR_SIZE/32)
{
i++;
}
diff --git a/firmware/drivers/fat.h b/firmware/drivers/fat.h
index b60b3d4..a7c73c5 100644
--- a/firmware/drivers/fat.h
+++ b/firmware/drivers/fat.h
@@ -20,7 +20,7 @@
#ifndef FAT_H
#define FAT_H
-#define BLOCK_SIZE 512
+#define SECTOR_SIZE 512
struct bpb
{
@@ -71,12 +71,12 @@ struct fat_direntry
unsigned short crttime; /* Creation time */
unsigned short crtdate; /* Creation date */
unsigned short lstaccdate; /* Last access date */
- unsigned short fstclushi; /* High word of first cluster
- (0 for FAT12/16) */
unsigned short wrttime; /* Last write time */
unsigned short wrtdate; /* Last write date */
- unsigned short fstcluslo; /* Low word of first cluster */
unsigned int filesize; /* File size in bytes */
+ unsigned short fstclusterlo;
+ unsigned short fstclusterhi;
+ int firstcluster; /* fstclusterhi<<16 + fstcluslo */
};
#define FAT_ATTR_READ_ONLY 0x01
@@ -91,7 +91,15 @@ struct fat_dirent
int entry;
unsigned int cached_sec;
unsigned int num_sec;
- char cached_buf[BLOCK_SIZE];
+ char cached_buf[SECTOR_SIZE];
+};
+
+struct fat_fileent
+{
+ int firstcluster; /* first cluster in file */
+ int nextcluster; /* cluster of last access */
+ int nextsector; /* sector of last access */
+ int sectornum; /* sector number in this cluster */
};
extern int fat_create_file(struct bpb *bpb,
@@ -100,6 +108,14 @@ extern int fat_create_file(struct bpb *bpb,
extern int fat_create_dir(struct bpb *bpb,
unsigned int currdir,
char *name);
+extern int fat_open(struct bpb *bpb,
+ unsigned int cluster,
+ struct fat_fileent *ent);
+extern int fat_read(struct bpb *bpb,
+ struct fat_fileent *ent,
+ int sectorcount,
+ void* buf );
+
extern int fat_opendir(struct bpb *bpb,
struct fat_dirent *ent,
unsigned int currdir);