mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-23 03:52:45 -05:00
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
This commit is contained in:
parent
b4cf6a1a0b
commit
d2df3c01dc
1 changed files with 113 additions and 62 deletions
|
|
@ -429,14 +429,15 @@ static int find_free_cluster(int startcluster)
|
||||||
int offset = startcluster % CLUSTERS_PER_FAT_SECTOR;
|
int offset = startcluster % CLUSTERS_PER_FAT_SECTOR;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = sector; i<fat_bpb.fatsize; i++) {
|
for (i = 0; i<fat_bpb.fatsize; i++) {
|
||||||
int j;
|
int j;
|
||||||
unsigned int* fat = cache_fat_sector(i);
|
int nr = (i + sector) % fat_bpb.fatsize;
|
||||||
|
unsigned int* fat = cache_fat_sector(nr);
|
||||||
if ( !fat )
|
if ( !fat )
|
||||||
break;
|
break;
|
||||||
for (j = offset; j < CLUSTERS_PER_FAT_SECTOR; j++)
|
for (j = offset; j < CLUSTERS_PER_FAT_SECTOR; j++)
|
||||||
if (!(SWAB32(fat[j]) & 0x0fffffff)) {
|
if (!(SWAB32(fat[j]) & 0x0fffffff)) {
|
||||||
int c = i * CLUSTERS_PER_FAT_SECTOR + j;
|
int c = nr * CLUSTERS_PER_FAT_SECTOR + j;
|
||||||
LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c);
|
LDEBUGF("find_free_cluster(%x) == %x\n",startcluster,c);
|
||||||
fat_bpb.fsinfo.nextfree = c;
|
fat_bpb.fsinfo.nextfree = c;
|
||||||
return c;
|
return c;
|
||||||
|
|
@ -472,8 +473,10 @@ static int update_fat_entry(unsigned int entry, unsigned int val)
|
||||||
if (!(SWAB32(sec[offset]) & 0x0fffffff))
|
if (!(SWAB32(sec[offset]) & 0x0fffffff))
|
||||||
fat_bpb.fsinfo.freecount--;
|
fat_bpb.fsinfo.freecount--;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
if (SWAB32(sec[offset]) & 0x0fffffff)
|
||||||
fat_bpb.fsinfo.freecount++;
|
fat_bpb.fsinfo.freecount++;
|
||||||
|
}
|
||||||
|
|
||||||
/* don't change top 4 bits */
|
/* don't change top 4 bits */
|
||||||
sec[offset] &= SWAB32(0xf0000000);
|
sec[offset] &= SWAB32(0xf0000000);
|
||||||
|
|
@ -503,7 +506,6 @@ static int get_next_cluster(unsigned int cluster)
|
||||||
int next_cluster;
|
int next_cluster;
|
||||||
|
|
||||||
next_cluster = read_fat_entry(cluster);
|
next_cluster = read_fat_entry(cluster);
|
||||||
LDEBUGF("get_next_cluster(%x) == %x\n",cluster,next_cluster);
|
|
||||||
|
|
||||||
/* is this last cluster in chain? */
|
/* is this last cluster in chain? */
|
||||||
if ( next_cluster >= FAT_EOF_MARK )
|
if ( next_cluster >= FAT_EOF_MARK )
|
||||||
|
|
@ -630,6 +632,7 @@ static int add_dir_entry(struct fat_dir* dir,
|
||||||
|
|
||||||
while(!done)
|
while(!done)
|
||||||
{
|
{
|
||||||
|
bool new = false;
|
||||||
if (sec_cnt >= fat_bpb.bpb_secperclus)
|
if (sec_cnt >= fat_bpb.bpb_secperclus)
|
||||||
{
|
{
|
||||||
int oldcluster;
|
int oldcluster;
|
||||||
|
|
@ -645,19 +648,19 @@ static int add_dir_entry(struct fat_dir* dir,
|
||||||
/* end of dir, add new cluster */
|
/* end of dir, add new cluster */
|
||||||
LDEBUGF("Adding cluster to dir\n");
|
LDEBUGF("Adding cluster to dir\n");
|
||||||
currdir = find_free_cluster(fat_bpb.fsinfo.nextfree);
|
currdir = find_free_cluster(fat_bpb.fsinfo.nextfree);
|
||||||
if (!currdir) {
|
|
||||||
currdir = find_free_cluster(0);
|
|
||||||
if (!currdir) {
|
if (!currdir) {
|
||||||
DEBUGF("add_dir_entry(): Disk full!\n");
|
DEBUGF("add_dir_entry(): Disk full!\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
update_fat_entry(oldcluster, currdir);
|
update_fat_entry(oldcluster, currdir);
|
||||||
|
new = true;
|
||||||
|
memset(buf, 0, sizeof buf);
|
||||||
}
|
}
|
||||||
LDEBUGF("new cluster is %x\n", currdir);
|
LDEBUGF("new cluster is %x\n", currdir);
|
||||||
sec = cluster2sec(currdir);
|
sec = cluster2sec(currdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!new) {
|
||||||
LDEBUGF("Reading sector %x...\n", sec);
|
LDEBUGF("Reading sector %x...\n", sec);
|
||||||
/* Read the next sector in the current dir */
|
/* Read the next sector in the current dir */
|
||||||
err = ata_read_sectors(sec + fat_bpb.startsector,1,buf);
|
err = ata_read_sectors(sec + fat_bpb.startsector,1,buf);
|
||||||
|
|
@ -667,6 +670,7 @@ static int add_dir_entry(struct fat_dir* dir,
|
||||||
" (error code %d)\n", err);
|
" (error code %d)\n", err);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (need_to_update_last_empty_marker)
|
if (need_to_update_last_empty_marker)
|
||||||
{
|
{
|
||||||
|
|
@ -981,8 +985,7 @@ int fat_remove(struct fat_file* file)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fat_readwrite( struct fat_file *file, int sectorcount,
|
int fat_read( struct fat_file *file, int sectorcount, void* buf )
|
||||||
void* buf, bool write )
|
|
||||||
{
|
{
|
||||||
int cluster = file->lastcluster;
|
int cluster = file->lastcluster;
|
||||||
int sector = file->lastsector;
|
int sector = file->lastsector;
|
||||||
|
|
@ -990,49 +993,23 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
|
||||||
int first=0, last=0;
|
int first=0, last=0;
|
||||||
int err, i;
|
int err, i;
|
||||||
|
|
||||||
LDEBUGF( "fat_readwrite(file:%x,count:%d,buf:%x,%s)\n",
|
LDEBUGF( "fat_read(file:%x,count:%d,buf:%x)\n",
|
||||||
cluster,sectorcount,buf,write?"write":"read");
|
cluster,sectorcount,buf);
|
||||||
LDEBUGF( "fat_readwrite: c=%x s=%x n=%d\n", cluster,sector,numsec);
|
LDEBUGF( "fat_read: c=%x s=%x n=%d\n", cluster,sector,numsec);
|
||||||
if ( sector == -1 )
|
if ( sector == -1 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!write)
|
|
||||||
first = last = sector;
|
first = last = sector;
|
||||||
|
|
||||||
/* find sequential sectors and read/write them all at once */
|
/* find sequential sectors and read/write them all at once */
|
||||||
for (i=0; i<sectorcount && sector>=0; i++ ) {
|
for (i=0; i<sectorcount && sector>=0; i++ ) {
|
||||||
numsec++;
|
numsec++;
|
||||||
if ( numsec >= fat_bpb.bpb_secperclus || !cluster) {
|
if ( numsec >= fat_bpb.bpb_secperclus ) {
|
||||||
int oldcluster = cluster;
|
|
||||||
cluster = get_next_cluster(cluster);
|
cluster = get_next_cluster(cluster);
|
||||||
if (!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 */
|
/* reading past end-of-file */
|
||||||
sector = -1;
|
sector = -1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cluster) {
|
if (cluster) {
|
||||||
sector = cluster2sec(cluster);
|
sector = cluster2sec(cluster);
|
||||||
|
|
@ -1045,21 +1022,15 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
|
||||||
else
|
else
|
||||||
sector++;
|
sector++;
|
||||||
|
|
||||||
if (write && !first)
|
|
||||||
first = last = sector;
|
|
||||||
|
|
||||||
if ( (sector != last+1) || /* not sequential any more? */
|
if ( (sector != last+1) || /* not sequential any more? */
|
||||||
(i == sectorcount-1) || /* last sector requested? */
|
(i == sectorcount-1) || /* last sector requested? */
|
||||||
(last-first+1 == 256) ) { /* max 256 sectors per ata request */
|
(last-first+1 == 256) ) { /* max 256 sectors per ata request */
|
||||||
int count = last - first + 1;
|
int count = last - first + 1;
|
||||||
int start = first + fat_bpb.startsector;
|
int start = first + fat_bpb.startsector;
|
||||||
LDEBUGF("s=%x, l=%x, f=%x, i=%d\n",sector,last,first,i);
|
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) {
|
if (err) {
|
||||||
DEBUGF( "fat_readwrite() - Couldn't read sector %d"
|
DEBUGF( "fat_read() - Couldn't read sector %d"
|
||||||
" (error code %d)\n", sector,err);
|
" (error code %d)\n", sector,err);
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
@ -1076,6 +1047,86 @@ int fat_readwrite( struct fat_file *file, int sectorcount,
|
||||||
return 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<sectorcount && sector>=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 fat_seek(struct fat_file *file, int seeksector )
|
||||||
{
|
{
|
||||||
int cluster = file->firstcluster;
|
int cluster = file->firstcluster;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue