From d2df3c01dc34157fe3c0d414df7c68687f6aaedc Mon Sep 17 00:00:00 2001 From: Björn Stenberg Date: Wed, 30 Oct 2002 16:16:47 +0000 Subject: Improved find_free_cluster(). Split readwrite() in two to simplify debugging. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2783 a1c6a512-1295-4272-9138-f99709370657 --- firmware/drivers/fat.c | 175 +++++++++++++++++++++++++++++++------------------ 1 file changed, 113 insertions(+), 62 deletions(-) diff --git a/firmware/drivers/fat.c b/firmware/drivers/fat.c index 89b322e10a..40f9c47fa7 100644 --- a/firmware/drivers/fat.c +++ b/firmware/drivers/fat.c @@ -429,14 +429,15 @@ static int find_free_cluster(int startcluster) int offset = startcluster % CLUSTERS_PER_FAT_SECTOR; int i; - for (i = sector; i= FAT_EOF_MARK ) @@ -630,6 +632,7 @@ static int add_dir_entry(struct fat_dir* dir, while(!done) { + bool new = false; if (sec_cnt >= fat_bpb.bpb_secperclus) { int oldcluster; @@ -646,26 +649,27 @@ static int add_dir_entry(struct fat_dir* dir, LDEBUGF("Adding cluster to dir\n"); currdir = find_free_cluster(fat_bpb.fsinfo.nextfree); if (!currdir) { - currdir = find_free_cluster(0); - if (!currdir) { - DEBUGF("add_dir_entry(): Disk full!\n"); - return -1; - } + DEBUGF("add_dir_entry(): Disk full!\n"); + return -1; } update_fat_entry(oldcluster, currdir); + new = true; + memset(buf, 0, sizeof buf); } LDEBUGF("new cluster is %x\n", currdir); sec = cluster2sec(currdir); } - LDEBUGF("Reading sector %x...\n", sec); - /* Read the next sector in the current dir */ - err = ata_read_sectors(sec + fat_bpb.startsector,1,buf); - if (err) - { - DEBUGF( "add_dir_entry() - Couldn't read dir sector" - " (error code %d)\n", err); - return -2; + if (!new) { + LDEBUGF("Reading sector %x...\n", sec); + /* Read the next sector in the current dir */ + err = ata_read_sectors(sec + fat_bpb.startsector,1,buf); + if (err) + { + DEBUGF( "add_dir_entry() - Couldn't read dir sector" + " (error code %d)\n", err); + return -2; + } } if (need_to_update_last_empty_marker) @@ -981,8 +985,7 @@ int fat_remove(struct fat_file* file) return 0; } -int fat_readwrite( struct fat_file *file, int sectorcount, - void* buf, bool write ) +int fat_read( struct fat_file *file, int sectorcount, void* buf ) { int cluster = file->lastcluster; int sector = file->lastsector; @@ -990,48 +993,22 @@ int fat_readwrite( struct fat_file *file, int sectorcount, int first=0, last=0; int err, i; - LDEBUGF( "fat_readwrite(file:%x,count:%d,buf:%x,%s)\n", - cluster,sectorcount,buf,write?"write":"read"); - LDEBUGF( "fat_readwrite: c=%x s=%x n=%d\n", cluster,sector,numsec); + LDEBUGF( "fat_read(file:%x,count:%d,buf:%x)\n", + cluster,sectorcount,buf); + LDEBUGF( "fat_read: c=%x s=%x n=%d\n", cluster,sector,numsec); if ( sector == -1 ) return 0; - if (!write) - first = last = sector; + first = last = sector; /* find sequential sectors and read/write them all at once */ for (i=0; i=0; i++ ) { numsec++; - if ( numsec >= fat_bpb.bpb_secperclus || !cluster) { - int oldcluster = cluster; + if ( numsec >= fat_bpb.bpb_secperclus ) { cluster = get_next_cluster(cluster); if (!cluster) { - if ( write ) { - if (!oldcluster) /* new file */ - cluster = find_free_cluster(fat_bpb.fsinfo.nextfree); - else /* writing past end-of-file */ - cluster = find_free_cluster(oldcluster+1); - if (!cluster) { - /* no free cluster found after last, - search from beginning */ - cluster = find_free_cluster(0); - if (!cluster) { - /* no free clusters. disk is full. */ - sector = -1; - DEBUGF("fat_readwrite(): Disk full!\n"); - } - } - if ( cluster ) { - if ( !oldcluster ) - file->firstcluster = cluster; - else - update_fat_entry(oldcluster, cluster); - } - } - else { - /* reading past end-of-file */ - sector = -1; - } + /* reading past end-of-file */ + sector = -1; } if (cluster) { @@ -1045,21 +1022,15 @@ int fat_readwrite( struct fat_file *file, int sectorcount, else sector++; - if (write && !first) - first = last = sector; - if ( (sector != last+1) || /* not sequential any more? */ (i == sectorcount-1) || /* last sector requested? */ (last-first+1 == 256) ) { /* max 256 sectors per ata request */ int count = last - first + 1; int start = first + fat_bpb.startsector; LDEBUGF("s=%x, l=%x, f=%x, i=%d\n",sector,last,first,i); - if (write) - err = ata_write_sectors(start, count, buf); - else - err = ata_read_sectors(start, count, buf); + err = ata_read_sectors(start, count, buf); if (err) { - DEBUGF( "fat_readwrite() - Couldn't read sector %d" + DEBUGF( "fat_read() - Couldn't read sector %d" " (error code %d)\n", sector,err); return -2; } @@ -1076,6 +1047,86 @@ int fat_readwrite( struct fat_file *file, int sectorcount, return sectorcount; } +int fat_write( struct fat_file *file, int sectorcount, void* buf ) +{ + int cluster = file->lastcluster; + int sector = file->lastsector; + int numsec = file->sectornum; + int first=0, last=0; + int err, i; + + LDEBUGF( "fat_write(file:%x,count:%d,buf:%x)\n", + cluster,sectorcount,buf); + LDEBUGF( "fat_write: c=%x s=%x n=%d\n", cluster,sector,numsec); + if ( sector == -1 ) + return 0; + + /* find sequential sectors and write them all at once */ + for (i=0; i=0; i++ ) { + numsec++; + + /* find a new cluster */ + if ( numsec >= fat_bpb.bpb_secperclus || !cluster) { + int oldcluster = cluster; + cluster = get_next_cluster(cluster); + if (!cluster) { + if (!oldcluster) + cluster = find_free_cluster(fat_bpb.fsinfo.nextfree); + else + cluster = find_free_cluster(oldcluster+1); + + if (cluster) { + if ( !oldcluster ) + file->firstcluster = cluster; + else + update_fat_entry(oldcluster, cluster); + } + else { + sector = -1; + DEBUGF("fat_write(): Disk full!\n"); + } + } + + if (cluster) { + sector = cluster2sec(cluster); + LDEBUGF("cluster2sec(%x) == %x\n",cluster,sector); + if (sector<0) + return -1; + numsec=0; + + if (!oldcluster) + first = last = sector; + } + } + else + sector++; + + /* we start simple: one sector at a time */ + err = ata_write_sectors(sector, 1, buf); + if (err) { + DEBUGF( "fat_write() - Couldn't write sector %d" + " (error code %d)\n", sector,err); + return -2; + } + ((char*)buf) += SECTOR_SIZE; + } + + file->lastcluster = cluster; + file->lastsector = sector; + file->sectornum = numsec; + + return sectorcount; +} + +int fat_readwrite( struct fat_file *file, int sectorcount, + void* buf, bool write ) +{ + if (write) + return fat_write(file, sectorcount, buf); + else + return fat_read(file, sectorcount, buf); +} + int fat_seek(struct fat_file *file, int seeksector ) { int cluster = file->firstcluster; -- cgit v1.2.3