diff options
| author | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-12-28 22:16:07 +0000 |
|---|---|---|
| committer | Jörg Hohensohn <hohensoh@rockbox.org> | 2004-12-28 22:16:07 +0000 |
| commit | da848576312800dc229624e928d132d0702c1854 (patch) | |
| tree | 38cd01b8a9c1069a1de734e0f7eb478436715573 /firmware/common | |
| parent | ae45d970d874217b779071b414dcd5edbf5647da (diff) | |
| download | rockbox-da848576312800dc229624e928d132d0702c1854.zip rockbox-da848576312800dc229624e928d132d0702c1854.tar.gz rockbox-da848576312800dc229624e928d132d0702c1854.tar.bz2 rockbox-da848576312800dc229624e928d132d0702c1854.tar.xz | |
prepared to mount multiple partitions into one logical file system (most useful for Ondio, internal memory + external MMC)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5514 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/common')
| -rw-r--r-- | firmware/common/dir.c | 83 | ||||
| -rw-r--r-- | firmware/common/disk.c | 26 | ||||
| -rw-r--r-- | firmware/common/file.c | 3 |
3 files changed, 97 insertions, 15 deletions
diff --git a/firmware/common/dir.c b/firmware/common/dir.c index 1bad932..5fa5f9d 100644 --- a/firmware/common/dir.c +++ b/firmware/common/dir.c @@ -23,11 +23,48 @@ #include "fat.h" #include "dir.h" #include "debug.h" +#include "atoi.h" #define MAX_OPEN_DIRS 8 static DIR opendirs[MAX_OPEN_DIRS]; +#ifdef HAVE_MULTIVOLUME + +/* how to name volumes, first char must be outside of legal file names, + a number gets appended to enumerate, if applicable */ +#ifdef HAVE_MMC +static const char* vol_names = ":MMC"; +#else +static const char* vol_names = ":HD"; +#endif + +/* returns on which volume this is, and copies the reduced name + (sortof a preprocessor for volume-decorated pathnames) */ +static int strip_volume(const char* name, char* namecopy) +{ + int volume = 0; + + if (name[1] == vol_names[0] ) /* a colon identifies our volumes */ + { + const char* temp; + temp = name + 1 + strlen(vol_names); /* behind special name */ + volume = atoi(temp); /* number is following */ + temp = strchr(temp, '/'); /* search for slash behind */ + if (temp != NULL) + name = temp; /* use the part behind the volume */ + else + name = "/"; /* else this must be the root dir */ + } + + strncpy(namecopy, name, MAX_PATH); + namecopy[MAX_PATH-1] = '\0'; + + return volume; +} +#endif /* #ifdef HAVE_MULTIVOLUME */ + + DIR* opendir(const char* name) { char namecopy[MAX_PATH]; @@ -35,6 +72,9 @@ DIR* opendir(const char* name) char* end; struct fat_direntry entry; int dd; +#ifdef HAVE_MULTIVOLUME + int volume; +#endif /* find a free dir descriptor */ for ( dd=0; dd<MAX_OPEN_DIRS; dd++ ) @@ -55,15 +95,21 @@ DIR* opendir(const char* name) return NULL; } - if ( fat_opendir(&(opendirs[dd].fatdir), 0, NULL) < 0 ) { +#ifdef HAVE_MULTIVOLUME + /* try to extract a heading volume name, if present */ + volume = strip_volume(name, namecopy); + opendirs[dd].volumecounter = 0; +#else + strncpy(namecopy,name,sizeof(namecopy)); /* just copy */ + namecopy[sizeof(namecopy)-1] = '\0'; +#endif + + if ( fat_opendir(IF_MV2(volume,) &(opendirs[dd].fatdir), 0, NULL) < 0 ) { DEBUGF("Failed opening root dir\n"); opendirs[dd].busy = false; return NULL; } - strncpy(namecopy,name,sizeof(namecopy)); - namecopy[sizeof(namecopy)-1] = 0; - for ( part = strtok_r(namecopy, "/", &end); part; part = strtok_r(NULL, "/", &end)) { /* scan dir for name */ @@ -76,7 +122,8 @@ DIR* opendir(const char* name) if ( (entry.attr & FAT_ATTR_DIRECTORY) && (!strcasecmp(part, entry.name)) ) { opendirs[dd].parent_dir = opendirs[dd].fatdir; - if ( fat_opendir(&(opendirs[dd].fatdir), + if ( fat_opendir(IF_MV2(volume,) + &(opendirs[dd].fatdir), entry.firstcluster, &(opendirs[dd].parent_dir)) < 0 ) { DEBUGF("Failed opening dir '%s' (%d)\n", @@ -84,6 +131,9 @@ DIR* opendir(const char* name) opendirs[dd].busy = false; return NULL; } +#ifdef HAVE_MULTIVOLUME + opendirs[dd].volumecounter = -1; /* n.a. to subdirs */ +#endif break; } } @@ -102,7 +152,28 @@ struct dirent* readdir(DIR* dir) { struct fat_direntry entry; struct dirent* theent = &(dir->theent); - +#ifdef HAVE_MULTIVOLUME + /* Volumes (secondary file systems) get inserted into the root directory + of the first volume, since we have no separate top level. */ + if (dir->volumecounter >= 0 /* on a root dir */ + && dir->volumecounter < NUM_VOLUMES /* in range */ + && dir->fatdir.file.volume == 0) /* at volume 0 */ + { /* fake special directories, which don't really exist, but + will get redirected upon opendir() */ + while (++dir->volumecounter < NUM_VOLUMES) + { + if (fat_ismounted(dir->volumecounter)) + { + memset(theent, 0, sizeof(*theent)); + theent->attribute = FAT_ATTR_DIRECTORY | FAT_ATTR_VOLUME; + snprintf(theent->d_name, sizeof(theent->d_name), + "%s%d", vol_names, dir->volumecounter); + return theent; + } + } + } +#endif + /* normal directory entry fetching follows here */ if (fat_getnext(&(dir->fatdir),&entry) < 0) return NULL; diff --git a/firmware/common/disk.c b/firmware/common/disk.c index b85f460..cfe1598 100644 --- a/firmware/common/disk.c +++ b/firmware/common/disk.c @@ -41,12 +41,22 @@ static struct partinfo part[8]; -struct partinfo* disk_init(void) +struct partinfo* disk_init(IF_MV_NONVOID(int drive)) { int i; unsigned char sector[512]; +#ifdef HAVE_MULTIVOLUME + /* For each drive, start at a different position, in order not to destroy + the first entry of drive 0. + That one is needed to calculate config sector position. */ + struct partinfo* pinfo = &part[drive*4]; + if ((size_t)drive >= sizeof(part)/sizeof(*part)/4) + return NULL; /* out of space in table */ +#else + struct partinfo* pinfo = part; +#endif - ata_read_sectors(0,1,§or); + ata_read_sectors(IF_MV2(drive,) 0,1,§or); /* check that the boot sector is initialized */ if ( (sector[510] != 0x55) || @@ -58,20 +68,20 @@ struct partinfo* disk_init(void) /* parse partitions */ for ( i=0; i<4; i++ ) { unsigned char* ptr = sector + 0x1be + 16*i; - part[i].type = ptr[4]; - part[i].start = BYTES2INT32(ptr, 8); - part[i].size = BYTES2INT32(ptr, 12); + pinfo[i].type = ptr[4]; + pinfo[i].start = BYTES2INT32(ptr, 8); + pinfo[i].size = BYTES2INT32(ptr, 12); DEBUGF("Part%d: Type %02x, start: %08x size: %08x\n", - i,part[i].type,part[i].start,part[i].size); + i,pinfo[i].type,pinfo[i].start,pinfo[i].size); /* extended? */ - if ( part[i].type == 5 ) { + if ( pinfo[i].type == 5 ) { /* not handled yet */ } } - return part; + return pinfo; } struct partinfo* disk_partinfo(int partition) diff --git a/firmware/common/file.c b/firmware/common/file.c index 81b5a19..6714b99 100644 --- a/firmware/common/file.c +++ b/firmware/common/file.c @@ -132,7 +132,8 @@ int open(const char* pathname, int flags) /* scan dir for name */ while ((entry = readdir(dir))) { if ( !strcasecmp(name, entry->d_name) ) { - fat_open(entry->startcluster, + fat_open(IF_MV2(dir->fatdir.file.volume,) + entry->startcluster, &(file->fatfile), &(dir->fatdir)); file->size = file->trunc ? 0 : entry->size; |