forked from len0rd/rockbox
preparations for hotswapping MMC
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5701 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
3662ad2ae3
commit
dc7534bdb2
7 changed files with 128 additions and 36 deletions
|
@ -67,6 +67,26 @@ static int strip_volume(const char* name, char* namecopy)
|
||||||
#endif /* #ifdef HAVE_MULTIVOLUME */
|
#endif /* #ifdef HAVE_MULTIVOLUME */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_HOTSWAP
|
||||||
|
// release all dir handles on a given volume "by force", to avoid leaks
|
||||||
|
int release_dirs(int volume)
|
||||||
|
{
|
||||||
|
DIR* pdir = opendirs;
|
||||||
|
int dd;
|
||||||
|
int closed = 0;
|
||||||
|
for ( dd=0; dd<MAX_OPEN_DIRS; dd++, pdir++)
|
||||||
|
{
|
||||||
|
if (pdir->fatdir.file.volume == volume)
|
||||||
|
{
|
||||||
|
pdir->busy = false; /* mark as available, no further action */
|
||||||
|
closed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closed; /* return how many we did */
|
||||||
|
}
|
||||||
|
#endif /* #ifdef HAVE_HOTSWAP */
|
||||||
|
|
||||||
|
|
||||||
DIR* opendir(const char* name)
|
DIR* opendir(const char* name)
|
||||||
{
|
{
|
||||||
char namecopy[MAX_PATH];
|
char namecopy[MAX_PATH];
|
||||||
|
@ -154,6 +174,10 @@ struct dirent* readdir(DIR* dir)
|
||||||
{
|
{
|
||||||
struct fat_direntry entry;
|
struct fat_direntry entry;
|
||||||
struct dirent* theent = &(dir->theent);
|
struct dirent* theent = &(dir->theent);
|
||||||
|
|
||||||
|
if (!dir->busy)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
#ifdef HAVE_MULTIVOLUME
|
#ifdef HAVE_MULTIVOLUME
|
||||||
/* Volumes (secondary file systems) get inserted into the root directory
|
/* Volumes (secondary file systems) get inserted into the root directory
|
||||||
of the first volume, since we have no separate top level. */
|
of the first volume, since we have no separate top level. */
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#ifdef HAVE_MMC
|
#ifdef HAVE_MMC
|
||||||
#include "ata_mmc.h"
|
#include "ata_mmc.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "file.h" /* for release_dirs() */
|
||||||
|
#include "dir.h" /* for release_files() */
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
|
|
||||||
/* Partition table entry layout:
|
/* Partition table entry layout:
|
||||||
|
@ -44,6 +46,7 @@
|
||||||
((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 ))
|
((long)array[pos+2] << 16 ) | ((long)array[pos+3] << 24 ))
|
||||||
|
|
||||||
static struct partinfo part[8]; /* space for 4 partitions on 2 drives */
|
static struct partinfo part[8]; /* space for 4 partitions on 2 drives */
|
||||||
|
static int vol_drive[NUM_VOLUMES]; /* mounted to which drive (-1 if none) */
|
||||||
|
|
||||||
struct partinfo* disk_init(IF_MV_NONVOID(int drive))
|
struct partinfo* disk_init(IF_MV_NONVOID(int drive))
|
||||||
{
|
{
|
||||||
|
@ -95,46 +98,86 @@ struct partinfo* disk_partinfo(int partition)
|
||||||
|
|
||||||
int disk_mount_all(void)
|
int disk_mount_all(void)
|
||||||
{
|
{
|
||||||
struct partinfo* pinfo;
|
int mounted;
|
||||||
int i,j;
|
int i;
|
||||||
int mounted = 0;
|
|
||||||
bool found;
|
fat_init(); /* reset all mounted partitions */
|
||||||
int drives = 1;
|
for (i=0; i<NUM_VOLUMES; i++)
|
||||||
|
vol_drive[i] = -1; /* mark all as unassigned */
|
||||||
|
|
||||||
|
mounted = disk_mount(0);
|
||||||
#ifdef HAVE_MMC
|
#ifdef HAVE_MMC
|
||||||
if (mmc_detect()) /* for Ondio, only if card detected */
|
if (mmc_detect()) /* for Ondio, only if card detected */
|
||||||
{
|
{
|
||||||
drives = 2; /* in such case we have two drives to try */
|
mounted += disk_mount(1); /* try 2nd "drive", too */
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fat_init(); /* reset all mounted partitions */
|
|
||||||
for (j=0; j<drives; j++)
|
|
||||||
{
|
|
||||||
found = false; /* reset partition-on-drive flag */
|
|
||||||
pinfo = disk_init(IF_MV(j));
|
|
||||||
if (pinfo == NULL)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (i=0; mounted<NUM_VOLUMES && i<4; i++)
|
|
||||||
{
|
|
||||||
if (!fat_mount(IF_MV2(mounted,) IF_MV2(j,) pinfo[i].start))
|
|
||||||
{
|
|
||||||
mounted++;
|
|
||||||
found = true; /* at least one valid entry */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!found && mounted<NUM_VOLUMES) /* none of the 4 entries worked? */
|
|
||||||
{ /* try "superfloppy" mode */
|
|
||||||
DEBUGF("No partition found, trying to mount sector 0.\n");
|
|
||||||
if (!fat_mount(IF_MV2(mounted,) IF_MV2(j,) 0))
|
|
||||||
{
|
|
||||||
mounted++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mounted;
|
return mounted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_free_volume(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i=0; i<NUM_VOLUMES; i++)
|
||||||
|
{
|
||||||
|
if (vol_drive[i] == -1) /* unassigned? */
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1; /* none found */
|
||||||
|
}
|
||||||
|
|
||||||
|
int disk_mount(int drive)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int mounted = 0; /* reset partition-on-drive flag */
|
||||||
|
int volume = get_free_volume();
|
||||||
|
struct partinfo* pinfo = disk_init(IF_MV(drive));
|
||||||
|
|
||||||
|
if (pinfo == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i=0; volume != -1 && i<4; i++)
|
||||||
|
{
|
||||||
|
if (!fat_mount(IF_MV2(volume,) IF_MV2(drive,) pinfo[i].start))
|
||||||
|
{
|
||||||
|
mounted++;
|
||||||
|
vol_drive[volume] = drive; /* remember the drive for this volume */
|
||||||
|
volume = get_free_volume(); /* prepare next entry */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mounted == 0 && volume != -1) /* none of the 4 entries worked? */
|
||||||
|
{ /* try "superfloppy" mode */
|
||||||
|
DEBUGF("No partition found, trying to mount sector 0.\n");
|
||||||
|
if (!fat_mount(IF_MV2(volume,) IF_MV2(drive,) 0))
|
||||||
|
{
|
||||||
|
mounted = 1;
|
||||||
|
vol_drive[volume] = drive; /* remember the drive for this volume */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mounted;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_HOTSWAP
|
||||||
|
int disk_unmount(int drive)
|
||||||
|
{
|
||||||
|
int unmounted = 0;
|
||||||
|
int i;
|
||||||
|
for (i=0; i<NUM_VOLUMES; i++)
|
||||||
|
{
|
||||||
|
if (vol_drive[i] == drive)
|
||||||
|
{ /* force releasing resources */
|
||||||
|
vol_drive[i] = -1; /* mark unused */
|
||||||
|
unmounted++;
|
||||||
|
release_files(i);
|
||||||
|
release_dirs(i);
|
||||||
|
fat_unmount(i, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unmounted;
|
||||||
|
}
|
||||||
|
#endif /* #ifdef HAVE_HOTSWAP */
|
||||||
|
|
|
@ -660,3 +660,23 @@ off_t filesize(int fd)
|
||||||
|
|
||||||
return file->size;
|
return file->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_HOTSWAP
|
||||||
|
// release all file handles on a given volume "by force", to avoid leaks
|
||||||
|
int release_files(int volume)
|
||||||
|
{
|
||||||
|
struct filedesc* pfile = openfiles;
|
||||||
|
int fd;
|
||||||
|
int closed = 0;
|
||||||
|
for ( fd=0; fd<MAX_OPEN_FILES; fd++, pfile++)
|
||||||
|
{
|
||||||
|
if (pfile->fatfile.volume == volume)
|
||||||
|
{
|
||||||
|
pfile->busy = false; /* mark as available, no further action */
|
||||||
|
closed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return closed; /* return how many we did */
|
||||||
|
}
|
||||||
|
#endif /* #ifdef HAVE_HOTSWAP */
|
||||||
|
|
|
@ -482,7 +482,7 @@ int fat_mount(IF_MV2(int volume,) IF_MV2(int drive,) long startsector)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_MULTIVOLUME
|
#ifdef HAVE_HOTSWAP
|
||||||
int fat_unmount(int volume, bool flush)
|
int fat_unmount(int volume, bool flush)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -511,7 +511,7 @@ int fat_unmount(int volume, bool flush)
|
||||||
fat_bpb->mounted = false;
|
fat_bpb->mounted = false;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif /* #ifdef HAVE_HOTSWAP */
|
||||||
|
|
||||||
void fat_recalc_free(IF_MV_NONVOID(int volume))
|
void fat_recalc_free(IF_MV_NONVOID(int volume))
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,5 +35,7 @@ struct partinfo {
|
||||||
struct partinfo* disk_init(IF_MV_NONVOID(int volume));
|
struct partinfo* disk_init(IF_MV_NONVOID(int volume));
|
||||||
struct partinfo* disk_partinfo(int partition);
|
struct partinfo* disk_partinfo(int partition);
|
||||||
int disk_mount_all(void); /* returns the # of successful mounts */
|
int disk_mount_all(void); /* returns the # of successful mounts */
|
||||||
|
int disk_mount(int drive);
|
||||||
|
int disk_unmount(int drive);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -84,6 +84,8 @@ extern int rmdir(const char* name);
|
||||||
|
|
||||||
extern struct dirent* readdir(DIR* dir);
|
extern struct dirent* readdir(DIR* dir);
|
||||||
|
|
||||||
|
extern int release_dirs(int volume);
|
||||||
|
|
||||||
#endif /* DIRFUNCTIONS_DEFINED */
|
#endif /* DIRFUNCTIONS_DEFINED */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -87,6 +87,7 @@ extern int remove(const char* pathname);
|
||||||
extern int rename(const char* path, const char* newname);
|
extern int rename(const char* path, const char* newname);
|
||||||
extern int ftruncate(int fd, off_t length);
|
extern int ftruncate(int fd, off_t length);
|
||||||
extern off_t filesize(int fd);
|
extern off_t filesize(int fd);
|
||||||
|
extern int release_files(int volume);
|
||||||
#endif /* SIMULATOR */
|
#endif /* SIMULATOR */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue