fygue: switch tabs to spaces :)

This commit is contained in:
Yann MAGNIN 2025-04-12 08:47:17 +02:00
parent 817e654e74
commit 7ff93e79f0
No known key found for this signature in database
GPG key ID: D82629D933EADC59
61 changed files with 2094 additions and 2101 deletions

View file

@ -12,13 +12,13 @@ int close(int fd)
int rc = 0;
if(d->type->close == NULL)
goto end;
/* Fugue's close primitive can flush pending IO write operation. So, we
* are in the same situation than the write() primitive: force-sync
* Fygue's descriptor to ensure data intergrity */
goto end;
/* Fugue's close primitive can flush pending IO write operation. So, we
* are in the same situation than the write() primitive: force-sync
* Fygue's descriptor to ensure data intergrity */
rc = d->type->close(d->data);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
end:
fs_free_descriptor(fd);

View file

@ -50,29 +50,29 @@ void fs_free_descriptor(int fd)
bool fs_descriptor_is_fugue(fs_descriptor_t const *desc)
{
return (
(desc->type == &fugue_dir_descriptor_type) ||
(desc->type == &fugue_descriptor_type)
);
return (
(desc->type == &fugue_dir_descriptor_type) ||
(desc->type == &fugue_descriptor_type)
);
}
bool fs_descriptor_is_fygue(fs_descriptor_t const *desc)
{
return (
(desc->type == &fygue_dir_descriptor_type) ||
(desc->type == &fygue_file_descriptor_type)
);
return (
(desc->type == &fygue_dir_descriptor_type) ||
(desc->type == &fygue_file_descriptor_type)
);
}
void fs_fygue_sync(void)
{
fygue_sync();
for (int i = 3 ; i < FS_FD_MAX ; i++) {
if (fdtable[i].type == NULL)
continue;
if (fs_descriptor_is_fygue(fdtable[i].data))
fygue_syncfs(fdtable[i].data);
}
fygue_sync();
for (int i = 3 ; i < FS_FD_MAX ; i++) {
if (fdtable[i].type == NULL)
continue;
if (fs_descriptor_is_fygue(fdtable[i].data))
fygue_syncfs(fdtable[i].data);
}
}
int open_generic(fs_descriptor_type_t const *type, void *data, int fd)

View file

@ -12,7 +12,7 @@ int BFile_Ext_Stat(uint16_t const *path, int *type, int *size)
uint16_t found_file[256];
struct BFile_FileInfo fileinfo;
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
rc = BFile_FindFirst(path, &search_handle, found_file, &fileinfo);
if(rc < 0) {
if(type) *type = -1;
@ -26,6 +26,6 @@ int BFile_Ext_Stat(uint16_t const *path, int *type, int *size)
}
BFile_FindClose(search_handle);
gint_world_leave();
gint_world_leave();
return rc;
}

View file

@ -13,7 +13,7 @@
ssize_t fugue_read(void *data0, void *buf, size_t size)
{
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
fugue_fd_t *data = data0;
int fugue_fd = data->fd;
@ -32,10 +32,10 @@ ssize_t fugue_read(void *data0, void *buf, size_t size)
errno = bfile_error_to_errno(rc);
size = -1;
} else {
data->pos += rc;
}
data->pos += rc;
}
gint_world_leave();
gint_world_leave();
return size;
}
@ -73,7 +73,7 @@ ssize_t fugue_write(void *data0, const void *buf, size_t size)
return -1;
}
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
while(written < size) {
size_t block_size = min(size - written, alloc_size);
memcpy(ram, buf + written, block_size);
@ -91,22 +91,22 @@ ssize_t fugue_write(void *data0, const void *buf, size_t size)
/* Partial write */
if(rc < (int)block_size) break;
}
gint_world_leave();
gint_world_leave();
free(ram);
return written;
}
/* Otherwise, we can write normally */
else {
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Write(fugue_fd, buf, size);
gint_world_leave();
gint_world_leave();
if(rc < 0) {
errno = bfile_error_to_errno(rc);
return -1;
}
data->pos += rc;
return rc;
return rc;
}
}
@ -118,20 +118,20 @@ off_t fugue_lseek(void *data0, off_t offset, int whence)
// TODO: fugue_lseek: CP400 optimization with native whence?
#if GINT_OS_CP
whence = (whence == SEEK_SET) ? BFileCP_SEEK_SET :
(whence == SEEK_CUR) ? BFileCP_SEEK_CUR :
BFileCP_SEEK_END;
gint_world_enter(GINT_WORLD_OS);
(whence == SEEK_CUR) ? BFileCP_SEEK_CUR :
BFileCP_SEEK_END;
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Seek(fugue_fd, offset, whence);
if(rc < 0) {
errno = bfile_error_to_errno(rc);
rc = -1;
} else {
data->pos = rc;
}
gint_world_leave();
data->pos = rc;
}
gint_world_leave();
return rc;
#else
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int filesize = BFile_Size(fugue_fd);
if(whence == SEEK_CUR)
@ -148,10 +148,10 @@ off_t fugue_lseek(void *data0, off_t offset, int whence)
errno = bfile_error_to_errno(rc);
offset = -1;
} else {
data->pos = offset;
}
data->pos = offset;
}
gint_world_leave();
gint_world_leave();
/* rc is the amount of space left in the file (including pre-allocated
space), so instead just return offset directly */
@ -161,7 +161,7 @@ off_t fugue_lseek(void *data0, off_t offset, int whence)
int fugue_close(void *data0)
{
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
fugue_fd_t *data = data0;
int fugue_fd = data->fd;
@ -171,9 +171,9 @@ int fugue_close(void *data0)
errno = bfile_error_to_errno(rc);
rc = -1;
} else {
rc = 0;
}
gint_world_leave();
rc = 0;
}
gint_world_leave();
free(data);
return rc;
}

View file

@ -98,7 +98,7 @@ void *fugue_dir_explore(char const *path)
/* We allocate by batches of 8 */
int sd=-1, rc, allocated=0;
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
dir_t *dp = malloc(sizeof *dp);
if(!dp) goto alloc_failure;
@ -165,6 +165,6 @@ end:
free(fc_path);
if(sd >= 0)
BFile_FindClose(sd);
gint_world_leave();
gint_world_leave();
return dp;
}

View file

@ -17,9 +17,9 @@ int fugue_mkdir(char const *path, GUNUSED mode_t mode)
return -1;
}
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Mkdir(normpath);
gint_world_leave();
gint_world_leave();
free(normpath);
#else
uint16_t *fcpath = fs_path_normalize_fc(path);
@ -28,15 +28,15 @@ int fugue_mkdir(char const *path, GUNUSED mode_t mode)
return -1;
}
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Create(fcpath, BFile_Folder, NULL);
gint_world_leave();
gint_world_leave();
free(fcpath);
#endif
if(rc < 0) {
errno = bfile_error_to_errno(rc);
return -1;
}
}
return rc;
}

View file

@ -45,7 +45,7 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode)
bfile_mode |= BFile_AppendFlag;
#endif
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
/* Stat the entry. A special case is needed for the root, which doesn't
respond well. fs_path_normalize_fc() normalizes the path so we just
@ -171,7 +171,7 @@ int fugue_open(char const *path, int flags, GUNUSED mode_t mode)
}
end:
gint_world_leave();
gint_world_leave();
#if GINT_OS_CP
free(normpath);
#endif

View file

@ -12,9 +12,9 @@ int fugue_rename(char const *oldpath, char const *newpath)
ENOTSUP_IF_NOT_FUGUE(-1);
#if GINT_OS_CP
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Rename(oldpath, newpath);
gint_world_leave();
gint_world_leave();
#else
u16 *fcpath_1 = fs_path_normalize_fc(oldpath);
if(!fcpath_1) {
@ -27,9 +27,9 @@ int fugue_rename(char const *oldpath, char const *newpath)
free(fcpath_1);
return -1;
}
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Rename(fcpath_1, fcpath_2);
gint_world_leave();
gint_world_leave();
free(fcpath_1);
free(fcpath_2);
#endif
@ -38,5 +38,5 @@ int fugue_rename(char const *oldpath, char const *newpath)
errno = bfile_error_to_errno(rc);
return -1;
}
return 0;
return 0;
}

View file

@ -36,9 +36,9 @@ int fugue_rmdir(char const *path)
}
#if GINT_OS_CP
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Remove(path);
gint_world_leave();
gint_world_leave();
#else
uint16_t *fcpath = fs_path_normalize_fc(path);
if(!fcpath) {
@ -46,9 +46,9 @@ int fugue_rmdir(char const *path)
return -1;
}
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int rc = BFile_Remove(fcpath);
gint_world_leave();
gint_world_leave();
free(fcpath);
#endif

View file

@ -19,9 +19,9 @@ int fugue_stat(char const * restrict path, struct stat * restrict statbuf)
}
int type, size, rc;
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
rc = BFile_Ext_Stat(fcpath, &type, &size);
gint_world_leave();
gint_world_leave();
free(fcpath);
if(rc < 0) {

View file

@ -26,7 +26,7 @@ int fugue_unlink(char const *path)
}
#endif
gint_world_enter(GINT_WORLD_OS);
gint_world_enter(GINT_WORLD_OS);
int type, size, rc;
rc = BFile_Ext_Stat(fcpath, &type, &size);
@ -54,7 +54,7 @@ int fugue_unlink(char const *path)
rc = 0;
end:
gint_world_leave();
gint_world_leave();
free(fcpath);
#if GINT_OS_CP
free(normpath);

View file

@ -12,47 +12,47 @@ int bfile_error_to_errno(int e)
{
#if GINT_OS_CP
switch(e) {
case BFileCP_ENOMEM: return ENOENT;
case BFileCP_EINVAL: return EINVAL;
case BFileCP_EDEVFAIL: return EIO;
case BFileCP_EMOUNTED: return ENODEV;
case BFileCP_EACCES: return EACCES;
case BFileCP_EBADFSID: return ENODEV;
case BFileCP_ENOVOLUME: return ENODEV;
case BFileCP_ENOPATH: return ENOENT;
case BFileCP_EEXIST: return EEXIST;
case BFileCP_ENAMETOOLONG: return EINVAL;
case BFileCP_EOUTOFBOUND: return EINVAL;
case BFileCP_EUNFORMAT: return EINVAL;
case BFileCP_ENOSPC: return ENOSPC;
case BFileCP_ENOENT: return ENOENT;
case BFileCP_EISDIRECTORY: return EISDIR;
case BFileCP_ESHARE: return EINVAL;
case BFileCP_EMFILE: return EMFILE;
case BFileCP_EBADF: return EBADF;
case BFileCP_EEOF: return EINVAL;
case BFileCP_ENOTEMPTY: return EINVAL;
case BFileCP_ECLUSTERSIZEMISMATCH: return EINVAL;
case BFileCP_ESYSTEM: return EINVAL;
default: return errno;
case BFileCP_ENOMEM: return ENOENT;
case BFileCP_EINVAL: return EINVAL;
case BFileCP_EDEVFAIL: return EIO;
case BFileCP_EMOUNTED: return ENODEV;
case BFileCP_EACCES: return EACCES;
case BFileCP_EBADFSID: return ENODEV;
case BFileCP_ENOVOLUME: return ENODEV;
case BFileCP_ENOPATH: return ENOENT;
case BFileCP_EEXIST: return EEXIST;
case BFileCP_ENAMETOOLONG: return EINVAL;
case BFileCP_EOUTOFBOUND: return EINVAL;
case BFileCP_EUNFORMAT: return EINVAL;
case BFileCP_ENOSPC: return ENOSPC;
case BFileCP_ENOENT: return ENOENT;
case BFileCP_EISDIRECTORY: return EISDIR;
case BFileCP_ESHARE: return EINVAL;
case BFileCP_EMFILE: return EMFILE;
case BFileCP_EBADF: return EBADF;
case BFileCP_EEOF: return EINVAL;
case BFileCP_ENOTEMPTY: return EINVAL;
case BFileCP_ECLUSTERSIZEMISMATCH: return EINVAL;
case BFileCP_ESYSTEM: return EINVAL;
default: return errno;
}
#else
/* TODO: Find BFile code for too many fds and map it to ENFILE. */
switch(e) {
case BFile_EntryNotFound: return ENOENT;
case BFile_IllegalPath: return EINVAL;
case BFile_DeviceFull: return EDQUOT;
case BFile_IllegalDevice: return EINVAL;
case BFile_AccessDenied: return EACCES;
case BFile_PermissionError: return EACCES;
case BFile_EntryFull: return EDQUOT;
case BFile_AlreadyExists: return EEXIST;
case BFile_ReadOnlyFile: return EACCES;
case BFile_EnumerateEnd: return ENOENT;
case BFile_IllegalSeekPos: return EINVAL;
case BFile_NotMountDevice: return ENOENT;
case BFile_DeviceNotFound: return ENOENT;
default: return errno;
case BFile_EntryNotFound: return ENOENT;
case BFile_IllegalPath: return EINVAL;
case BFile_DeviceFull: return EDQUOT;
case BFile_IllegalDevice: return EINVAL;
case BFile_AccessDenied: return EACCES;
case BFile_PermissionError: return EACCES;
case BFile_EntryFull: return EDQUOT;
case BFile_AlreadyExists: return EEXIST;
case BFile_ReadOnlyFile: return EACCES;
case BFile_EnumerateEnd: return ENOENT;
case BFile_IllegalSeekPos: return EINVAL;
case BFile_NotMountDevice: return ENOENT;
case BFile_DeviceNotFound: return ENOENT;
default: return errno;
}
#endif
}
@ -63,10 +63,10 @@ int bfile_type_to_mode_t(int bfile_type)
return bfile_type == BFile_Type_Directory ? S_IFDIR : S_IFREG;
#else
switch(bfile_type) {
case BFile_Type_Directory: return S_IFDIR;
case BFile_Type_Dot: return S_IFDIR;
case BFile_Type_DotDot: return S_IFDIR;
default: return S_IFREG;
case BFile_Type_Directory: return S_IFDIR;
case BFile_Type_Dot: return S_IFDIR;
case BFile_Type_DotDot: return S_IFDIR;
default: return S_IFREG;
}
#endif
}
@ -77,18 +77,18 @@ int bfile_type_to_dirent(int bfile_type)
return bfile_type == BFile_Type_Directory ? DT_DIR : DT_REG;
#else
switch(bfile_type) {
case BFile_Type_Directory: return DT_DIR;
case BFile_Type_Dot: return DT_DIR;
case BFile_Type_DotDot: return DT_DIR;
case BFile_Type_MainMem: return DT_REG;
case BFile_Type_File: return DT_REG;
case BFile_Type_Addin: return DT_REG;
case BFile_Type_Eact: return DT_REG;
case BFile_Type_Language: return DT_REG;
case BFile_Type_Bitmap: return DT_REG;
case BFile_Type_Volume: return DT_BLK;
case BFile_Type_Archived: return DT_REG;
default: return DT_UNKNOWN;
case BFile_Type_Directory: return DT_DIR;
case BFile_Type_Dot: return DT_DIR;
case BFile_Type_DotDot: return DT_DIR;
case BFile_Type_MainMem: return DT_REG;
case BFile_Type_File: return DT_REG;
case BFile_Type_Addin: return DT_REG;
case BFile_Type_Eact: return DT_REG;
case BFile_Type_Language: return DT_REG;
case BFile_Type_Bitmap: return DT_REG;
case BFile_Type_Volume: return DT_BLK;
case BFile_Type_Archived: return DT_REG;
default: return DT_UNKNOWN;
}
#endif
}

View file

@ -10,78 +10,78 @@
/* _fygue_fat16_cluster_get_next(): FAT16 cluster handling */
static int _fygue_fat16_cluster_get_next(
struct fygue_fat *fat,
int *cluster
struct fygue_fat *fat,
int *cluster
) {
uint16_t *fat0;
int nb_entry_per_sector;
int cluster_sector;
int cluster_real;
int rc;
uint16_t *fat0;
int nb_entry_per_sector;
int cluster_sector;
int cluster_real;
int rc;
nb_entry_per_sector = fat->SectorSize / 2;
cluster_sector = *cluster / nb_entry_per_sector;
cluster_real = *cluster - (cluster_sector * nb_entry_per_sector);
rc = fygue_fat_sector_get_addr(
fat,
(void*)&fat0,
fat->FAT0SectorID + cluster_sector
);
if (rc < 0)
return -1;
*cluster = FAT_WORD(fat0[cluster_real]);
return 0;
nb_entry_per_sector = fat->SectorSize / 2;
cluster_sector = *cluster / nb_entry_per_sector;
cluster_real = *cluster - (cluster_sector * nb_entry_per_sector);
rc = fygue_fat_sector_get_addr(
fat,
(void*)&fat0,
fat->FAT0SectorID + cluster_sector
);
if (rc < 0)
return -1;
*cluster = FAT_WORD(fat0[cluster_real]);
return 0;
}
/* _fygue_fat12_cluster_get_next(): FAT12 cluster handling */
// TODO: better calculus
static int _fygue_fat12_cluster_get_next(
struct fygue_fat *fat,
int *cluster
struct fygue_fat *fat,
int *cluster
) {
int fat_index0;
int fat_index1;
int fat_offset0;
int fat_offset1;
int fat_sector0;
int fat_sector1;
uintptr_t fat_data0;
uintptr_t fat_data1;
int fat_index0;
int fat_index1;
int fat_offset0;
int fat_offset1;
int fat_sector0;
int fat_sector1;
uintptr_t fat_data0;
uintptr_t fat_data1;
fat_index0 = *cluster + (*cluster / 2);
fat_index1 = fat_index0 + 1;
fat_sector0 = fat->FAT0SectorID + (fat_index0 / 512);
fat_sector1 = fat->FAT0SectorID + (fat_index1 / 512);
fat_index0 = *cluster + (*cluster / 2);
fat_index1 = fat_index0 + 1;
fat_sector0 = fat->FAT0SectorID + (fat_index0 / 512);
fat_sector1 = fat->FAT0SectorID + (fat_index1 / 512);
if (fat_sector0 == fat_sector1) {
if (fygue_fat_sector_get_addr(fat, &fat_data0, fat_sector0) != 0)
return -1;
fat_data1 = fat_data0;
fat_offset0 = fat_index0 - ((fat_index0 / 512) * 512);
fat_offset1 = fat_offset0 + 1;
} else {
if (fygue_fat_sector_get_addr(fat, &fat_data0, fat_sector0) != 0)
return -1;
if (fygue_fat_sector_get_addr(fat, &fat_data1, fat_sector1) != 0)
return -1;
fat_offset0 = fat_index0 - ((fat_index0 / 512) * 512);
fat_offset1 = fat_index1 - ((fat_index1 / 512) * 512);
}
if (fat_sector0 == fat_sector1) {
if (fygue_fat_sector_get_addr(fat, &fat_data0, fat_sector0) != 0)
return -1;
fat_data1 = fat_data0;
fat_offset0 = fat_index0 - ((fat_index0 / 512) * 512);
fat_offset1 = fat_offset0 + 1;
} else {
if (fygue_fat_sector_get_addr(fat, &fat_data0, fat_sector0) != 0)
return -1;
if (fygue_fat_sector_get_addr(fat, &fat_data1, fat_sector1) != 0)
return -1;
fat_offset0 = fat_index0 - ((fat_index0 / 512) * 512);
fat_offset1 = fat_index1 - ((fat_index1 / 512) * 512);
}
if (*cluster & 1) {
*cluster = (
(((((uint8_t*)fat_data0)[fat_offset0] & 0xf0) >> 4) << 0) |
(((((uint8_t*)fat_data1)[fat_offset1] & 0xff) >> 0) << 4)
);
} else {
*cluster = (
(((((uint8_t*)fat_data0)[fat_offset0] & 0xff) >> 0) << 0) |
(((((uint8_t*)fat_data1)[fat_offset1] & 0x0f) >> 0) << 8)
);
}
if (*cluster == 0x0fff)
*cluster = 0xffff;
return 0;
if (*cluster & 1) {
*cluster = (
(((((uint8_t*)fat_data0)[fat_offset0] & 0xf0) >> 4) << 0) |
(((((uint8_t*)fat_data1)[fat_offset1] & 0xff) >> 0) << 4)
);
} else {
*cluster = (
(((((uint8_t*)fat_data0)[fat_offset0] & 0xff) >> 0) << 0) |
(((((uint8_t*)fat_data1)[fat_offset1] & 0x0f) >> 0) << 8)
);
}
if (*cluster == 0x0fff)
*cluster = 0xffff;
return 0;
}
//---
@ -104,61 +104,61 @@ static int _fygue_fat12_cluster_get_next(
* - ensure FAT1 information is the same ? */
int fygue_fat_cluster_get_next(struct fygue_fat *fat, int *cluster_current)
{
int cluster;
int rc;
int cluster;
int rc;
if (fat == NULL || cluster_current == NULL)
return -1;
cluster = *cluster_current;
if (cluster == 0xffff)
return -3;
if (cluster == 0x0000)
return -4;
if (cluster <= 1)
return -2;
if (cluster >= fat->ClusterCount)
return -2;
if (fat->Type == FYGUE_FAT_TYPE_FAT12)
rc = _fygue_fat12_cluster_get_next(fat, &cluster);
if (fat->Type == FYGUE_FAT_TYPE_FAT16)
rc = _fygue_fat16_cluster_get_next(fat, &cluster);
if (rc != 0)
return -5;
if (cluster == 0xffff)
rc = -6;
if (cluster == 0x0000)
rc = -7;
*cluster_current = cluster;
return rc;
if (fat == NULL || cluster_current == NULL)
return -1;
cluster = *cluster_current;
if (cluster == 0xffff)
return -3;
if (cluster == 0x0000)
return -4;
if (cluster <= 1)
return -2;
if (cluster >= fat->ClusterCount)
return -2;
if (fat->Type == FYGUE_FAT_TYPE_FAT12)
rc = _fygue_fat12_cluster_get_next(fat, &cluster);
if (fat->Type == FYGUE_FAT_TYPE_FAT16)
rc = _fygue_fat16_cluster_get_next(fat, &cluster);
if (rc != 0)
return -5;
if (cluster == 0xffff)
rc = -6;
if (cluster == 0x0000)
rc = -7;
*cluster_current = cluster;
return rc;
}
/* fygue_fat_cluster_get_sector() - get sector ID from cluster ID */
int fygue_fat_cluster_get_sector(
struct fygue_fat *fat,
int cluster_id,
int *sector_id
struct fygue_fat *fat,
int cluster_id,
int *sector_id
) {
if (fat == NULL || sector_id == NULL)
return -1;
if (cluster_id >= fat->ClusterCount)
return -1;
if (cluster_id <= 1) {
*sector_id = fat->RootSectorID;
} else {
*sector_id = fat->DataSectorID + ((cluster_id - 2) * 8);
}
return 0;
if (fat == NULL || sector_id == NULL)
return -1;
if (cluster_id >= fat->ClusterCount)
return -1;
if (cluster_id <= 1) {
*sector_id = fat->RootSectorID;
} else {
*sector_id = fat->DataSectorID + ((cluster_id - 2) * 8);
}
return 0;
}
/* fygue_fat_get_cluster_addr() - get logical sector addr */
int fygue_fat_cluster_get_addr(
struct fygue_fat *fat,
uintptr_t *addr,
int cluster_id
struct fygue_fat *fat,
uintptr_t *addr,
int cluster_id
) {
int sector_id;
int sector_id;
if (fygue_fat_cluster_get_sector(fat, cluster_id, &sector_id) != 0)
return -1;
return fygue_fat_sector_get_addr(fat, addr, sector_id);
if (fygue_fat_cluster_get_sector(fat, cluster_id, &sector_id) != 0)
return -1;
return fygue_fat_sector_get_addr(fat, addr, sector_id);
}

View file

@ -1,5 +1,5 @@
/*
** fygue/fat/initialize - FAT initialization
** fygue/fat/initialize - FAT initialization
*/
#include <string.h>
#include <errno.h>
@ -15,35 +15,35 @@
/* struct _fat_bpb : Bios Parameter Block */
struct _fat_bpb
{
// common boot structure
uint8_t BS_jmpBoot[3];
uint8_t BS_OEMName[8];
// common boot structure
uint8_t BS_jmpBoot[3];
uint8_t BS_OEMName[8];
// BIOS parameter Block
uint16_t BPB_BytsPerSec;
uint8_t BPB_SecPerClus;
uint16_t BPB_RsvdSecCnt;
uint8_t BPB_NumFATs;
uint16_t BPB_RootEntCnt;
uint16_t BPB_TotSec16;
uint8_t BPB_Media;
uint16_t BPB_FATSz16;
uint16_t BPB_SecPerTrk;
uint16_t BPB_NumHeads;
uint32_t BPB_HiddSec;
uint32_t BPB_TotSec32;
// BIOS parameter Block
uint16_t BPB_BytsPerSec;
uint8_t BPB_SecPerClus;
uint16_t BPB_RsvdSecCnt;
uint8_t BPB_NumFATs;
uint16_t BPB_RootEntCnt;
uint16_t BPB_TotSec16;
uint8_t BPB_Media;
uint16_t BPB_FATSz16;
uint16_t BPB_SecPerTrk;
uint16_t BPB_NumHeads;
uint32_t BPB_HiddSec;
uint32_t BPB_TotSec32;
// Extended BIOS Parameter Block
uint8_t BS_DrvNum;
uint8_t BS_Reserved1;
uint8_t BS_BootSig;
uint8_t BS_VolID[4];
uint8_t BS_VolLab[11];
uint8_t BS_FilSysType[8];
uint8_t _unused[448];
// Extended BIOS Parameter Block
uint8_t BS_DrvNum;
uint8_t BS_Reserved1;
uint8_t BS_BootSig;
uint8_t BS_VolID[4];
uint8_t BS_VolLab[11];
uint8_t BS_FilSysType[8];
uint8_t _unused[448];
// Signature
uint8_t Signature_word[2];
// Signature
uint8_t Signature_word[2];
} GPACKED(1);
@ -55,35 +55,35 @@ struct _fat_bpb
* on fecthed information, Fugue select an hardcoded FAT configuration
*
* return
* -1 unable to load the sector0
* -2 unsupported Fugue configuration */
* -1 unable to load the sector0
* -2 unsupported Fugue configuration */
static int _fygue_fat_sector0(struct fygue_fat *fat)
{
uint8_t *sector;
int rc;
uint8_t *sector;
int rc;
if (fygue_fat_sector_get_addr(fat, (void*)&sector, 0) != 0)
return -1;
fat->SectorHiddenCount = (
(sector[0x1c9] << 24) |
(sector[0x1c8] << 16) |
(sector[0x1c7] << 8) |
(sector[0x1c6] << 0)
);
fat->SectorCount = (
(sector[0x1cd] << 24) |
(sector[0x1cc] << 16) |
(sector[0x1cb] << 8) |
(sector[0x1ca] << 0)
);
rc = fygue_fat_sector_get_addr(
fat,
&fat->BPB,
fat->SectorHiddenCount
);
if (rc != 0)
return -2;
return 0;
if (fygue_fat_sector_get_addr(fat, (void*)&sector, 0) != 0)
return -1;
fat->SectorHiddenCount = (
(sector[0x1c9] << 24) |
(sector[0x1c8] << 16) |
(sector[0x1c7] << 8) |
(sector[0x1c6] << 0)
);
fat->SectorCount = (
(sector[0x1cd] << 24) |
(sector[0x1cc] << 16) |
(sector[0x1cb] << 8) |
(sector[0x1ca] << 0)
);
rc = fygue_fat_sector_get_addr(
fat,
&fat->BPB,
fat->SectorHiddenCount
);
if (rc != 0)
return -2;
return 0;
}
/* _fygue_fat_configure() - configure the FAT information
@ -97,56 +97,56 @@ static int _fygue_fat_sector0(struct fygue_fat *fat)
* FAT */
static int _fygue_fat_configure(struct fygue_fat *fat)
{
struct _fat_bpb *bpb;
int RootDirSectors;
int DataSec;
struct _fat_bpb *bpb;
int RootDirSectors;
int DataSec;
bpb = (void *)fat->BPB;
bpb = (void *)fat->BPB;
RootDirSectors = FAT_WORD(bpb->BPB_RootEntCnt) * 32;
RootDirSectors += FAT_WORD(bpb->BPB_BytsPerSec) - 1;
RootDirSectors /= FAT_WORD(bpb->BPB_BytsPerSec);
DataSec = FAT_WORD(bpb->BPB_RsvdSecCnt);
DataSec += FAT_WORD(bpb->BPB_FATSz16) * bpb->BPB_NumFATs;
DataSec += RootDirSectors;
DataSec = FAT_WORD(bpb->BPB_TotSec16) - DataSec;
fat->ClusterCount = DataSec / bpb->BPB_SecPerClus;
if (fat->ClusterCount < 4085) {
fat->Type = FYGUE_FAT_TYPE_FAT12;
} else if (fat->ClusterCount < 65525) {
fat->Type = FYGUE_FAT_TYPE_FAT16;
} else {
// TODO: (FAT32) maybe gint panic ?
return -2;
}
RootDirSectors = FAT_WORD(bpb->BPB_RootEntCnt) * 32;
RootDirSectors += FAT_WORD(bpb->BPB_BytsPerSec) - 1;
RootDirSectors /= FAT_WORD(bpb->BPB_BytsPerSec);
DataSec = FAT_WORD(bpb->BPB_RsvdSecCnt);
DataSec += FAT_WORD(bpb->BPB_FATSz16) * bpb->BPB_NumFATs;
DataSec += RootDirSectors;
DataSec = FAT_WORD(bpb->BPB_TotSec16) - DataSec;
fat->ClusterCount = DataSec / bpb->BPB_SecPerClus;
if (fat->ClusterCount < 4085) {
fat->Type = FYGUE_FAT_TYPE_FAT12;
} else if (fat->ClusterCount < 65525) {
fat->Type = FYGUE_FAT_TYPE_FAT16;
} else {
// TODO: (FAT32) maybe gint panic ?
return -2;
}
fat->TotalCapacity = DataSec * FAT_WORD(bpb->BPB_BytsPerSec);
fat->RootEntCount = FAT_WORD(bpb->BPB_RootEntCnt);
fat->SectorSize = FAT_WORD(bpb->BPB_BytsPerSec);
fat->SectorPerClus = bpb->BPB_SecPerClus;
fat->TotalCapacity = DataSec * FAT_WORD(bpb->BPB_BytsPerSec);
fat->RootEntCount = FAT_WORD(bpb->BPB_RootEntCnt);
fat->SectorSize = FAT_WORD(bpb->BPB_BytsPerSec);
fat->SectorPerClus = bpb->BPB_SecPerClus;
fat->FAT0SectorID = fat->SectorHiddenCount;
fat->FAT0SectorID += FAT_WORD(bpb->BPB_RsvdSecCnt);
fat->FAT1SectorID = fat->FAT0SectorID;
fat->FAT1SectorID += FAT_WORD(bpb->BPB_FATSz16);
fat->RootSectorID = fat->FAT1SectorID;
fat->RootSectorID += FAT_WORD(bpb->BPB_FATSz16);
fat->DataSectorID = fat->RootSectorID;
fat->DataSectorID += RootDirSectors;
return 0;
fat->FAT0SectorID = fat->SectorHiddenCount;
fat->FAT0SectorID += FAT_WORD(bpb->BPB_RsvdSecCnt);
fat->FAT1SectorID = fat->FAT0SectorID;
fat->FAT1SectorID += FAT_WORD(bpb->BPB_FATSz16);
fat->RootSectorID = fat->FAT1SectorID;
fat->RootSectorID += FAT_WORD(bpb->BPB_FATSz16);
fat->DataSectorID = fat->RootSectorID;
fat->DataSectorID += RootDirSectors;
return 0;
}
/* _fygue_fat_prepare() - prepare logic information */
static int _fygue_fat_prepare(struct fygue_fat *fat)
{
int rc = fygue_fat_sector_get_addr(
fat,
&fat->RootAddr,
fat->RootSectorID
);
if (rc != 0)
return -1;
return 0;
int rc = fygue_fat_sector_get_addr(
fat,
&fat->RootAddr,
fat->RootSectorID
);
if (rc != 0)
return -1;
return 0;
}
//---
@ -156,28 +156,28 @@ static int _fygue_fat_prepare(struct fygue_fat *fat)
/* fygue_fat_initialize() - fully initialize the FAT information */
int fygue_fat_initialize(struct fygue_fat *fat)
{
if (fat == NULL)
return -1;
memset(fat, 0x00, sizeof(struct fygue_fat));
if (fygue_flash_initialize(&(fat->_flash)) != 0)
return -2;
if (_fygue_fat_sector0(fat) != 0)
return -3;
if (_fygue_fat_configure(fat) != 0)
return -4;
if (_fygue_fat_prepare(fat) != 0)
return -5;
return 0;
if (fat == NULL)
return -1;
memset(fat, 0x00, sizeof(struct fygue_fat));
if (fygue_flash_initialize(&(fat->_flash)) != 0)
return -2;
if (_fygue_fat_sector0(fat) != 0)
return -3;
if (_fygue_fat_configure(fat) != 0)
return -4;
if (_fygue_fat_prepare(fat) != 0)
return -5;
return 0;
}
/* fygue_fat_sync(): re-initialize the FAT information */
int fygue_fat_sync(struct fygue_fat *fat)
{
if (fat == NULL)
return -1;
if (fygue_flash_sync((&fat->_flash)) != 0)
return -2;
if (_fygue_fat_prepare(fat) != 0)
return -3;
return 0;
if (fat == NULL)
return -1;
if (fygue_flash_sync((&fat->_flash)) != 0)
return -2;
if (_fygue_fat_prepare(fat) != 0)
return -3;
return 0;
}

View file

@ -8,21 +8,21 @@
/* _FAT_WORD() : helper for 16bit value */
#define FAT_WORD(x) \
(((x & 0xff00) >> 8) | ((x & 0x00ff) << 8))
(((x & 0xff00) >> 8) | ((x & 0x00ff) << 8))
/* _FAT_DWORD() : helper for 32bit value */
#define FAT_DWORD(x) ( \
(((x) & 0xff000000) >> 24) \
| (((x) & 0x00ff0000) >> 8) \
| (((x) & 0x0000ff00) << 8) \
| (((x) & 0x000000ff) << 24) \
#define FAT_DWORD(x) ( \
(((x) & 0xff000000) >> 24) \
| (((x) & 0x00ff0000) >> 8) \
| (((x) & 0x0000ff00) << 8) \
| (((x) & 0x000000ff) << 24) \
)
/* FYGUE_FAT_ATTR_* : FAT dirent attribute */
#define FYGUE_FAT_ATTR_READ_ONLY 0x01
#define FYGUE_FAT_ATTR_HIDDEN 0x02
#define FYGUE_FAT_ATTR_SYSTEM 0x04
#define FYGUE_FAT_ATTR_VOLUME 0x08
#define FYGUE_FAT_ATTR_HIDDEN 0x02
#define FYGUE_FAT_ATTR_SYSTEM 0x04
#define FYGUE_FAT_ATTR_VOLUME 0x08
#define FYGUE_FAT_ATTR_DIRECTORY 0x10
#define FYGUE_FAT_ATTR_ARCHIVE 0x20
@ -30,81 +30,81 @@
// TODO: rename fields
struct fygue_fat
{
enum {
FYGUE_FAT_TYPE_FAT12 = 0,
FYGUE_FAT_TYPE_FAT16 = 1,
} Type;
int SectorHiddenCount;
int SectorCount;
int SectorSize;
int SectorPerClus;
int ClusterCount;
int TotalCapacity;
int RootEntCount;
int FAT0SectorID;
int FAT1SectorID;
int RootSectorID;
int DataSectorID;
uintptr_t RootAddr;
uintptr_t BPB;
struct fygue_flash _flash;
enum {
FYGUE_FAT_TYPE_FAT12 = 0,
FYGUE_FAT_TYPE_FAT16 = 1,
} Type;
int SectorHiddenCount;
int SectorCount;
int SectorSize;
int SectorPerClus;
int ClusterCount;
int TotalCapacity;
int RootEntCount;
int FAT0SectorID;
int FAT1SectorID;
int RootSectorID;
int DataSectorID;
uintptr_t RootAddr;
uintptr_t BPB;
struct fygue_flash _flash;
};
/* fygue_fat_dirent - FAT dirent information */
//TODO: flexible name array like the high-level `struct dirent` ?
struct fygue_fat_dirent
{
char name[256];
size_t size;
uintptr_t meta_addr;
unsigned int cluster_id;
int attribute;
char name[256];
size_t size;
uintptr_t meta_addr;
unsigned int cluster_id;
int attribute;
};
/* fygue_fat_dir - fygue directory information */
struct fygue_fat_dir
{
int cluster_entry;
int cluster_current;
int root_dirent_count;
int sector_id;
int sector_count;
int dirent_cursor;
uintptr_t dirent_current_addr;
bool end_of_dirent;
bool dirty;
int attribute;
int cluster_entry;
int cluster_current;
int root_dirent_count;
int sector_id;
int sector_count;
int dirent_cursor;
uintptr_t dirent_current_addr;
bool end_of_dirent;
bool dirty;
int attribute;
};
/* fygue_fat_file: file information needed to perform IO primitives */
struct fygue_fat_file
{
int cluster_entry;
int attribute;
size_t size;
off_t cursor;
struct {
uintptr_t addr;
size_t size;
int cluster_count;
} *chunk;
int chunk_table_max_index;
int chunk_count;
int chunk_rd_index;
int chunk_rd_offset;
int cluster_entry;
int attribute;
size_t size;
off_t cursor;
struct {
uintptr_t addr;
size_t size;
int cluster_count;
} *chunk;
int chunk_table_max_index;
int chunk_count;
int chunk_rd_index;
int chunk_rd_offset;
};
/* fygue_fat_descriptor: FAT descriptor information */
struct fygue_fat_descriptor
{
enum {
FYGUE_FAT_DESC_TYPE_FILE,
FYGUE_FAT_DESC_TYPE_DIR,
} type;
union {
struct fygue_fat_file file;
struct fygue_fat_dir dir;
};
enum {
FYGUE_FAT_DESC_TYPE_FILE,
FYGUE_FAT_DESC_TYPE_DIR,
} type;
union {
struct fygue_fat_file file;
struct fygue_fat_dir dir;
};
};
//---
@ -119,9 +119,9 @@ extern int fygue_fat_sync(struct fygue_fat *fat);
/* fygue_fat_open() - resolve the path and set the dirent information */
extern int fygue_fat_open(
struct fygue_fat *fat,
char const * const path,
struct fygue_fat_descriptor *desc
struct fygue_fat *fat,
char const * const path,
struct fygue_fat_descriptor *desc
);
//---
@ -130,36 +130,36 @@ extern int fygue_fat_open(
/* fugue_fat_dir_open(): convert dirent to dir */
extern int fygue_fat_dir_open(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
);
/* fygue_fat_dir_read(): readdir primitive */
extern int fygue_fat_dir_read(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
);
/* fygue_fat_dir_close(): closedir primitive */
extern int fygue_fat_dir_close(
struct fygue_fat *fat,
struct fygue_fat_dir *dir
struct fygue_fat *fat,
struct fygue_fat_dir *dir
);
/* fygue_fat_dir_stat(): directory stat primitive */
extern int fygue_fat_dir_stat(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct stat *statbuf
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct stat *statbuf
);
/* fygue_fat_dir_sync(): sync directory information */
extern int fygue_fat_dir_sync(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
int cluster_id
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
int cluster_id
);
//---
@ -168,44 +168,44 @@ extern int fygue_fat_dir_sync(
/* _fygue_fat_file_open(): generate file information */
extern int fygue_fat_file_open(
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct fygue_fat_dirent *dirent
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct fygue_fat_dirent *dirent
);
/* fygue_fat_file_read(): read primitive */
extern int fygue_fat_file_read(
struct fygue_fat *fat,
struct fygue_fat_file *file,
void *buffer,
size_t size
struct fygue_fat *fat,
struct fygue_fat_file *file,
void *buffer,
size_t size
);
/* fygue_fat_file_stat(): stat primitive */
extern int fygue_fat_file_stat(
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct stat *statbuf
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct stat *statbuf
);
/* fygue_fat_file_seek(): lseek primitive */
extern int fygue_fat_file_seek(
struct fygue_fat *fat,
struct fygue_fat_file *file,
off_t offset
struct fygue_fat *fat,
struct fygue_fat_file *file,
off_t offset
);
/* fygue_fat_file_close(): close primitive */
extern int fygue_fat_file_close(
struct fygue_fat *fat,
struct fygue_fat_file *file
struct fygue_fat *fat,
struct fygue_fat_file *file
);
/* fygue_fat_file_sync(): sync internal information */
extern int fygue_fat_file_sync(
struct fygue_fat *fat,
struct fygue_fat_file *file,
int cluster_id
struct fygue_fat *fat,
struct fygue_fat_file *file,
int cluster_id
);
//---
@ -214,22 +214,22 @@ extern int fygue_fat_file_sync(
/* fygue_fat_cluster_get_next() - find the next cluster ID of a file */
extern int fygue_fat_cluster_get_next(
struct fygue_fat *fat,
int *cluster_current
struct fygue_fat *fat,
int *cluster_current
);
/* fygue_fat_cluster_get_sector() - get sector ID from cluster ID */
extern int fygue_fat_cluster_get_sector(
struct fygue_fat *fat,
int cluster_id,
int *sector_id
struct fygue_fat *fat,
int cluster_id,
int *sector_id
);
/* fygue_fat_get_cluster_addr() - get logical sector addr */
extern int fygue_fat_cluster_get_addr(
struct fygue_fat *fat,
uintptr_t *addr,
int cluster_id
struct fygue_fat *fat,
uintptr_t *addr,
int cluster_id
);
//---
@ -238,9 +238,9 @@ extern int fygue_fat_cluster_get_addr(
/* fygue_fat_get_sector_addr() - get logical sector addr */
extern int fygue_fat_sector_get_addr(
struct fygue_fat *fat,
uintptr_t *addr,
int sector
struct fygue_fat *fat,
uintptr_t *addr,
int sector
);
#endif /* FS_FYGUE_FAT_H */

View file

@ -4,10 +4,10 @@
/* fygue_fat_dir_close(): closedir primitive */
int fygue_fat_dir_close(struct fygue_fat *fat, struct fygue_fat_dir *dir)
{
if (fat == NULL || dir == NULL)
return -1;
// nothing to do here...
memset(dir, 0x00, sizeof(struct fygue_fat_file));
return 0;
if (fat == NULL || dir == NULL)
return -1;
// nothing to do here...
memset(dir, 0x00, sizeof(struct fygue_fat_file));
return 0;
}

View file

@ -3,21 +3,21 @@
/* fugue_fat_dir_open(): convert dirent to dir */
int fygue_fat_dir_open(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent
) {
memset(dir, 0x00, sizeof(struct fygue_fat_dir));
if (dirent == NULL) {
dir->cluster_entry = 0;
dir->root_dirent_count = fat->RootEntCount;
dir->attribute = FYGUE_FAT_DESC_TYPE_DIR;
} else {
if ((dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY) == 0x00)
return -1;
dir->cluster_entry = dirent->cluster_id;
dir->attribute = FYGUE_FAT_DESC_TYPE_DIR;
dir->root_dirent_count = 0;
}
return fygue_fat_dir_sync(fat, dir, dir->cluster_entry);
memset(dir, 0x00, sizeof(struct fygue_fat_dir));
if (dirent == NULL) {
dir->cluster_entry = 0;
dir->root_dirent_count = fat->RootEntCount;
dir->attribute = FYGUE_FAT_DESC_TYPE_DIR;
} else {
if ((dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY) == 0x00)
return -1;
dir->cluster_entry = dirent->cluster_id;
dir->attribute = FYGUE_FAT_DESC_TYPE_DIR;
dir->root_dirent_count = 0;
}
return fygue_fat_dir_sync(fat, dir, dir->cluster_entry);
}

View file

@ -16,56 +16,56 @@
/* _fat_dirent - FAT directory entry structure */
struct _fat_dirent
{
uint8_t DIR_Name[11];
uint8_t DIR_Attr;
uint8_t DIR_NTRes;
uint8_t DIR_CrtTimeTenth;
uint16_t DIR_CrtTime;
uint16_t DIR_CrtDate;
uint16_t DIR_LstAccDate;
uint16_t DIR_FstClusHI;
uint16_t DIR_WrtTime;
uint16_t DIR_WrtDate;
uint16_t DIR_FstClusLO;
uint32_t DIR_FileSize;
uint8_t DIR_Name[11];
uint8_t DIR_Attr;
uint8_t DIR_NTRes;
uint8_t DIR_CrtTimeTenth;
uint16_t DIR_CrtTime;
uint16_t DIR_CrtDate;
uint16_t DIR_LstAccDate;
uint16_t DIR_FstClusHI;
uint16_t DIR_WrtTime;
uint16_t DIR_WrtDate;
uint16_t DIR_FstClusLO;
uint32_t DIR_FileSize;
} GPACKED(1);
/* _fat_dir_name : Fugue directory name strcuture */
struct _fat_dirname
{
struct {
uint8_t :1; // must be 0
uint8_t last :1;
uint8_t :1; // must be 0
uint8_t id :5;
} DIR_Sequence;
uint16_t DIR_Char0;
uint16_t DIR_Char1;
uint16_t DIR_Char2;
uint16_t DIR_Char3;
uint16_t DIR_Char4;
uint8_t DIR_Attr; // must be 0x0f
uint8_t DIR_Type; // must be 0x00
uint8_t checksum;
uint16_t DIR_Char5;
uint16_t DIR_Char6;
uint16_t DIR_Char7;
uint16_t DIR_Char8;
uint16_t DIR_Char9;
uint16_t DIR_Char10;
uint16_t DIR_FstClus; // must be 0x0000
uint16_t DIR_Char11;
uint16_t DIR_Char12;
struct {
uint8_t :1; // must be 0
uint8_t last :1;
uint8_t :1; // must be 0
uint8_t id :5;
} DIR_Sequence;
uint16_t DIR_Char0;
uint16_t DIR_Char1;
uint16_t DIR_Char2;
uint16_t DIR_Char3;
uint16_t DIR_Char4;
uint8_t DIR_Attr; // must be 0x0f
uint8_t DIR_Type; // must be 0x00
uint8_t checksum;
uint16_t DIR_Char5;
uint16_t DIR_Char6;
uint16_t DIR_Char7;
uint16_t DIR_Char8;
uint16_t DIR_Char9;
uint16_t DIR_Char10;
uint16_t DIR_FstClus; // must be 0x0000
uint16_t DIR_Char11;
uint16_t DIR_Char12;
} GPACKED(1);
/* _fat_info - internal struct info */
struct _fat_info
{
struct fygue_fat *fat;
struct fygue_fat_dir *dir;
struct fygue_fat_dirent *current;
uint8_t *filename;
int idx;
struct fygue_fat *fat;
struct fygue_fat_dir *dir;
struct fygue_fat_dirent *current;
uint8_t *filename;
int idx;
};
@ -76,66 +76,66 @@ struct _fat_info
* - special root handling (root= dir->cluster_id == 0)
*
* return
* -1 end of dirent
* 0 success */
* -1 end of dirent
* 0 success */
static int _fygue_fat_readdir_cursor_update(struct _fat_info *finfo)
{
struct fygue_fat_dir *dir;
int rc;
struct fygue_fat_dir *dir;
int rc;
dir = finfo->dir;
if (dir->end_of_dirent == true)
return -1;
dir->end_of_dirent = true;
if (dir->cluster_entry == 0)
{
dir->dirent_cursor += 1;
if (dir->dirent_cursor >= dir->root_dirent_count)
return -1;
if ((dir->dirent_cursor % 16) != 0)
{
dir->dirent_current_addr += sizeof(struct _fat_dirent);
dir->end_of_dirent = false;
return 0;
}
dir->sector_id += 1;
} else {
dir->dirent_cursor += 1;
if ((dir->dirent_cursor % 16) != 0)
{
dir->dirent_current_addr += sizeof(struct _fat_dirent);
dir->end_of_dirent = false;
return 0;
}
dir->dirent_cursor = 0;
dir->sector_count += 1;
if (dir->sector_count >= 8)
{
rc = fygue_fat_cluster_get_next(
finfo->fat,
&dir->cluster_current
);
if (rc != 0)
return -1;
rc = fygue_fat_cluster_get_sector(
finfo->fat,
dir->cluster_current,
&dir->sector_id
);
if (rc != 0)
return -1;
dir->sector_count = 0;
}
}
rc = fygue_fat_sector_get_addr(
finfo->fat,
&dir->dirent_current_addr,
dir->sector_id
);
if (rc != 0)
return -1;
dir->end_of_dirent = false;
return 0;
dir = finfo->dir;
if (dir->end_of_dirent == true)
return -1;
dir->end_of_dirent = true;
if (dir->cluster_entry == 0)
{
dir->dirent_cursor += 1;
if (dir->dirent_cursor >= dir->root_dirent_count)
return -1;
if ((dir->dirent_cursor % 16) != 0)
{
dir->dirent_current_addr += sizeof(struct _fat_dirent);
dir->end_of_dirent = false;
return 0;
}
dir->sector_id += 1;
} else {
dir->dirent_cursor += 1;
if ((dir->dirent_cursor % 16) != 0)
{
dir->dirent_current_addr += sizeof(struct _fat_dirent);
dir->end_of_dirent = false;
return 0;
}
dir->dirent_cursor = 0;
dir->sector_count += 1;
if (dir->sector_count >= 8)
{
rc = fygue_fat_cluster_get_next(
finfo->fat,
&dir->cluster_current
);
if (rc != 0)
return -1;
rc = fygue_fat_cluster_get_sector(
finfo->fat,
dir->cluster_current,
&dir->sector_id
);
if (rc != 0)
return -1;
dir->sector_count = 0;
}
}
rc = fygue_fat_sector_get_addr(
finfo->fat,
&dir->dirent_current_addr,
dir->sector_id
);
if (rc != 0)
return -1;
dir->end_of_dirent = false;
return 0;
}
//---
@ -144,114 +144,114 @@ static int _fygue_fat_readdir_cursor_update(struct _fat_info *finfo)
/* _fygue_fat_readdir_dirent_gen() - generate dirent */
static void _fygue_fat_readdir_dirent_gen(
struct _fat_info *finfo,
struct _fat_dirent *dirent
struct _fat_info *finfo,
struct _fat_dirent *dirent
) {
struct fygue_fat_dirent *current;
int idx;
struct fygue_fat_dirent *current;
int idx;
idx = 0;
current = finfo->current;
while (finfo->idx > 0)
current->name[idx++] = finfo->filename[--finfo->idx];
current->name[idx] = 0x00;
current->attribute = dirent->DIR_Attr;
current->size = FAT_DWORD(dirent->DIR_FileSize);
current->meta_addr = (uintptr_t)dirent;
current->cluster_id = (
(FAT_WORD(dirent->DIR_FstClusHI) << 16) |
(FAT_WORD(dirent->DIR_FstClusLO) << 0)
);
idx = 0;
current = finfo->current;
while (finfo->idx > 0)
current->name[idx++] = finfo->filename[--finfo->idx];
current->name[idx] = 0x00;
current->attribute = dirent->DIR_Attr;
current->size = FAT_DWORD(dirent->DIR_FileSize);
current->meta_addr = (uintptr_t)dirent;
current->cluster_id = (
(FAT_WORD(dirent->DIR_FstClusHI) << 16) |
(FAT_WORD(dirent->DIR_FstClusLO) << 0)
);
}
/* _fygue_fat_readdir_name_shard_update() - update internal name info */
static int _fygue_fat_readdir_name_shard_update(
struct _fat_info *finfo,
uint16_t buffer[13]
struct _fat_info *finfo,
uint16_t buffer[13]
) {
uint8_t b0;
uint8_t b1;
uint8_t b0;
uint8_t b1;
for (int i = 0 ; i < 13 ; i++)
{
if (buffer[i] == 0x0000 || buffer[i] == 0xffff)
continue;
if (buffer[i] >= 0x20 && buffer[i] <= 0x7a) {
finfo->filename[finfo->idx++] = buffer[i] & 0x00ff;
continue;
}
b0 = (buffer[i] & 0x00ff) >> 0;
b1 = (buffer[i] & 0xff00) >> 8;
if (
(b0 >= 0x81 && b0 <= 0x9f) ||
(b0 >= 0xa1 && b0 <= 0xfc)
) {
if (b1 >= 0x40 && b1 <= 0xfc && b1 != 0x7f)
{
finfo->filename[finfo->idx++] = b1;
finfo->filename[finfo->idx++] = b0;
continue;
}
}
return -2;
}
return 0;
for (int i = 0 ; i < 13 ; i++)
{
if (buffer[i] == 0x0000 || buffer[i] == 0xffff)
continue;
if (buffer[i] >= 0x20 && buffer[i] <= 0x7a) {
finfo->filename[finfo->idx++] = buffer[i] & 0x00ff;
continue;
}
b0 = (buffer[i] & 0x00ff) >> 0;
b1 = (buffer[i] & 0xff00) >> 8;
if (
(b0 >= 0x81 && b0 <= 0x9f) ||
(b0 >= 0xa1 && b0 <= 0xfc)
) {
if (b1 >= 0x40 && b1 <= 0xfc && b1 != 0x7f)
{
finfo->filename[finfo->idx++] = b1;
finfo->filename[finfo->idx++] = b0;
continue;
}
}
return -2;
}
return 0;
}
/* _fygue_fat_readdir_name_prepare() - classic FAT handling */
static int _fygue_fat_readdir_name_fat_prepare(
struct _fat_info *finfo,
struct _fat_dirent *dirent
struct _fat_info *finfo,
struct _fat_dirent *dirent
) {
uint16_t buffer[13];
bool need_dot;
int j;
uint16_t buffer[13];
bool need_dot;
int j;
j = 13;
need_dot = false;
for (int i = 0 ; i < 11 ; i++)
{
if (i == 8)
need_dot = true;
if (dirent->DIR_Name[i] == 0x20)
continue;
if (need_dot) {
buffer[--j] = '.';
need_dot = false;
}
if (dirent->DIR_Name[i] >= 'A' && dirent->DIR_Name[i] <= 'Z') {
buffer[--j] = dirent->DIR_Name[i] + 0x20;
} else {
buffer[--j] = dirent->DIR_Name[i];
}
}
while (--j >= 0)
buffer[j] = 0x0000;
finfo->idx = 0;
return _fygue_fat_readdir_name_shard_update(finfo, buffer);
j = 13;
need_dot = false;
for (int i = 0 ; i < 11 ; i++)
{
if (i == 8)
need_dot = true;
if (dirent->DIR_Name[i] == 0x20)
continue;
if (need_dot) {
buffer[--j] = '.';
need_dot = false;
}
if (dirent->DIR_Name[i] >= 'A' && dirent->DIR_Name[i] <= 'Z') {
buffer[--j] = dirent->DIR_Name[i] + 0x20;
} else {
buffer[--j] = dirent->DIR_Name[i];
}
}
while (--j >= 0)
buffer[j] = 0x0000;
finfo->idx = 0;
return _fygue_fat_readdir_name_shard_update(finfo, buffer);
}
/* _fygue_fat_readdir_name_update() - pre-generate filename info */
static int _fygue_fat_readdir_name_vfat_prepare(
struct _fat_info *finfo,
struct _fat_dirname *dirname
struct _fat_info *finfo,
struct _fat_dirname *dirname
) {
uint16_t buffer[13];
uint16_t buffer[13];
buffer[0] = FAT_WORD(dirname->DIR_Char12);
buffer[1] = FAT_WORD(dirname->DIR_Char11);
buffer[2] = FAT_WORD(dirname->DIR_Char10);
buffer[3] = FAT_WORD(dirname->DIR_Char9);
buffer[4] = FAT_WORD(dirname->DIR_Char8);
buffer[5] = FAT_WORD(dirname->DIR_Char7);
buffer[6] = FAT_WORD(dirname->DIR_Char6);
buffer[7] = FAT_WORD(dirname->DIR_Char5);
buffer[8] = FAT_WORD(dirname->DIR_Char4);
buffer[9] = FAT_WORD(dirname->DIR_Char3);
buffer[10] = FAT_WORD(dirname->DIR_Char2);
buffer[11] = FAT_WORD(dirname->DIR_Char1);
buffer[12] = FAT_WORD(dirname->DIR_Char0);
return _fygue_fat_readdir_name_shard_update(finfo, buffer);
buffer[0] = FAT_WORD(dirname->DIR_Char12);
buffer[1] = FAT_WORD(dirname->DIR_Char11);
buffer[2] = FAT_WORD(dirname->DIR_Char10);
buffer[3] = FAT_WORD(dirname->DIR_Char9);
buffer[4] = FAT_WORD(dirname->DIR_Char8);
buffer[5] = FAT_WORD(dirname->DIR_Char7);
buffer[6] = FAT_WORD(dirname->DIR_Char6);
buffer[7] = FAT_WORD(dirname->DIR_Char5);
buffer[8] = FAT_WORD(dirname->DIR_Char4);
buffer[9] = FAT_WORD(dirname->DIR_Char3);
buffer[10] = FAT_WORD(dirname->DIR_Char2);
buffer[11] = FAT_WORD(dirname->DIR_Char1);
buffer[12] = FAT_WORD(dirname->DIR_Char0);
return _fygue_fat_readdir_name_shard_update(finfo, buffer);
}
//---
@ -264,52 +264,52 @@ static int _fygue_fat_readdir_name_vfat_prepare(
* - properly handle broken chain (0x00, 0xe5, ...)
* - properly handle `cursor_update()` error
* returns
* -3 internal error
* -2 invalid VFAT
* -1 invlaid VFAT (start)
* 0 success */
* -3 internal error
* -2 invalid VFAT
* -1 invlaid VFAT (start)
* 0 success */
static int _fygue_readdir_vfat(struct _fat_info *finfo)
{
struct _fat_dirname *dirname;
int count;
struct _fat_dirname *dirname;
int count;
dirname = (void*)finfo->dir->dirent_current_addr;
if (dirname->DIR_Sequence.last == 0) {
finfo->dir->dirty = true;
return -1;
}
finfo->idx = 0;
count = dirname->DIR_Sequence.id;
do {
dirname = (void*)finfo->dir->dirent_current_addr;
if (dirname->DIR_Attr != 0x0f)
return -2;
if (dirname->DIR_Sequence.id != count)
return -2;
if (_fygue_fat_readdir_name_vfat_prepare(finfo, dirname) != 0)
return -2;
if (_fygue_fat_readdir_cursor_update(finfo) != 0)
return -3;
count -= 1;
} while (count >= 1);
_fygue_fat_readdir_dirent_gen(
finfo,
(void*)finfo->dir->dirent_current_addr
);
finfo->dir->dirty = true;
return 0;
dirname = (void*)finfo->dir->dirent_current_addr;
if (dirname->DIR_Sequence.last == 0) {
finfo->dir->dirty = true;
return -1;
}
finfo->idx = 0;
count = dirname->DIR_Sequence.id;
do {
dirname = (void*)finfo->dir->dirent_current_addr;
if (dirname->DIR_Attr != 0x0f)
return -2;
if (dirname->DIR_Sequence.id != count)
return -2;
if (_fygue_fat_readdir_name_vfat_prepare(finfo, dirname) != 0)
return -2;
if (_fygue_fat_readdir_cursor_update(finfo) != 0)
return -3;
count -= 1;
} while (count >= 1);
_fygue_fat_readdir_dirent_gen(
finfo,
(void*)finfo->dir->dirent_current_addr
);
finfo->dir->dirty = true;
return 0;
}
/* _fygue_readdir_fat() - handle FAT dirent generation */
static int _fygue_readdir_fat(struct _fat_info *finfo)
{
struct _fat_dirent *dirent;
struct _fat_dirent *dirent;
dirent = (void*)finfo->dir->dirent_current_addr;
_fygue_fat_readdir_name_fat_prepare(finfo, dirent);
_fygue_fat_readdir_dirent_gen(finfo, dirent);
finfo->dir->dirty = true;
return 0;
dirent = (void*)finfo->dir->dirent_current_addr;
_fygue_fat_readdir_name_fat_prepare(finfo, dirent);
_fygue_fat_readdir_dirent_gen(finfo, dirent);
finfo->dir->dirty = true;
return 0;
}
/* _fygue_readdir_fat_check() - check FAT type
@ -317,54 +317,54 @@ static int _fygue_readdir_fat(struct _fat_info *finfo)
* notes
* check special first character of the FAT entry and try to determine
* if it is:
* 0x00 unused entry and all remaning entry will be unused
* 0xe5 unused entry
* 0x2e special "." or ".." entry
* 0x00 unused entry and all remaning entry will be unused
* 0xe5 unused entry
* 0x2e special "." or ".." entry
* then check the dirent attribute to distinguish an VFAT entry from an
* classic FAT entry
*
* return
* -4 unsupported enty (volume ID)
* -3 this is a end-of-dirent entry (0x00)
* -2 this is an unused entry (0xe5)
* -1 this is a special "." or ".." entry
* 0 this is a classic FAT entry
* 1 this is a VFAT entry */
* -4 unsupported enty (volume ID)
* -3 this is a end-of-dirent entry (0x00)
* -2 this is an unused entry (0xe5)
* -1 this is a special "." or ".." entry
* 0 this is a classic FAT entry
* 1 this is a VFAT entry */
static int _fygue_readdir_fat_check(struct _fat_info *finfo)
{
struct _fat_dirent *dirent;
struct _fat_dirent *dirent;
dirent = (void*)finfo->dir->dirent_current_addr;
switch (dirent->DIR_Name[0])
{
case 0x00:
finfo->dir->end_of_dirent = true;
return -3;
case 0xe5:
finfo->dir->dirty = true;
return -2;
case 0x2e:
if (dirent->DIR_Name[1] == '.') {
finfo->filename[0] = '.';
finfo->filename[1] = '.';
finfo->filename[2] = '\0';
finfo->idx = 2;
} else {
finfo->filename[0] = '.';
finfo->filename[1] = '\0';
finfo->idx = 1;
}
_fygue_fat_readdir_dirent_gen(finfo, dirent);
finfo->dir->dirty = true;
return -1;
}
if (dirent->DIR_Attr == 0x0f)
return 1;
if ((dirent->DIR_Attr & 0x08) != 0) {
finfo->dir->dirty = true;
return -4;
}
return 0;
dirent = (void*)finfo->dir->dirent_current_addr;
switch (dirent->DIR_Name[0])
{
case 0x00:
finfo->dir->end_of_dirent = true;
return -3;
case 0xe5:
finfo->dir->dirty = true;
return -2;
case 0x2e:
if (dirent->DIR_Name[1] == '.') {
finfo->filename[0] = '.';
finfo->filename[1] = '.';
finfo->filename[2] = '\0';
finfo->idx = 2;
} else {
finfo->filename[0] = '.';
finfo->filename[1] = '\0';
finfo->idx = 1;
}
_fygue_fat_readdir_dirent_gen(finfo, dirent);
finfo->dir->dirty = true;
return -1;
}
if (dirent->DIR_Attr == 0x0f)
return 1;
if ((dirent->DIR_Attr & 0x08) != 0) {
finfo->dir->dirty = true;
return -4;
}
return 0;
}
//---
@ -374,46 +374,46 @@ static int _fygue_readdir_fat_check(struct _fat_info *finfo)
/* fygue_fat_dir_read() - readdir-like primitive
*
* return
* -2 internal error
* -1 argument error
* 0 success
* 1 no directory found */
* -2 internal error
* -1 argument error
* 0 success
* 1 no directory found */
int fygue_fat_dir_read(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *current
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *current
) {
struct _fat_info finfo;
int rc;
struct _fat_info finfo;
int rc;
if (fat == NULL || current == NULL || dir == NULL)
return -1;
finfo.fat = fat;
finfo.current = current;
finfo.dir = dir;
finfo.filename = alloca(256 * sizeof(uint8_t));
if (finfo.filename == NULL)
return -2;
while (dir->end_of_dirent == false)
{
if (finfo.dir->dirty)
{
if (_fygue_fat_readdir_cursor_update(&finfo) != 0)
break;
finfo.dir->dirty = false;
}
rc = _fygue_readdir_fat_check(&finfo);
if (rc == -3)
break;
if (rc == -1)
return 0;
if (rc < 0)
continue;
if (rc == 0 && _fygue_readdir_fat(&finfo) == 0)
return 0;
if (rc == 1 && _fygue_readdir_vfat(&finfo) == 0)
return 0;
}
dir->end_of_dirent = true;
return 1;
if (fat == NULL || current == NULL || dir == NULL)
return -1;
finfo.fat = fat;
finfo.current = current;
finfo.dir = dir;
finfo.filename = alloca(256 * sizeof(uint8_t));
if (finfo.filename == NULL)
return -2;
while (dir->end_of_dirent == false)
{
if (finfo.dir->dirty)
{
if (_fygue_fat_readdir_cursor_update(&finfo) != 0)
break;
finfo.dir->dirty = false;
}
rc = _fygue_readdir_fat_check(&finfo);
if (rc == -3)
break;
if (rc == -1)
return 0;
if (rc < 0)
continue;
if (rc == 0 && _fygue_readdir_fat(&finfo) == 0)
return 0;
if (rc == 1 && _fygue_readdir_vfat(&finfo) == 0)
return 0;
}
dir->end_of_dirent = true;
return 1;
}

View file

@ -8,31 +8,31 @@
/* _get_mode(): get "pseudo" file mode */
static mode_t _get_mode(struct fygue_fat_dir *dir)
{
mode_t mode;
mode_t mode;
mode = 0777;
if (dir->attribute & FYGUE_FAT_ATTR_READ_ONLY)
mode = 0444;
if (dir->attribute & FYGUE_FAT_ATTR_DIRECTORY)
return mode | S_IFDIR;
return S_IFREG | 0777;
mode = 0777;
if (dir->attribute & FYGUE_FAT_ATTR_READ_ONLY)
mode = 0444;
if (dir->attribute & FYGUE_FAT_ATTR_DIRECTORY)
return mode | S_IFDIR;
return S_IFREG | 0777;
}
/* _get_block_size(): return one cluster size */
static int _get_block_size(struct fygue_fat *fat)
{
return (fat->SectorSize * fat->SectorPerClus);
return (fat->SectorSize * fat->SectorPerClus);
}
/* _get_block_nb(): count the number of cluster */
static int _get_block_nb(struct fygue_fat *fat, int cluster)
{
int count;
int count;
count = 0;
while (fygue_fat_cluster_get_next(fat, &cluster) == 0)
count += 1;
return count;
count = 0;
while (fygue_fat_cluster_get_next(fat, &cluster) == 0)
count += 1;
return count;
}
//---
@ -41,26 +41,26 @@ static int _get_block_nb(struct fygue_fat *fat, int cluster)
/* fygue_fat_dir_stat(): directory-specific stat primitive */
int fygue_fat_dir_stat(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct stat *statbuf
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct stat *statbuf
) {
if (fat == NULL || dir == NULL || statbuf == NULL) {
errno = EIO;
return -1;
}
statbuf->st_dev = 0; /* not supported */
statbuf->st_ino = dir->cluster_entry;
statbuf->st_mode = _get_mode(dir);
statbuf->st_nlink = 0; /* not supported */
statbuf->st_uid = 0; /* not supported */
statbuf->st_gid = 0; /* not supported */
statbuf->st_rdev = 0; /* not supported */
statbuf->st_size = 0;
statbuf->st_atime = 0; /* not supported */
statbuf->st_mtime = 0; /* not supported */
statbuf->st_ctime = 0; /* not supported */
statbuf->st_blksize = _get_block_size(fat);
statbuf->st_blocks = _get_block_nb(fat, dir->cluster_entry);
return 0;
if (fat == NULL || dir == NULL || statbuf == NULL) {
errno = EIO;
return -1;
}
statbuf->st_dev = 0; /* not supported */
statbuf->st_ino = dir->cluster_entry;
statbuf->st_mode = _get_mode(dir);
statbuf->st_nlink = 0; /* not supported */
statbuf->st_uid = 0; /* not supported */
statbuf->st_gid = 0; /* not supported */
statbuf->st_rdev = 0; /* not supported */
statbuf->st_size = 0;
statbuf->st_atime = 0; /* not supported */
statbuf->st_mtime = 0; /* not supported */
statbuf->st_ctime = 0; /* not supported */
statbuf->st_blksize = _get_block_size(fat);
statbuf->st_blocks = _get_block_nb(fat, dir->cluster_entry);
return 0;
}

View file

@ -2,33 +2,33 @@
/* fygue_fat_dir_sync(): sync directory information */
int fygue_fat_dir_sync(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
int cluster_id
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
int cluster_id
) {
int rc;
int rc;
if (fat == NULL || dir == NULL)
return -1;
dir->dirty = false;
dir->sector_count = 0;
dir->dirent_cursor = 0;
dir->end_of_dirent = false;
dir->cluster_entry = cluster_id;
dir->cluster_current = dir->cluster_entry;
rc = fygue_fat_cluster_get_sector(
fat,
dir->cluster_current,
&dir->sector_id
);
if (rc != 0)
return -2;
rc = fygue_fat_sector_get_addr(
fat,
&dir->dirent_current_addr,
dir->sector_id
);
if (rc != 0)
return -3;
return 0;
if (fat == NULL || dir == NULL)
return -1;
dir->dirty = false;
dir->sector_count = 0;
dir->dirent_cursor = 0;
dir->end_of_dirent = false;
dir->cluster_entry = cluster_id;
dir->cluster_current = dir->cluster_entry;
rc = fygue_fat_cluster_get_sector(
fat,
dir->cluster_current,
&dir->sector_id
);
if (rc != 0)
return -2;
rc = fygue_fat_sector_get_addr(
fat,
&dir->dirent_current_addr,
dir->sector_id
);
if (rc != 0)
return -3;
return 0;
}

View file

@ -5,10 +5,10 @@
/* fygue_fat_file_close(): close primitive */
int fygue_fat_file_close(struct fygue_fat *fat, struct fygue_fat_file *file)
{
if (fat == NULL || file == NULL)
return -1;
if (file->chunk != NULL)
free(file->chunk);
memset(file, 0x00, sizeof(struct fygue_fat_file));
return 0;
if (fat == NULL || file == NULL)
return -1;
if (file->chunk != NULL)
free(file->chunk);
memset(file, 0x00, sizeof(struct fygue_fat_file));
return 0;
}

View file

@ -4,22 +4,22 @@
/* fygue_fat_file_open(): generate file information */
int fygue_fat_file_open(
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct fygue_fat_dirent *dirent
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct fygue_fat_dirent *dirent
) {
memset(file, 0x00, sizeof(struct fygue_fat_file));
file->attribute = dirent->attribute;
file->cluster_entry = dirent->cluster_id;
file->size = dirent->size;
file->chunk = NULL;
file->chunk_count = 0;
file->chunk_table_max_index = 0;
if (fygue_fat_file_sync(fat, file, dirent->cluster_id) != 0)
return -1;
if (fygue_fat_file_seek(fat, file, 0) != 0)
return -2;
return 0;
memset(file, 0x00, sizeof(struct fygue_fat_file));
file->attribute = dirent->attribute;
file->cluster_entry = dirent->cluster_id;
file->size = dirent->size;
file->chunk = NULL;
file->chunk_count = 0;
file->chunk_table_max_index = 0;
if (fygue_fat_file_sync(fat, file, dirent->cluster_id) != 0)
return -1;
if (fygue_fat_file_seek(fat, file, 0) != 0)
return -2;
return 0;
}

View file

@ -2,51 +2,44 @@
#include <string.h>
#include "fat.h"
uintptr_t debug_read_addr = 0;
size_t debug_read_size = 0;
int debug_read_off = 0;
/* fygue_fat_file_read(): read primitive */
int fygue_fat_file_read(
struct fygue_fat *fat,
struct fygue_fat_file *file,
void *buffer,
size_t size
struct fygue_fat *fat,
struct fygue_fat_file *file,
void *buffer,
size_t size
) {
uintptr_t chunk_data_addr;
size_t chunk_data_available;
size_t chunk_data_offset;
size_t read;
uintptr_t chunk_data_addr;
size_t chunk_data_available;
size_t chunk_data_offset;
size_t read;
if (fat == NULL || file == NULL || buffer == NULL)
return -1;
if (file->chunk == NULL)
return -1;
read = 0;
chunk_data_offset = file->chunk_rd_offset;
while (read < size)
{
if (file->chunk_rd_index >= file->chunk_count)
break;
chunk_data_addr = file->chunk[file->chunk_rd_index].addr;
chunk_data_addr += chunk_data_offset;
chunk_data_available = file->chunk[file->chunk_rd_index].size;
chunk_data_available -= chunk_data_offset;
if (read + chunk_data_available > size)
{
debug_read_addr = chunk_data_addr;
debug_read_size = size - read;
debug_read_off = chunk_data_offset;
chunk_data_offset += size - read;
memcpy(buffer, (void*)chunk_data_addr, size - read);
read += size - read;
break;
}
memcpy(buffer, (void*)chunk_data_addr, chunk_data_available);
read += chunk_data_available;
file->chunk_rd_index += 1;
chunk_data_offset = 0;
}
file->chunk_rd_offset = chunk_data_offset;
return read;
if (fat == NULL || file == NULL || buffer == NULL)
return -1;
if (file->chunk == NULL)
return -1;
read = 0;
chunk_data_offset = file->chunk_rd_offset;
while (read < size)
{
if (file->chunk_rd_index >= file->chunk_count)
break;
chunk_data_addr = file->chunk[file->chunk_rd_index].addr;
chunk_data_addr += chunk_data_offset;
chunk_data_available = file->chunk[file->chunk_rd_index].size;
chunk_data_available -= chunk_data_offset;
if (read + chunk_data_available > size)
{
chunk_data_offset += size - read;
memcpy(buffer, (void*)chunk_data_addr, size - read);
read += size - read;
break;
}
memcpy(buffer, (void*)chunk_data_addr, chunk_data_available);
read += chunk_data_available;
file->chunk_rd_index += 1;
chunk_data_offset = 0;
}
file->chunk_rd_offset = chunk_data_offset;
return read;
}

View file

@ -3,29 +3,29 @@
/* fygue_fat_file_seek(): seek primitive */
int fygue_fat_file_seek(
struct fygue_fat *fat,
struct fygue_fat_file *file,
off_t offset
struct fygue_fat *fat,
struct fygue_fat_file *file,
off_t offset
) {
off_t offset_current;
off_t offset_current;
if (fat == NULL || file == NULL)
return -1;
offset_current = 0;
file->chunk_rd_index = 0;
file->chunk_rd_offset = 0;
for (int i = 0; i < file->chunk_count; i++)
{
offset_current += file->chunk[i].size;
if (offset_current > offset) {
file->chunk_rd_offset = (
file->chunk[i].size - (offset_current - offset)
);
file->cursor = offset;
return 0;
}
file->chunk_rd_index += 1;
}
errno = EIO;
return -1;
if (fat == NULL || file == NULL)
return -1;
offset_current = 0;
file->chunk_rd_index = 0;
file->chunk_rd_offset = 0;
for (int i = 0; i < file->chunk_count; i++)
{
offset_current += file->chunk[i].size;
if (offset_current > offset) {
file->chunk_rd_offset = (
file->chunk[i].size - (offset_current - offset)
);
file->cursor = offset;
return 0;
}
file->chunk_rd_index += 1;
}
errno = EIO;
return -1;
}

View file

@ -8,26 +8,26 @@
/* _get_mode(): get "pseudo" file mode */
static mode_t _get_mode(int attribute)
{
if (attribute & FYGUE_FAT_ATTR_READ_ONLY)
return S_IFREG | 0444;
return S_IFREG | 0777;
if (attribute & FYGUE_FAT_ATTR_READ_ONLY)
return S_IFREG | 0444;
return S_IFREG | 0777;
}
/* _get_block_size(): return one cluster size */
static int _get_block_size(struct fygue_fat *fat)
{
return (fat->SectorSize * fat->SectorPerClus);
return (fat->SectorSize * fat->SectorPerClus);
}
/* _get_block_nb(): count the number of cluster */
static int _get_block_nb(struct fygue_fat *fat, int cluster)
{
int count;
int count;
count = 1;
while (fygue_fat_cluster_get_next(fat, &cluster) == 0)
count += 1;
return count;
count = 1;
while (fygue_fat_cluster_get_next(fat, &cluster) == 0)
count += 1;
return count;
}
//---
@ -36,26 +36,26 @@ static int _get_block_nb(struct fygue_fat *fat, int cluster)
/* fygue_fat_file_stat(): directory-specific stat primitive */
int fygue_fat_file_stat(
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct stat *statbuf
struct fygue_fat *fat,
struct fygue_fat_file *file,
struct stat *statbuf
) {
if (fat == NULL || file == NULL || statbuf == NULL) {
errno = EIO;
return -1;
}
statbuf->st_dev = 0; /* not supported */
statbuf->st_ino = file->cluster_entry;
statbuf->st_mode = _get_mode(file->attribute);
statbuf->st_nlink = 0; /* not supported */
statbuf->st_uid = 0; /* not supported */
statbuf->st_gid = 0; /* not supported */
statbuf->st_rdev = 0; /* not supported */
statbuf->st_size = file->size;
statbuf->st_atime = 0; /* not supported */
statbuf->st_mtime = 0; /* not supported */
statbuf->st_ctime = 0; /* not supported */
statbuf->st_blksize = _get_block_size(fat);
statbuf->st_blocks = _get_block_nb(fat, file->cluster_entry);
return 0;
if (fat == NULL || file == NULL || statbuf == NULL) {
errno = EIO;
return -1;
}
statbuf->st_dev = 0; /* not supported */
statbuf->st_ino = file->cluster_entry;
statbuf->st_mode = _get_mode(file->attribute);
statbuf->st_nlink = 0; /* not supported */
statbuf->st_uid = 0; /* not supported */
statbuf->st_gid = 0; /* not supported */
statbuf->st_rdev = 0; /* not supported */
statbuf->st_size = file->size;
statbuf->st_atime = 0; /* not supported */
statbuf->st_mtime = 0; /* not supported */
statbuf->st_ctime = 0; /* not supported */
statbuf->st_blksize = _get_block_size(fat);
statbuf->st_blocks = _get_block_nb(fat, file->cluster_entry);
return 0;
}

View file

@ -7,50 +7,50 @@
/* _fygue_chunk_table_update(): update chunk table */
static int _fygue_chunk_table_update(
struct fygue_fat_file *file,
uintptr_t cluster_addr
struct fygue_fat_file *file,
uintptr_t cluster_addr
) {
uintptr_t cluster_addr_prev;
void *tmp;
uintptr_t cluster_addr_prev;
void *tmp;
if (file->chunk_count > 0)
{
cluster_addr_prev = file->chunk[file->chunk_count - 1].addr;
cluster_addr_prev += file->chunk[file->chunk_count - 1].size;
if (cluster_addr == cluster_addr_prev)
{
file->chunk[file->chunk_count - 1].size += 8*512;
file->chunk[file->chunk_count - 1].cluster_count += 1;
return 0;
}
}
if (file->chunk_count >= file->chunk_table_max_index)
{
tmp = reallocarray(
file->chunk,
file->chunk_table_max_index + 1,
sizeof(*file->chunk)
);
if (tmp == NULL)
return -1;
file->chunk = tmp;
file->chunk_table_max_index += 1;
}
file->chunk[file->chunk_count].size = 8*512;
file->chunk[file->chunk_count].addr = cluster_addr;
file->chunk[file->chunk_count].cluster_count = 1;
file->chunk_count += 1;
return 0;
if (file->chunk_count > 0)
{
cluster_addr_prev = file->chunk[file->chunk_count - 1].addr;
cluster_addr_prev += file->chunk[file->chunk_count - 1].size;
if (cluster_addr == cluster_addr_prev)
{
file->chunk[file->chunk_count - 1].size += 8*512;
file->chunk[file->chunk_count - 1].cluster_count += 1;
return 0;
}
}
if (file->chunk_count >= file->chunk_table_max_index)
{
tmp = reallocarray(
file->chunk,
file->chunk_table_max_index + 1,
sizeof(*file->chunk)
);
if (tmp == NULL)
return -1;
file->chunk = tmp;
file->chunk_table_max_index += 1;
}
file->chunk[file->chunk_count].size = 8*512;
file->chunk[file->chunk_count].addr = cluster_addr;
file->chunk[file->chunk_count].cluster_count = 1;
file->chunk_count += 1;
return 0;
}
/* _fygue_chunk_error(): invalidate the chunk table */
static int _fygue_chunk_error(struct fygue_fat_file *file)
{
if (file->chunk == NULL)
free(file->chunk);
file->chunk_table_max_index = 0;
file->chunk_count = 0;
return -1;
if (file->chunk == NULL)
free(file->chunk);
file->chunk_table_max_index = 0;
file->chunk_count = 0;
return -1;
}
//---
@ -59,26 +59,26 @@ static int _fygue_chunk_error(struct fygue_fat_file *file)
/* fygue_fat_file_sync(): sync internal information */
int fygue_fat_file_sync(
struct fygue_fat *fat,
struct fygue_fat_file *file,
int cluster_id
struct fygue_fat *fat,
struct fygue_fat_file *file,
int cluster_id
) {
uintptr_t cluster_addr;
uintptr_t cluster_addr;
if (fat == NULL || file == NULL)
return -1;
file->chunk_count = 0;
file->cluster_entry = cluster_id;
while (true)
{
if (fygue_fat_cluster_get_addr(fat, &cluster_addr, cluster_id) != 0)
return _fygue_chunk_error(file);
if (_fygue_chunk_table_update(file, cluster_addr) != 0)
return _fygue_chunk_error(file);
if (fygue_fat_cluster_get_next(fat, &cluster_id) != 0)
break;
}
if (fygue_fat_file_seek(fat, file, file->cursor) != 0)
return -3;
return 0;
if (fat == NULL || file == NULL)
return -1;
file->chunk_count = 0;
file->cluster_entry = cluster_id;
while (true)
{
if (fygue_fat_cluster_get_addr(fat, &cluster_addr, cluster_id) != 0)
return _fygue_chunk_error(file);
if (_fygue_chunk_table_update(file, cluster_addr) != 0)
return _fygue_chunk_error(file);
if (fygue_fat_cluster_get_next(fat, &cluster_id) != 0)
break;
}
if (fygue_fat_file_seek(fat, file, file->cursor) != 0)
return -3;
return 0;
}

View file

@ -13,55 +13,55 @@
* - assume that size is not NULL
* - assume that prefix can start with '/' */
static int _fygue_path_get_name(
char const **prefix,
char const **filename,
size_t *len
char const **prefix,
char const **filename,
size_t *len
) {
while ((*prefix)[0] == '/') {
*prefix = &((*prefix)[1]);
}
if ((*prefix)[0] == '\0')
return -1;
*len = 0;
*filename = *prefix;
while ((*prefix)[0] != '\0' && (*prefix)[0] != '/') {
*len += 1;
*prefix = &((*prefix)[1]);
}
return 0;
while ((*prefix)[0] == '/') {
*prefix = &((*prefix)[1]);
}
if ((*prefix)[0] == '\0')
return -1;
*len = 0;
*filename = *prefix;
while ((*prefix)[0] != '\0' && (*prefix)[0] != '/') {
*len += 1;
*prefix = &((*prefix)[1]);
}
return 0;
}
/* _fygue_opendir_find() - try to find the directory entry */
static int _fygue_dirent_find(
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent,
char const *start,
size_t len
struct fygue_fat *fat,
struct fygue_fat_dir *dir,
struct fygue_fat_dirent *dirent,
char const *start,
size_t len
) {
while (true)
{
if (fygue_fat_dir_read(fat, dir, dirent) != 0)
return -1;
if (strncmp(dirent->name, start, len) != 0)
continue;
return 0;
}
while (true)
{
if (fygue_fat_dir_read(fat, dir, dirent) != 0)
return -1;
if (strncmp(dirent->name, start, len) != 0)
continue;
return 0;
}
}
/* _fygue_resolve_set(): setup the resolve response */
static int _fygue_resolve_set(
struct fygue_fat *fat,
struct fygue_fat_descriptor *desc,
struct fygue_fat_dirent *dirent
struct fygue_fat *fat,
struct fygue_fat_descriptor *desc,
struct fygue_fat_dirent *dirent
) {
if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) {
desc->type = FYGUE_FAT_DESC_TYPE_DIR;
return fygue_fat_dir_open(fat, &(desc->dir), dirent);
} else {
desc->type = FYGUE_FAT_DESC_TYPE_FILE;
return fygue_fat_file_open(fat, &(desc->file), dirent);
}
if (dirent == NULL || (dirent->attribute & FYGUE_FAT_ATTR_DIRECTORY)) {
desc->type = FYGUE_FAT_DESC_TYPE_DIR;
return fygue_fat_dir_open(fat, &(desc->dir), dirent);
} else {
desc->type = FYGUE_FAT_DESC_TYPE_FILE;
return fygue_fat_file_open(fat, &(desc->file), dirent);
}
}
//---
@ -73,39 +73,39 @@ static int _fygue_resolve_set(
* notes
* - assume that the path is clean */
int fygue_fat_open(
struct fygue_fat *fat,
char const * const path,
struct fygue_fat_descriptor *desc
struct fygue_fat *fat,
char const * const path,
struct fygue_fat_descriptor *desc
) {
struct fygue_fat_dirent dirent;
struct fygue_fat_dir dir;
char const *prefix;
char const *start;
size_t len;
bool is_root;
struct fygue_fat_dirent dirent;
struct fygue_fat_dir dir;
char const *prefix;
char const *start;
size_t len;
bool is_root;
if (fat == NULL || path == NULL || desc == NULL)
return -1;
prefix = path;
is_root = true;
while (true)
{
if (is_root) {
if (fygue_fat_dir_open(fat, &dir, NULL) != 0)
return -3;
if (_fygue_path_get_name(&prefix, &start, &len) != 0)
break;
is_root = false;
continue;
}
if (_fygue_dirent_find(fat, &dir, &dirent, start, len) != 0)
return -4;
if (_fygue_path_get_name(&prefix, &start, &len) != 0)
break;
if (fygue_fat_dir_open(fat, &dir, &dirent) != 0)
return -5;
}
if (is_root)
return _fygue_resolve_set(fat, desc, NULL);
return _fygue_resolve_set(fat, desc, &dirent);
if (fat == NULL || path == NULL || desc == NULL)
return -1;
prefix = path;
is_root = true;
while (true)
{
if (is_root) {
if (fygue_fat_dir_open(fat, &dir, NULL) != 0)
return -3;
if (_fygue_path_get_name(&prefix, &start, &len) != 0)
break;
is_root = false;
continue;
}
if (_fygue_dirent_find(fat, &dir, &dirent, start, len) != 0)
return -4;
if (_fygue_path_get_name(&prefix, &start, &len) != 0)
break;
if (fygue_fat_dir_open(fat, &dir, &dirent) != 0)
return -5;
}
if (is_root)
return _fygue_resolve_set(fat, desc, NULL);
return _fygue_resolve_set(fat, desc, &dirent);
}

View file

@ -16,13 +16,13 @@
/* _bfile_cluster_metadata - special cluster metadata information */
struct _bfile_cluster_metadata
{
uint8_t bitmask[2];
uint32_t fcluster_version;
uint16_t lcluster_id;
uint16_t fcluster_crc;
uint8_t constant[24];
uint8_t signature[3];
uint8_t ecc_bitmask_position[3];
uint8_t bitmask[2];
uint32_t fcluster_version;
uint16_t lcluster_id;
uint16_t fcluster_crc;
uint8_t constant[24];
uint8_t signature[3];
uint8_t ecc_bitmask_position[3];
} GPACKED(1);
/* _fygue_flash_cluster_convert - ensure that the provided meta is valid
@ -31,9 +31,9 @@ struct _bfile_cluster_metadata
* - assume that fcluster is not NULL
* - try using P1 information first then, P2 if this greedy-read fail
* - to ensure that the provided bfile metadata is valid we will perform
* some test (also performed by Casio). First, ensure that the
* fcluster "kind" is valid (only 0x88, 0x22 or 0x11 are known and
* used) and then ensure that the "constant" part is also valid
* some test (also performed by Casio). First, ensure that the
* fcluster "kind" is valid (only 0x88, 0x22 or 0x11 are known and
* used) and then ensure that the "constant" part is also valid
*
* todo : ensure checksum
* todo : ensure ecc handling (?)
@ -42,73 +42,73 @@ struct _bfile_cluster_metadata
* return
* -1 if the provided `fcluster` is not NULL
* -1 if the bfile metadata cannot be validated
* 0 otherwise */
* 0 otherwise */
static int _fygue_flash_cluster_convert(
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
uintptr_t meta
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
uintptr_t meta
) {
#if 0
static const uint8_t _constant1[] = {
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
};
static const uint8_t _constant2[] = {
0x11, 0x11, 0x11, 0x22,
0x22, 0x22, 0x44, 0x44,
0x44, 0x88, 0x88, 0x88,
0x77, 0x77, 0x77, 0xbb,
0xbb, 0xbb, 0xdd, 0xdd,
0xdd, 0xee, 0xee, 0xee,
};
static const uint8_t _constant1[] = {
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff,
};
static const uint8_t _constant2[] = {
0x11, 0x11, 0x11, 0x22,
0x22, 0x22, 0x44, 0x44,
0x44, 0x88, 0x88, 0x88,
0x77, 0x77, 0x77, 0xbb,
0xbb, 0xbb, 0xdd, 0xdd,
0xdd, 0xee, 0xee, 0xee,
};
#endif
struct _bfile_cluster_metadata *bfile_meta;
struct _bfile_cluster_metadata *bfile_meta;
if (flash == NULL || fcluster == NULL)
return -1;
bfile_meta = (void*)(meta | 0xa0000000);
if (
bfile_meta->signature[0] != 0x5a ||
bfile_meta->signature[1] != 0x5a ||
bfile_meta->signature[2] != 0x5a
) {
return -2;
}
if (
bfile_meta->bitmask[0] != 0x88 &&
bfile_meta->bitmask[0] != 0x22 &&
bfile_meta->bitmask[0] != 0x11
) {
return -3;
}
if (bfile_meta->bitmask[1] != 0x0f)
return -4;
if (
bfile_meta->bitmask[0] != 0x11 &&
bfile_meta->lcluster_id != 0xffff
) {
return -5;
}
// on the fxcp400, have only some flash sector with the constants used
// in other device. Internally, on the fxcp400, Casio only perform
// a check an CRC that is performed on the whole cluster
// TODO: CRC check
if (flash == NULL || fcluster == NULL)
return -1;
bfile_meta = (void*)(meta | 0xa0000000);
if (
bfile_meta->signature[0] != 0x5a ||
bfile_meta->signature[1] != 0x5a ||
bfile_meta->signature[2] != 0x5a
) {
return -2;
}
if (
bfile_meta->bitmask[0] != 0x88 &&
bfile_meta->bitmask[0] != 0x22 &&
bfile_meta->bitmask[0] != 0x11
) {
return -3;
}
if (bfile_meta->bitmask[1] != 0x0f)
return -4;
if (
bfile_meta->bitmask[0] != 0x11 &&
bfile_meta->lcluster_id != 0xffff
) {
return -5;
}
// on the fxcp400, have only some flash sector with the constants used
// in other device. Internally, on the fxcp400, Casio only perform
// a check an CRC that is performed on the whole cluster
// TODO: CRC check
#if 0
if (
memcmp(&(bfile_meta->constant), _constant1, 0x18) != 0 &&
memcmp(&(bfile_meta->constant), _constant2, 0x18) != 0
) {
return -6;
}
if (
memcmp(&(bfile_meta->constant), _constant1, 0x18) != 0 &&
memcmp(&(bfile_meta->constant), _constant2, 0x18) != 0
) {
return -6;
}
#endif
fcluster->lcluster_id = bfile_meta->lcluster_id;
fcluster->kind = bfile_meta->bitmask[0];
fcluster->version = bfile_meta->fcluster_version;
return 0;
fcluster->lcluster_id = bfile_meta->lcluster_id;
fcluster->kind = bfile_meta->bitmask[0];
fcluster->version = bfile_meta->fcluster_version;
return 0;
}
/* _fygue_flash_cluster_meta(): special metadata cluster handling
@ -118,25 +118,25 @@ static int _fygue_flash_cluster_convert(
* not have Bfile information. Generate a fake flash cluster with a
* special custom kind to allow quick identification */
static int _fygue_flash_cluster_meta(
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fsector_id
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fsector_id
) {
GAUTOTYPE geometry = &(flash->geometry);
GAUTOTYPE geometry = &(flash->geometry);
memset(fcluster, 0x00, sizeof(struct fygue_flash_cluster));
fcluster->kind = FYGUE_FCLUSTER_KIND_METADATA;
fcluster->lcluster_id = 0xffff;
fcluster->fcluster_id = 0xffff;
fcluster->fcluster_id_bfile = 0xffff;
fcluster->version = 0xffffffff;
fcluster->meta_addr = 0xffffffff;
fcluster->data_addr = (
(geometry->phy_start | 0xa0000000) +
((fsector_id + 1) * geometry->fsector_size) -
(8 * 512)
);
return 0;
memset(fcluster, 0x00, sizeof(struct fygue_flash_cluster));
fcluster->kind = FYGUE_FCLUSTER_KIND_METADATA;
fcluster->lcluster_id = 0xffff;
fcluster->fcluster_id = 0xffff;
fcluster->fcluster_id_bfile = 0xffff;
fcluster->version = 0xffffffff;
fcluster->meta_addr = 0xffffffff;
fcluster->data_addr = (
(geometry->phy_start | 0xa0000000) +
((fsector_id + 1) * geometry->fsector_size) -
(8 * 512)
);
return 0;
}
/* _fygue_flash_cluster_details(): special flash sector details handling
@ -153,46 +153,46 @@ static int _fygue_flash_cluster_meta(
* one type.
*
* for 64k cluster the 0xf3c0 offset can be calculated as:
* 0x10000 - (8*512) = 0xf000 | sector size minus cluster size
* 15 * 0x40 = 0x3c0 | skip all data cluster meta info */
* 0x10000 - (8*512) = 0xf000 | sector size minus cluster size
* 15 * 0x40 = 0x3c0 | skip all data cluster meta info */
static int _fygue_flash_cluster_details(
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fsector_id
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fsector_id
) {
GAUTOTYPE geometry = &(flash->geometry);
volatile uint32_t *data32;
uintptr_t meta;
uintptr_t data;
GAUTOTYPE geometry = &(flash->geometry);
volatile uint32_t *data32;
uintptr_t meta;
uintptr_t data;
memset(fcluster, 0x00, sizeof(struct fygue_flash_cluster));
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
data = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x10000) +
(0xf3c0)
);
meta = data + 512;
} else {
data = (geometry->phy_start | 0xa0000000) + (fsector_id * 0x20000);
meta = data + 0x1f000;
}
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
return -1;
if (fcluster->version != 0xffffffff)
return -2;
data32 = (void*)data;
if (
((data32[0] ^ data32[1]) != 0xffffffff) ||
((data32[2] ^ data32[3]) != 0xffffffff) ||
((data32[4] ^ data32[5]) != 0xffffffff)
) {
return -1;
}
fcluster->data_addr = data;
fcluster->meta_addr = meta;
fcluster->version = data32[0];
return 0;
memset(fcluster, 0x00, sizeof(struct fygue_flash_cluster));
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
data = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x10000) +
(0xf3c0)
);
meta = data + 512;
} else {
data = (geometry->phy_start | 0xa0000000) + (fsector_id * 0x20000);
meta = data + 0x1f000;
}
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
return -1;
if (fcluster->version != 0xffffffff)
return -2;
data32 = (void*)data;
if (
((data32[0] ^ data32[1]) != 0xffffffff) ||
((data32[2] ^ data32[3]) != 0xffffffff) ||
((data32[4] ^ data32[5]) != 0xffffffff)
) {
return -1;
}
fcluster->data_addr = data;
fcluster->meta_addr = meta;
fcluster->version = data32[0];
return 0;
}
/* _fygue_flash_cluster_data(): handle generic data flash cluster
@ -201,51 +201,51 @@ static int _fygue_flash_cluster_details(
* flash cluster data (0x11 or 0x88) are handled in the same way between
* all device */
static int _fygue_flash_cluster_data(
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fcluster_id,
int fsector_id,
int fcluster_off
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fcluster_id,
int fsector_id,
int fcluster_off
) {
GAUTOTYPE geometry = &(flash->geometry);
uintptr_t meta;
uintptr_t data;
GAUTOTYPE geometry = &(flash->geometry);
uintptr_t meta;
uintptr_t data;
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
data = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x10000) +
(fcluster_off * (8 * 512))
);
meta = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x10000) +
(0xf000) +
(fcluster_off * 0x40)
);
} else {
data = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x20000) +
(fcluster_off * (8 * 512))
);
meta = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x20000) +
(0x1f000) +
(fcluster_off * 0x40)
);
}
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
return -1;
fcluster->data_addr = data;
fcluster->meta_addr = meta;
fcluster->fcluster_id = fcluster_id;
fcluster->fcluster_id_bfile = (
(fsector_id * (geometry->fcluster_per_fsector - 1)) +
(fcluster_off)
);
return 0;
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
data = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x10000) +
(fcluster_off * (8 * 512))
);
meta = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x10000) +
(0xf000) +
(fcluster_off * 0x40)
);
} else {
data = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x20000) +
(fcluster_off * (8 * 512))
);
meta = (
(geometry->phy_start | 0xa0000000) +
(fsector_id * 0x20000) +
(0x1f000) +
(fcluster_off * 0x40)
);
}
if (_fygue_flash_cluster_convert(flash, fcluster, meta) != 0)
return -1;
fcluster->data_addr = data;
fcluster->meta_addr = meta;
fcluster->fcluster_id = fcluster_id;
fcluster->fcluster_id_bfile = (
(fsector_id * (geometry->fcluster_per_fsector - 1)) +
(fcluster_off)
);
return 0;
}
//---
@ -257,43 +257,43 @@ static int _fygue_flash_cluster_data(
* return
* -1 if the provided `fline` is not valid
* -2 if the provided `fline` have invalid Bfile metadata
* 0 if the meta information has been generated */
* 0 if the meta information has been generated */
int fygue_flash_cluster_get(
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fcluster_id
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fcluster_id
) {
GAUTOTYPE geometry = &(flash->geometry);
int fsector_id;
int fcluster_off;
int nb_entry;
GAUTOTYPE geometry = &(flash->geometry);
int fsector_id;
int fcluster_off;
int nb_entry;
if (flash == NULL || fcluster == NULL)
return -1;
if (fcluster_id >= flash->geometry.fcluster_count)
return -1;
if (flash == NULL || fcluster == NULL)
return -1;
if (fcluster_id >= flash->geometry.fcluster_count)
return -1;
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
nb_entry = 16;
fsector_id = fcluster_id / 16;
fcluster_off = fcluster_id % 16;
} else {
nb_entry = 32;
fsector_id = fcluster_id / 32;
fcluster_off = fcluster_id % 32;
}
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_64K) {
nb_entry = 16;
fsector_id = fcluster_id / 16;
fcluster_off = fcluster_id % 16;
} else {
nb_entry = 32;
fsector_id = fcluster_id / 32;
fcluster_off = fcluster_id % 32;
}
if (fcluster_off == 0)
return _fygue_flash_cluster_details(flash, fcluster, fsector_id);
if (fcluster_off == (nb_entry - 1))
return _fygue_flash_cluster_meta(flash, fcluster, fsector_id);
return _fygue_flash_cluster_data(
flash,
fcluster,
fcluster_id,
fsector_id,
fcluster_off
);
if (fcluster_off == 0)
return _fygue_flash_cluster_details(flash, fcluster, fsector_id);
if (fcluster_off == (nb_entry - 1))
return _fygue_flash_cluster_meta(flash, fcluster, fsector_id);
return _fygue_flash_cluster_data(
flash,
fcluster,
fcluster_id,
fsector_id,
fcluster_off
);
}
/* fygue_flash_cluster_geometry() - get geometry information
@ -304,28 +304,28 @@ int fygue_flash_cluster_get(
* that ignore the last entry which contain meta information
*
* returns
* -1 if the provided address is not valid
* 0 success */
* -1 if the provided address is not valid
* 0 success */
int fygue_flash_cluster_geometry(
struct fygue_flash *flash,
uintptr_t addr,
uint16_t *fcluster_id,
uint16_t *fsector_id,
uint16_t *fcluster_off
struct fygue_flash *flash,
uintptr_t addr,
uint16_t *fcluster_id,
uint16_t *fsector_id,
uint16_t *fcluster_off
) {
int nb_cluster;
int nb_cluster;
if ((addr & 0x0fffffff) < flash->geometry.phy_start)
return -1;
nb_cluster = flash->geometry.fcluster_per_fsector;
addr = (addr & 0x0fffffff) - flash->geometry.phy_start;
if (fcluster_id != NULL) {
*fcluster_id = ((addr & 0xfffe0000) >> 17) * nb_cluster;
*fcluster_id += ((addr & 0x0001ffff) >> 12);
}
if (fsector_id != NULL)
*fsector_id = ((addr & 0xfffe0000) >> 17) * nb_cluster;
if (fcluster_off != NULL)
*fcluster_off = ((addr & 0x0001ffff) >> 12);
return 0;
if ((addr & 0x0fffffff) < flash->geometry.phy_start)
return -1;
nb_cluster = flash->geometry.fcluster_per_fsector;
addr = (addr & 0x0fffffff) - flash->geometry.phy_start;
if (fcluster_id != NULL) {
*fcluster_id = ((addr & 0xfffe0000) >> 17) * nb_cluster;
*fcluster_id += ((addr & 0x0001ffff) >> 12);
}
if (fsector_id != NULL)
*fsector_id = ((addr & 0xfffe0000) >> 17) * nb_cluster;
if (fcluster_off != NULL)
*fcluster_off = ((addr & 0x0001ffff) >> 12);
return 0;
}

View file

@ -1,5 +1,5 @@
/*
** fygue/flash/cmap - flash cluster map
** fygue/flash/cmap - flash cluster map
*/
#include <stdlib.h>
#include <string.h>
@ -25,89 +25,89 @@
*
* return
* -1 if the provided information is not valid
* 0 if the provided lcluster exists and has not been updated
* 1 if the provided lcluster has been created
* 2 if the provided lcluster exists and has been updated */
* 0 if the provided lcluster exists and has not been updated
* 1 if the provided lcluster has been created
* 2 if the provided lcluster exists and has been updated */
static int fygue_flash_cmap_update(
struct fygue_flash_cmap *cmap,
struct fygue_flash_cluster *fcluster
struct fygue_flash_cmap *cmap,
struct fygue_flash_cluster *fcluster
) {
struct fygue_flash_cmap_entry *entry;
int i;
struct fygue_flash_cmap_entry *entry;
int i;
if (cmap == NULL || fcluster == NULL)
return -1;
if (fcluster->kind != 0x11)
return -1;
if (cmap->lcluster_id_max > fcluster->lcluster_id)
{
if (
cmap->lcluster[fcluster->lcluster_id].version != 0xffffffff &&
cmap->lcluster[fcluster->lcluster_id].version
< fcluster->version
) {
return 1;
}
} else {
cmap->lcluster = reallocarray(
cmap->lcluster,
(fcluster->lcluster_id + 1),
sizeof(struct fygue_flash_cmap_entry)
);
for (
i = cmap->lcluster_id_max ;
i < fcluster->lcluster_id ;
i++
) {
cmap->lcluster[i].fcluster_id = 0xffff;
cmap->lcluster[i].fcluster_id_bfile = 0xffff;
cmap->lcluster[i].fcluster_addr = 0xffffffff;
cmap->lcluster[i].version = 0xffffffff;
}
cmap->lcluster_id_max = fcluster->lcluster_id + 1;
}
entry = &(cmap->lcluster[fcluster->lcluster_id]);
entry->fcluster_id = fcluster->fcluster_id;
entry->fcluster_id_bfile = fcluster->fcluster_id_bfile;
entry->fcluster_addr = fcluster->data_addr;
entry->version = fcluster->version;
return 0;
if (cmap == NULL || fcluster == NULL)
return -1;
if (fcluster->kind != 0x11)
return -1;
if (cmap->lcluster_id_max > fcluster->lcluster_id)
{
if (
cmap->lcluster[fcluster->lcluster_id].version != 0xffffffff &&
cmap->lcluster[fcluster->lcluster_id].version
< fcluster->version
) {
return 1;
}
} else {
cmap->lcluster = reallocarray(
cmap->lcluster,
(fcluster->lcluster_id + 1),
sizeof(struct fygue_flash_cmap_entry)
);
for (
i = cmap->lcluster_id_max ;
i < fcluster->lcluster_id ;
i++
) {
cmap->lcluster[i].fcluster_id = 0xffff;
cmap->lcluster[i].fcluster_id_bfile = 0xffff;
cmap->lcluster[i].fcluster_addr = 0xffffffff;
cmap->lcluster[i].version = 0xffffffff;
}
cmap->lcluster_id_max = fcluster->lcluster_id + 1;
}
entry = &(cmap->lcluster[fcluster->lcluster_id]);
entry->fcluster_id = fcluster->fcluster_id;
entry->fcluster_id_bfile = fcluster->fcluster_id_bfile;
entry->fcluster_addr = fcluster->data_addr;
entry->version = fcluster->version;
return 0;
}
/* _fygue_flash_cmap_discover(): discover flash information */
static int _fygue_flash_cmap_discover(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
) {
struct fygue_flash_cluster fcluster;
int fsector_id;
int fsector;
int rc;
int j;
struct fygue_flash_cluster fcluster;
int fsector_id;
int fsector;
int rc;
int j;
fsector_id = 0;
for (
fsector = 0 ;
fsector < flash->geometry.fsector_count ;
fsector++
) {
if (fsector != 0)
fsector_id += flash->geometry.fcluster_per_fsector;
if (fygue_flash_cluster_get(flash, &fcluster, fsector_id) != 0)
continue;
if (fcluster.kind != 0x22)
continue;
for (j = 1 ; j < (flash->geometry.fcluster_per_fsector - 1) ; j++)
{
rc = fygue_flash_cluster_get(flash, &fcluster, fsector_id + j);
if (rc != 0)
continue;
if (fcluster.kind != 0x11)
continue;
fygue_flash_cmap_update(cmap, &fcluster);
}
}
return 0;
fsector_id = 0;
for (
fsector = 0 ;
fsector < flash->geometry.fsector_count ;
fsector++
) {
if (fsector != 0)
fsector_id += flash->geometry.fcluster_per_fsector;
if (fygue_flash_cluster_get(flash, &fcluster, fsector_id) != 0)
continue;
if (fcluster.kind != 0x22)
continue;
for (j = 1 ; j < (flash->geometry.fcluster_per_fsector - 1) ; j++)
{
rc = fygue_flash_cluster_get(flash, &fcluster, fsector_id + j);
if (rc != 0)
continue;
if (fcluster.kind != 0x11)
continue;
fygue_flash_cmap_update(cmap, &fcluster);
}
}
return 0;
}
//---
@ -116,29 +116,29 @@ static int _fygue_flash_cmap_discover(
/* fygue_flash_cmap_lsector_get_addr() - get logical sector address */
int fygue_flash_cmap_lsector_get_addr(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap,
uintptr_t *sector,
uint16_t lsector_id
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap,
uintptr_t *sector,
uint16_t lsector_id
) {
uintptr_t fsector_addr;
uint16_t lcluster_id;
uintptr_t fsector_addr;
uint16_t lcluster_id;
if (flash == NULL || sector == NULL || cmap == NULL)
return -1;
if (cmap->lcluster == NULL)
return -1;
lcluster_id = lsector_id / 8;
if (
cmap->lcluster_id_max < lcluster_id ||
cmap->lcluster[lcluster_id].fcluster_id == 0xffff
) {
return -2;
}
fsector_addr = cmap->lcluster[lcluster_id].fcluster_addr;
fsector_addr += (lsector_id % 8) * 512;
*sector = fsector_addr;
return 0;
if (flash == NULL || sector == NULL || cmap == NULL)
return -1;
if (cmap->lcluster == NULL)
return -1;
lcluster_id = lsector_id / 8;
if (
cmap->lcluster_id_max < lcluster_id ||
cmap->lcluster[lcluster_id].fcluster_id == 0xffff
) {
return -2;
}
fsector_addr = cmap->lcluster[lcluster_id].fcluster_addr;
fsector_addr += (lsector_id % 8) * 512;
*sector = fsector_addr;
return 0;
}
/* fygue_flash_cmap_init() - initialize fcluster translation
@ -149,41 +149,41 @@ int fygue_flash_cmap_lsector_get_addr(
* (read,write,erase). This because the Flash used in recent devices use
* sector of 128ko which imply, when you want to update one byte of
* memory, you need to:
* - copy the whole page in RAM
* - perform the modification
* - write the new page information
* - copy the whole page in RAM
* - perform the modification
* - write the new page information
*
* So, todo
*
* returns:
* -1 if the sector 0 is not found
* 0 success */
* 0 success */
int fygue_flash_cmap_initialize(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
) {
if (flash == NULL || cmap == NULL)
return -1;
memset(cmap, 0x00, sizeof(struct fygue_flash_cmap));
if (_fygue_flash_cmap_discover(flash, cmap) != 0)
return -1;
if (cmap->lcluster == NULL)
return -2;
if (cmap->lcluster[0].fcluster_id == 0xffff)
return -3;
return 0;
if (flash == NULL || cmap == NULL)
return -1;
memset(cmap, 0x00, sizeof(struct fygue_flash_cmap));
if (_fygue_flash_cmap_discover(flash, cmap) != 0)
return -1;
if (cmap->lcluster == NULL)
return -2;
if (cmap->lcluster[0].fcluster_id == 0xffff)
return -3;
return 0;
}
/* fygue_flash_cmap_sync() - sync the fcluster redirection map */
int fygue_flash_cmap_sync(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
) {
if (flash == NULL || cmap == NULL)
return -1;
for (int i = 0 ; i < cmap->lcluster_id_max ; i++)
cmap->lcluster[i].version = 0xffffffff;
if (_fygue_flash_cmap_discover(flash, cmap) != 0)
return -2;
return 0;
if (flash == NULL || cmap == NULL)
return -1;
for (int i = 0 ; i < cmap->lcluster_id_max ; i++)
cmap->lcluster[i].version = 0xffffffff;
if (_fygue_flash_cmap_discover(flash, cmap) != 0)
return -2;
return 0;
}

View file

@ -16,45 +16,45 @@
* hardcoded information */
int _fygue_flash_hw_detect(struct fygue_flash *flash)
{
GAUTOTYPE geometry = &(flash->geometry);
GAUTOTYPE geometry = &(flash->geometry);
switch (gint[HWCALC])
{
case HWCALC_FXCP400:
geometry->phy_start = 0x01a20000;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
geometry->fsector_count = 0xf2;
break;
case HWCALC_G35PE2:
geometry->phy_start = 0x003f0000;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_64K;
geometry->fsector_count = 0x41;
break;
case HWCALC_FXCG50:
geometry->phy_start = 0x00c80000;
geometry->fsector_count = 0x9c;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
break;
case HWCALC_FXCG100:
geometry->phy_start = 0x00c80000;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
geometry->fsector_count = 0x3d;
break;
default:
errno = ENOTSUP;
return -1;
}
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_128K) {
geometry->size = geometry->fsector_count * 0x20000;
geometry->fcluster_count = geometry->fsector_count * 32;
geometry->fcluster_per_fsector = 32;
} else {
geometry->size = geometry->fsector_count * 0x10000;
geometry->fcluster_count = geometry->fsector_count * 16;
geometry->fcluster_per_fsector = 16;
}
geometry->phy_end = geometry->phy_start + geometry->size;
return 0;
switch (gint[HWCALC])
{
case HWCALC_FXCP400:
geometry->phy_start = 0x01a20000;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
geometry->fsector_count = 0xf2;
break;
case HWCALC_G35PE2:
geometry->phy_start = 0x003f0000;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_64K;
geometry->fsector_count = 0x41;
break;
case HWCALC_FXCG50:
geometry->phy_start = 0x00c80000;
geometry->fsector_count = 0x9c;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
break;
case HWCALC_FXCG100:
geometry->phy_start = 0x00c80000;
geometry->fsector_size = FYGUE_FSECTOR_SIZE_128K;
geometry->fsector_count = 0x3d;
break;
default:
errno = ENOTSUP;
return -1;
}
if (geometry->fsector_size == FYGUE_FSECTOR_SIZE_128K) {
geometry->size = geometry->fsector_count * 0x20000;
geometry->fcluster_count = geometry->fsector_count * 32;
geometry->fcluster_per_fsector = 32;
} else {
geometry->size = geometry->fsector_count * 0x10000;
geometry->fcluster_count = geometry->fsector_count * 16;
geometry->fcluster_per_fsector = 16;
}
geometry->phy_end = geometry->phy_start + geometry->size;
return 0;
}
//---
@ -64,22 +64,22 @@ int _fygue_flash_hw_detect(struct fygue_flash *flash)
/* fygue_flash_initialize(): init flash abstraction */
int fygue_flash_initialize(struct fygue_flash *flash)
{
if (flash == NULL)
return -1;
memset(flash, 0x00, sizeof(struct fygue_flash));
if (_fygue_flash_hw_detect(flash) != 0)
return -2;
if (fygue_flash_cmap_initialize(flash, &(flash->cmap)) != 0)
return -3;
return 0;
if (flash == NULL)
return -1;
memset(flash, 0x00, sizeof(struct fygue_flash));
if (_fygue_flash_hw_detect(flash) != 0)
return -2;
if (fygue_flash_cmap_initialize(flash, &(flash->cmap)) != 0)
return -3;
return 0;
}
/* fygue_flash_sync(): re-init flash information */
int fygue_flash_sync(struct fygue_flash *flash)
{
if (flash == NULL)
return -1;
if (fygue_flash_cmap_sync(flash, &(flash->cmap)) != 0)
return -3;
return 0;
if (flash == NULL)
return -1;
if (fygue_flash_cmap_sync(flash, &(flash->cmap)) != 0)
return -3;
return 0;
}

View file

@ -7,52 +7,52 @@
/* fygue_fcluster - generic flash cluster information */
struct fygue_flash_cluster
{
enum {
FYGUE_FCLUSTER_KIND_DATA = 0x11,
FYGUE_FCLUSTER_KIND_FINFO = 0x22,
FYGUE_FCLUSTER_KIND_DETAILS = 0x88,
FYGUE_FCLUSTER_KIND_METADATA = 0x667,
} kind;
uint16_t fcluster_id;
uint16_t fcluster_id_bfile;
uint16_t lcluster_id;
uint32_t version;
uintptr_t data_addr;
uintptr_t meta_addr;
enum {
FYGUE_FCLUSTER_KIND_DATA = 0x11,
FYGUE_FCLUSTER_KIND_FINFO = 0x22,
FYGUE_FCLUSTER_KIND_DETAILS = 0x88,
FYGUE_FCLUSTER_KIND_METADATA = 0x667,
} kind;
uint16_t fcluster_id;
uint16_t fcluster_id_bfile;
uint16_t lcluster_id;
uint32_t version;
uintptr_t data_addr;
uintptr_t meta_addr;
};
/* fygue_fcluster_map_entry - cmap list entry */
struct fygue_flash_cmap_entry
{
uint16_t fcluster_id;
uint16_t fcluster_id_bfile;
uintptr_t fcluster_addr;
uint32_t version;
uint16_t fcluster_id;
uint16_t fcluster_id_bfile;
uintptr_t fcluster_addr;
uint32_t version;
};
/* fygue_cmap_info - Cluster redirection information */
struct fygue_flash_cmap
{
struct fygue_flash_cmap_entry *lcluster;
int lcluster_id_max;
struct fygue_flash_cmap_entry *lcluster;
int lcluster_id_max;
};
/* fygue_flash - flash information */
struct fygue_flash
{
struct {
uintptr_t phy_start;
uintptr_t phy_end;
size_t size;
enum {
FYGUE_FSECTOR_SIZE_64K,
FYGUE_FSECTOR_SIZE_128K,
} fsector_size;
int fsector_count;
int fcluster_per_fsector;
int fcluster_count;
} geometry;
struct fygue_flash_cmap cmap;
struct {
uintptr_t phy_start;
uintptr_t phy_end;
size_t size;
enum {
FYGUE_FSECTOR_SIZE_64K,
FYGUE_FSECTOR_SIZE_128K,
} fsector_size;
int fsector_count;
int fcluster_per_fsector;
int fcluster_count;
} geometry;
struct fygue_flash_cmap cmap;
};
//---
@ -67,9 +67,9 @@ extern int fygue_flash_sync(struct fygue_flash *flash);
/* fygue_flash_sector_get_addr(): return the logical sector address */
extern int fygue_flash_sector_get_addr(
struct fygue_flash *flash,
uintptr_t *sector_addr,
uint16_t sector_id
struct fygue_flash *flash,
uintptr_t *sector_addr,
uint16_t sector_id
);
//---
@ -78,22 +78,22 @@ extern int fygue_flash_sector_get_addr(
/* fygue_flash_cmap_initialize() - initialize the fcluster redirection map */
extern int fygue_flash_cmap_initialize(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
);
/* fygue_flash_cmap_sync() - sync the fcluster redirection map */
extern int fygue_flash_cmap_sync(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap
);
/* fygue_flash_cmap_lsector_get_addr() - get logical sector address */
extern int fygue_flash_cmap_lsector_get_addr(
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap,
uintptr_t *sector,
uint16_t lsector_id
struct fygue_flash *flash,
struct fygue_flash_cmap *cmap,
uintptr_t *sector,
uint16_t lsector_id
);
//---
@ -102,18 +102,18 @@ extern int fygue_flash_cmap_lsector_get_addr(
/* fygue_flash_cluster_geometry() - get geometry information */
extern int fygue_flash_cluster_geometry(
struct fygue_flash *flash,
uintptr_t addr,
uint16_t *fcluster_id,
uint16_t *fsector_id,
uint16_t *fcluster_off
struct fygue_flash *flash,
uintptr_t addr,
uint16_t *fcluster_id,
uint16_t *fsector_id,
uint16_t *fcluster_off
);
/* fygue_flash_cluster_get() - get cluster information */
extern int fygue_flash_cluster_get(
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fcluster_id
struct fygue_flash *flash,
struct fygue_flash_cluster *fcluster,
int fcluster_id
);
#endif /* FS_FYGUE_FLASH_H */

View file

@ -2,16 +2,16 @@
/* fygue_flash_sector_get_addr(): return the logical sector address */
int fygue_flash_sector_get_addr(
struct fygue_flash *flash,
uintptr_t *sector_addr,
uint16_t sector_id
struct fygue_flash *flash,
uintptr_t *sector_addr,
uint16_t sector_id
) {
if (flash == NULL || sector_addr == NULL)
return -1;
return fygue_flash_cmap_lsector_get_addr(
flash,
&(flash->cmap),
sector_addr,
sector_id
);
if (flash == NULL || sector_addr == NULL)
return -1;
return fygue_flash_cmap_lsector_get_addr(
flash,
&(flash->cmap),
sector_addr,
sector_id
);
}

View file

@ -1,5 +1,5 @@
/*
** fygue/_fat/sector - FAT sector handling
** fygue/_fat/sector - FAT sector handling
*/
#include "fat.h"
@ -9,11 +9,11 @@
/* fygue_fat_sector_get_addr() - get logical sector addr */
int fygue_fat_sector_get_addr(
struct fygue_fat *fat,
uintptr_t *addr,
int sector
struct fygue_fat *fat,
uintptr_t *addr,
int sector
) {
if (fat != NULL)
return fygue_flash_sector_get_addr(&(fat->_flash), addr, sector);
return -1;
if (fat != NULL)
return fygue_flash_sector_get_addr(&(fat->_flash), addr, sector);
return -1;
}

View file

@ -9,7 +9,7 @@
/* FYGUE_GFDI_CHEK - shorthand for all GFDI prologue */
#define FYGUE_GFDI_CHEK(type) \
_fygue_gfdi_ensure_valid(&fsinfo, desc, type)
_fygue_gfdi_ensure_valid(&fsinfo, desc, type)
/* _fygue_gfdi_ensure_valid(): ensure GFDI validity
*
@ -18,31 +18,31 @@
* - auto mount the FS (if needed) and get information
* - ensure file sync if needed */
static int _fygue_gfdi_ensure_valid(
struct fygue_fsinfo **fsinfo,
struct fygue_descriptor *desc,
unsigned int type
struct fygue_fsinfo **fsinfo,
struct fygue_descriptor *desc,
unsigned int type
) {
int rc;
int rc;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL)
FYGUE_RET_ERRNO(EIO);
if (desc == NULL || desc->type != type)
FYGUE_RET_ERRNO(EBADF);
if (fygue_mount(fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
if (desc->dirty)
{
if (desc->type == FYGUE_DESC_TYPE_DIR)
rc = fygue_dir_sync(*fsinfo, &(desc->dir));
if (desc->type == FYGUE_DESC_TYPE_FILE)
rc = fygue_file_sync(*fsinfo, &(desc->file));
if (rc != 0)
FYGUE_RET_ERRNO(EIO);
desc->dirty = false;
}
return 0;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL)
FYGUE_RET_ERRNO(EIO);
if (desc == NULL || desc->type != type)
FYGUE_RET_ERRNO(EBADF);
if (fygue_mount(fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
if (desc->dirty)
{
if (desc->type == FYGUE_DESC_TYPE_DIR)
rc = fygue_dir_sync(*fsinfo, &(desc->dir));
if (desc->type == FYGUE_DESC_TYPE_FILE)
rc = fygue_file_sync(*fsinfo, &(desc->file));
if (rc != 0)
FYGUE_RET_ERRNO(EIO);
desc->dirty = false;
}
return 0;
}
//---
@ -51,51 +51,51 @@ static int _fygue_gfdi_ensure_valid(
/* fygue_gfdi_file_write(): write file */
static ssize_t fygue_gfdi_file_write(
struct fygue_descriptor *desc,
void *buffer,
size_t size
struct fygue_descriptor *desc,
void *buffer,
size_t size
) {
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
return fygue_file_write(fsinfo, &(desc->file), buffer, size);
return -1;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
return fygue_file_write(fsinfo, &(desc->file), buffer, size);
return -1;
}
/* fygue_gfdi_file_read(): write directory (EISDIR) */
static ssize_t fygue_gfdi_file_read(
struct fygue_descriptor *desc,
void *buffer,
size_t size
struct fygue_descriptor *desc,
void *buffer,
size_t size
) {
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
return fygue_file_read(fsinfo, &(desc->file), buffer, size);
return -1;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
return fygue_file_read(fsinfo, &(desc->file), buffer, size);
return -1;
}
/* fygue_file_lseek(): seek file */
static off_t fygue_gfdi_file_lseek(
struct fygue_descriptor *desc,
off_t offset,
int whence
struct fygue_descriptor *desc,
off_t offset,
int whence
) {
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
return fygue_file_lseek(fsinfo, &(desc->file), offset, whence);
return -1;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
return fygue_file_lseek(fsinfo, &(desc->file), offset, whence);
return -1;
}
/* fygue_file_close(): close directory */
static int fygue_gfdi_file_close(struct fygue_descriptor *desc)
{
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
return fygue_file_close(fsinfo, &(desc->file));
return -1;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_FILE) == 0)
return fygue_file_close(fsinfo, &(desc->file));
return -1;
}
//---
@ -104,51 +104,51 @@ static int fygue_gfdi_file_close(struct fygue_descriptor *desc)
/* fygue_dir_write(): write directory (EISDIR) */
ssize_t fygue_gfdi_dir_write(
struct fygue_descriptor *desc,
void *buffer,
size_t size
struct fygue_descriptor *desc,
void *buffer,
size_t size
) {
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
return fygue_dir_write(fsinfo, &(desc->dir), buffer, size);
return -1;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
return fygue_dir_write(fsinfo, &(desc->dir), buffer, size);
return -1;
}
/* fygue_gfdi_dir_read(): readdir */
ssize_t fygue_gfdi_dir_read(
struct fygue_descriptor *desc,
struct dirent **dirent,
size_t size
struct fygue_descriptor *desc,
struct dirent **dirent,
size_t size
) {
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
return fygue_dir_read(fsinfo, &(desc->dir), dirent, size);
return -1;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
return fygue_dir_read(fsinfo, &(desc->dir), dirent, size);
return -1;
}
/* fygue_gfdi_dir_lseek(): seek directory */
off_t fygue_gfdi_dir_lseek(
struct fygue_descriptor *desc,
off_t offset,
int whence
struct fygue_descriptor *desc,
off_t offset,
int whence
) {
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
return fygue_dir_lseek(fsinfo, &(desc->dir), offset, whence);
return -1;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
return fygue_dir_lseek(fsinfo, &(desc->dir), offset, whence);
return -1;
}
/* fygue_gfdi_dir_close(): close directory */
int fygue_gfdi_dir_close(struct fygue_descriptor *desc)
{
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
return fygue_dir_close(fsinfo, &(desc->dir));
return -1;
if (FYGUE_GFDI_CHEK(FYGUE_DESC_TYPE_DIR) == 0)
return fygue_dir_close(fsinfo, &(desc->dir));
return -1;
}
//---
@ -157,15 +157,15 @@ int fygue_gfdi_dir_close(struct fygue_descriptor *desc)
/* fygue_file_descriptor_type - fygue file descriptor */
const fs_descriptor_type_t fygue_file_descriptor_type = {
.read = (void*)&fygue_gfdi_file_read,
.write = (void*)&fygue_gfdi_file_write,
.lseek = (void*)&fygue_gfdi_file_lseek,
.close = (void*)&fygue_gfdi_file_close,
.read = (void*)&fygue_gfdi_file_read,
.write = (void*)&fygue_gfdi_file_write,
.lseek = (void*)&fygue_gfdi_file_lseek,
.close = (void*)&fygue_gfdi_file_close,
};
const fs_descriptor_type_t fygue_dir_descriptor_type = {
.read = (void*)&fygue_gfdi_dir_read,
.write = (void*)&fygue_gfdi_dir_write,
.lseek = (void*)&fygue_gfdi_dir_lseek,
.close = (void*)&fygue_gfdi_dir_close,
.read = (void*)&fygue_gfdi_dir_read,
.write = (void*)&fygue_gfdi_dir_write,
.lseek = (void*)&fygue_gfdi_dir_lseek,
.close = (void*)&fygue_gfdi_dir_close,
};

View file

@ -28,13 +28,13 @@ extern const fs_descriptor_type_t fygue_dir_descriptor_type;
/* helper to set errno and return -1 */
#define FYGUE_RET_ERRNO(error) \
do { errno = error; return -1; } while(0);
do { errno = error; return -1; } while(0);
/* fygue_fsinfo: internal fygue FS information */
struct fygue_fsinfo
{
struct fygue_fat fat;
bool dirty;
struct fygue_fat fat;
bool dirty;
};
/* fygue_open() - open file or directory */
@ -60,35 +60,35 @@ extern int fygue_mount(struct fygue_fsinfo **fsinfo);
/* fygue_file - file information */
struct fygue_file
{
struct fygue_fat_file fat;
off_t cursor;
size_t size;
char *path;
struct fygue_fat_file fat;
off_t cursor;
size_t size;
char *path;
};
/* fygue_dir - directory information */
struct fygue_dir
{
struct fygue_fat_dir fat;
struct dirent **dirent;
int dirent_idx_max;
int count;
int pos;
char *path;
struct fygue_fat_dir fat;
struct dirent **dirent;
int dirent_idx_max;
int count;
int pos;
char *path;
};
/* fygue_descriptor - fygue file descriptor */
struct fygue_descriptor
{
enum {
FYGUE_DESC_TYPE_FILE,
FYGUE_DESC_TYPE_DIR,
} type;
union {
struct fygue_file file;
struct fygue_dir dir;
};
bool dirty;
enum {
FYGUE_DESC_TYPE_FILE,
FYGUE_DESC_TYPE_DIR,
} type;
union {
struct fygue_file file;
struct fygue_dir dir;
};
bool dirty;
};
//---
@ -97,8 +97,8 @@ struct fygue_descriptor
/* fygue_open_resolve() - open file or directory */
extern int fygue_open_resolve(
char const *path,
struct fygue_descriptor *desc
char const *path,
struct fygue_descriptor *desc
);
//---
@ -107,46 +107,46 @@ extern int fygue_open_resolve(
/* fygue_dir_open(): directory-specific open */
extern int fygue_dir_open(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
char const * const path,
struct fygue_fat_dir *fat_dir
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
char const * const path,
struct fygue_fat_dir *fat_dir
);
/* fygue_dir_read(): directory read implementation */
extern ssize_t fygue_dir_read(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
struct dirent **dirent,
size_t size
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
struct dirent **dirent,
size_t size
);
/* fygue_dir_lseek(): seek directory */
extern off_t fygue_dir_lseek(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
off_t offset,
int whence
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
off_t offset,
int whence
);
/* fygue_dir_write(): write directory (EISDIR) */
extern ssize_t fygue_dir_write(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
void *buffer,
size_t size
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
void *buffer,
size_t size
);
/* fygue_dir_close(): close directory */
extern int fygue_dir_close(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
);
/* fygue_dir_sync(): directory-specific sync */
extern int fygue_dir_sync(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
);
//---
@ -155,46 +155,46 @@ extern int fygue_dir_sync(
/* fygue_file_open(): file open */
extern int fygue_file_open(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
char const * const path,
struct fygue_fat_file *fat_file
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
char const * const path,
struct fygue_fat_file *fat_file
);
/* fygue_file_read(): read primitive */
extern ssize_t fygue_file_read(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
void *buffer,
size_t size
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
void *buffer,
size_t size
);
/* fygue_file_lseek(): seek directory */
extern off_t fygue_file_lseek(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
off_t offset,
int whence
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
off_t offset,
int whence
);
/* fygue_file_write(): write directory (EROFS) */
extern ssize_t fygue_file_write(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
void *buffer,
size_t size
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
void *buffer,
size_t size
);
/* fygue_file_close(): close directory */
extern int fygue_file_close(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file
struct fygue_fsinfo *fsinfo,
struct fygue_file *file
);
/* fygue_file_sync(): file-specific sync */
extern int fygue_file_sync(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file
struct fygue_fsinfo *fsinfo,
struct fygue_file *file
);
#ifdef __cplusplus

View file

@ -6,22 +6,22 @@
/* fygue_dir_close(): close directory */
int fygue_dir_close(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
) {
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
fygue_fat_dir_close(&(fsinfo->fat), &(dir->fat));
if (dir->dirent != NULL)
{
for (int i = 0 ; i < dir->count ; i++) {
if (dir->dirent[i] != NULL)
free(dir->dirent[i]);
}
free(dir->dirent);
}
if (dir->path != NULL)
free(dir->path);
memset(dir, 0x00, sizeof(struct fygue_dir));
return 0;
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
fygue_fat_dir_close(&(fsinfo->fat), &(dir->fat));
if (dir->dirent != NULL)
{
for (int i = 0 ; i < dir->count ; i++) {
if (dir->dirent[i] != NULL)
free(dir->dirent[i]);
}
free(dir->dirent);
}
if (dir->path != NULL)
free(dir->path);
memset(dir, 0x00, sizeof(struct fygue_dir));
return 0;
}

View file

@ -2,23 +2,23 @@
/* fygue_dir_lseek(): seek directory */
off_t fygue_dir_lseek(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
off_t offset,
int whence
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
off_t offset,
int whence
) {
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END)
FYGUE_RET_ERRNO(EINVAL);
if(whence == SEEK_CUR)
offset += dir->pos;
if(whence == SEEK_END)
offset += dir->count;
if(offset < 0 || offset >= dir->count + 1)
FYGUE_RET_ERRNO(EINVAL);
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END)
FYGUE_RET_ERRNO(EINVAL);
if(whence == SEEK_CUR)
offset += dir->pos;
if(whence == SEEK_END)
offset += dir->count;
if(offset < 0 || offset >= dir->count + 1)
FYGUE_RET_ERRNO(EINVAL);
dir->pos = offset;
return dir->pos;
dir->pos = offset;
return dir->pos;
}

View file

@ -9,78 +9,78 @@
/* realloc a prepare the internal table */
static int _fygue_dir_open_table_realloc(struct fygue_dir *dir)
{
void *tmp;
void *tmp;
tmp = reallocarray(
dir->dirent,
dir->dirent_idx_max + 16,
sizeof(struct dirent)
);
if (tmp == NULL)
FYGUE_RET_ERRNO(ENOMEM);
dir->dirent = tmp;
dir->dirent_idx_max += 16;
for (int i = dir->count ; i < dir->dirent_idx_max ; i++)
dir->dirent[i] = NULL;
return 0;
tmp = reallocarray(
dir->dirent,
dir->dirent_idx_max + 16,
sizeof(struct dirent)
);
if (tmp == NULL)
FYGUE_RET_ERRNO(ENOMEM);
dir->dirent = tmp;
dir->dirent_idx_max += 16;
for (int i = dir->count ; i < dir->dirent_idx_max ; i++)
dir->dirent[i] = NULL;
return 0;
}
/* free internal table */
static void _fygue_dir_open_table_free(struct fygue_dir *dir)
{
if (dir->dirent == NULL)
return;
for (int i = 0 ; i < dir->dirent_idx_max ; i++) {
if (dir->dirent[i] != NULL)
free(dir->dirent[i]);
}
free(dir->dirent);
dir->dirent = NULL;
if (dir->dirent == NULL)
return;
for (int i = 0 ; i < dir->dirent_idx_max ; i++) {
if (dir->dirent[i] != NULL)
free(dir->dirent[i]);
}
free(dir->dirent);
dir->dirent = NULL;
}
/* convert FAT dirent to dirent */
static int _fygue_dir_open_convert(
struct dirent **dirent,
struct fygue_fat_dirent *fat_dirent
struct dirent **dirent,
struct fygue_fat_dirent *fat_dirent
) {
size_t len;
size_t len;
len = strlen(fat_dirent->name);
*dirent = calloc(1, sizeof(struct dirent) + len + 2);
if (*dirent == NULL)
FYGUE_RET_ERRNO(ENOMEM);
(*dirent)->d_ino = fat_dirent->cluster_id;
(*dirent)->d_type = DT_REG;
memcpy((*dirent)->d_name, fat_dirent->name, len + 1);
return 0;
len = strlen(fat_dirent->name);
*dirent = calloc(1, sizeof(struct dirent) + len + 2);
if (*dirent == NULL)
FYGUE_RET_ERRNO(ENOMEM);
(*dirent)->d_ino = fat_dirent->cluster_id;
(*dirent)->d_type = DT_REG;
memcpy((*dirent)->d_name, fat_dirent->name, len + 1);
return 0;
}
/* _fygue_dir_open_discover(): discover all dirent */
static int _fygue_dir_open_discover(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
) {
struct fygue_fat_dirent dirent;
int rc;
struct fygue_fat_dirent dirent;
int rc;
while (true)
{
rc = fygue_fat_dir_read(&(fsinfo->fat), &(dir->fat), &dirent);
if (rc > 0)
return 0;
if (rc < 0)
break;
if (dir->count >= dir->dirent_idx_max) {
if (_fygue_dir_open_table_realloc(dir) != 0)
break;
}
rc = _fygue_dir_open_convert(&(dir->dirent[dir->count]), &dirent);
if (rc != 0)
break;
dir->count += 1;
}
_fygue_dir_open_table_free(dir);
FYGUE_RET_ERRNO(EIO);
while (true)
{
rc = fygue_fat_dir_read(&(fsinfo->fat), &(dir->fat), &dirent);
if (rc > 0)
return 0;
if (rc < 0)
break;
if (dir->count >= dir->dirent_idx_max) {
if (_fygue_dir_open_table_realloc(dir) != 0)
break;
}
rc = _fygue_dir_open_convert(&(dir->dirent[dir->count]), &dirent);
if (rc != 0)
break;
dir->count += 1;
}
_fygue_dir_open_table_free(dir);
FYGUE_RET_ERRNO(EIO);
}
//---
@ -90,27 +90,27 @@ static int _fygue_dir_open_discover(
/* fygue_dir_open(): directory-specific open */
int fygue_dir_open(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
char const * const path,
struct fygue_fat_dir *fat_dir
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
char const * const path,
struct fygue_fat_dir *fat_dir
) {
if (fsinfo == NULL || dir == NULL || path == NULL || fat_dir == NULL)
return -1;
if (fsinfo == NULL || dir == NULL || path == NULL || fat_dir == NULL)
return -1;
memset(dir, 0x00, sizeof(struct fygue_dir));
dir->path = strdup(path);
if (dir->path == NULL)
FYGUE_RET_ERRNO(ENOMEM);
dir->dirent_idx_max = 0;
dir->dirent = NULL;
dir->count = 0;
dir->pos = 0;
memcpy(&(dir->fat), fat_dir, sizeof(struct fygue_fat_dir));
memset(dir, 0x00, sizeof(struct fygue_dir));
dir->path = strdup(path);
if (dir->path == NULL)
FYGUE_RET_ERRNO(ENOMEM);
dir->dirent_idx_max = 0;
dir->dirent = NULL;
dir->count = 0;
dir->pos = 0;
memcpy(&(dir->fat), fat_dir, sizeof(struct fygue_fat_dir));
if (_fygue_dir_open_discover(fsinfo, dir) != 0) {
free(dir->path);
return -1;
}
return 0;
if (_fygue_dir_open_discover(fsinfo, dir) != 0) {
free(dir->path);
return -1;
}
return 0;
}

View file

@ -7,20 +7,20 @@
* notes
* - assume that the directory have read permission */
ssize_t fygue_dir_read(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
struct dirent **dirent,
size_t size
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
struct dirent **dirent,
size_t size
) {
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
if (dirent == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (size < sizeof *dirent)
FYGUE_RET_ERRNO(EINVAL);
if (dir->pos >= dir->count)
FYGUE_RET_ERRNO(EIO);
*dirent = dir->dirent[dir->pos];
dir->pos += 1;
return sizeof *dirent;
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
if (dirent == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (size < sizeof *dirent)
FYGUE_RET_ERRNO(EINVAL);
if (dir->pos >= dir->count)
FYGUE_RET_ERRNO(EIO);
*dirent = dir->dirent[dir->pos];
dir->pos += 1;
return sizeof *dirent;
}

View file

@ -4,55 +4,55 @@
/* fygue_dir_sync(): directory-specific sync */
int fygue_dir_sync(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir
) {
struct fygue_fat_descriptor desc;
int saved_pos;
int rc;
struct fygue_fat_descriptor desc;
int saved_pos;
int rc;
/* preliminary check */
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
/* preliminary check */
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
/* update FAT-specific information */
//TODO: assume that the first cluster will remain the same ?
if (fygue_fat_open(&(fsinfo->fat), dir->path, &desc) != 0)
FYGUE_RET_ERRNO(ENOENT);
if (desc.type != FYGUE_FAT_DESC_TYPE_FILE)
FYGUE_RET_ERRNO(EIO);
rc = fygue_fat_dir_sync(
&(fsinfo->fat),
&(desc.dir),
desc.file.cluster_entry
);
if (rc != 0)
FYGUE_RET_ERRNO(EIO);
/* update FAT-specific information */
//TODO: assume that the first cluster will remain the same ?
if (fygue_fat_open(&(fsinfo->fat), dir->path, &desc) != 0)
FYGUE_RET_ERRNO(ENOENT);
if (desc.type != FYGUE_FAT_DESC_TYPE_FILE)
FYGUE_RET_ERRNO(EIO);
rc = fygue_fat_dir_sync(
&(fsinfo->fat),
&(desc.dir),
desc.file.cluster_entry
);
if (rc != 0)
FYGUE_RET_ERRNO(EIO);
/* refresh internal information */
//TODO: re-use realloc
if (dir->dirent != NULL)
{
for (int i = 0 ; i < dir->count ; i++)
{
if (dir->dirent[i] == NULL)
continue;
free(dir->dirent[i]);
dir->dirent[i] = NULL;
}
free(dir->dirent);
dir->dirent = NULL;
dir->count = 0;
}
/* hack to force regenerate the dirent cache */
saved_pos = dir->pos;
if (
fygue_dir_lseek(fsinfo, dir, 0, SEEK_SET) != 0 ||
fygue_dir_lseek(fsinfo, dir, saved_pos, SEEK_SET) != 0
) {
return -1;
}
return 0;
/* refresh internal information */
//TODO: re-use realloc
if (dir->dirent != NULL)
{
for (int i = 0 ; i < dir->count ; i++)
{
if (dir->dirent[i] == NULL)
continue;
free(dir->dirent[i]);
dir->dirent[i] = NULL;
}
free(dir->dirent);
dir->dirent = NULL;
dir->count = 0;
}
/* hack to force regenerate the dirent cache */
saved_pos = dir->pos;
if (
fygue_dir_lseek(fsinfo, dir, 0, SEEK_SET) != 0 ||
fygue_dir_lseek(fsinfo, dir, saved_pos, SEEK_SET) != 0
) {
return -1;
}
return 0;
}

View file

@ -2,16 +2,16 @@
/* fygue_dir_write(): write directory (EISDIR) */
ssize_t fygue_dir_write(
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
void *buffer,
size_t size
struct fygue_fsinfo *fsinfo,
struct fygue_dir *dir,
void *buffer,
size_t size
) {
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
if (buffer == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (size != 0)
FYGUE_RET_ERRNO(EISDIR);
return 0;
if (fsinfo == NULL || dir == NULL)
FYGUE_RET_ERRNO(EIO);
if (buffer == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (size != 0)
FYGUE_RET_ERRNO(EISDIR);
return 0;
}

View file

@ -4,14 +4,14 @@
/* fygue_file_close(): close directory */
int fygue_file_close(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file
struct fygue_fsinfo *fsinfo,
struct fygue_file *file
) {
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
fygue_fat_file_close(&(fsinfo->fat), &(file->fat));
if (file->path != NULL)
free(file->path);
memset(file, 0x00, sizeof(struct fygue_file));
return 0;
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
fygue_fat_file_close(&(fsinfo->fat), &(file->fat));
if (file->path != NULL)
free(file->path);
memset(file, 0x00, sizeof(struct fygue_file));
return 0;
}

View file

@ -2,26 +2,26 @@
/* fygue_file_lseek(): seek file */
off_t fygue_file_lseek(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
off_t offset,
int whence
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
off_t offset,
int whence
) {
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END)
FYGUE_RET_ERRNO(EINVAL);
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
if (whence != SEEK_CUR && whence != SEEK_SET && whence != SEEK_END)
FYGUE_RET_ERRNO(EINVAL);
if(whence == SEEK_CUR)
offset += file->cursor;
if(whence == SEEK_END)
offset += file->size;
if(offset < 0 || (unsigned)offset >= file->size + 1)
FYGUE_RET_ERRNO(EINVAL);
if(whence == SEEK_CUR)
offset += file->cursor;
if(whence == SEEK_END)
offset += file->size;
if(offset < 0 || (unsigned)offset >= file->size + 1)
FYGUE_RET_ERRNO(EINVAL);
if (fygue_fat_file_seek(&(fsinfo->fat), &(file->fat), offset) != 0)
FYGUE_RET_ERRNO(EIO);
if (fygue_fat_file_seek(&(fsinfo->fat), &(file->fat), offset) != 0)
FYGUE_RET_ERRNO(EIO);
file->cursor = offset;
return file->cursor;
file->cursor = offset;
return file->cursor;
}

View file

@ -3,20 +3,20 @@
/* fygue_file_open(): file open */
int fygue_file_open(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
char const * const path,
struct fygue_fat_file *fat_file
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
char const * const path,
struct fygue_fat_file *fat_file
) {
if (fsinfo == NULL || file == NULL || path == NULL || fat_file == NULL)
return -1;
if (fsinfo == NULL || file == NULL || path == NULL || fat_file == NULL)
return -1;
memset(file, 0x00, sizeof(struct fygue_file));
file->path = strdup(path);
if (file->path == NULL)
FYGUE_RET_ERRNO(ENOMEM);
file->cursor = 0;
file->size = fat_file->size;
memcpy(&(file->fat), fat_file, sizeof(struct fygue_fat_file));
return 0;
memset(file, 0x00, sizeof(struct fygue_file));
file->path = strdup(path);
if (file->path == NULL)
FYGUE_RET_ERRNO(ENOMEM);
file->cursor = 0;
file->size = fat_file->size;
memcpy(&(file->fat), fat_file, sizeof(struct fygue_fat_file));
return 0;
}

View file

@ -2,24 +2,24 @@
/* fygue_file_read(): read file data */
ssize_t fygue_file_read(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
void *buffer,
size_t size
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
void *buffer,
size_t size
) {
ssize_t read;
ssize_t read;
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
if (buffer == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (file->cursor > 0 && (unsigned)file->cursor >= file->size)
return 0;
if (file->cursor + size >= file->size)
size = file->size - file->cursor;
read = fygue_fat_file_read(&(fsinfo->fat), &(file->fat), buffer, size);
if (read < 0)
FYGUE_RET_ERRNO(EIO);
file->cursor += read;
return read;
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
if (buffer == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (file->cursor > 0 && (unsigned)file->cursor >= file->size)
return 0;
if (file->cursor + size >= file->size)
size = file->size - file->cursor;
read = fygue_fat_file_read(&(fsinfo->fat), &(file->fat), buffer, size);
if (read < 0)
FYGUE_RET_ERRNO(EIO);
file->cursor += read;
return read;
}

View file

@ -3,28 +3,28 @@
/* fygue_file_sync(): file-specific sync */
int fygue_file_sync(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file
struct fygue_fsinfo *fsinfo,
struct fygue_file *file
) {
struct fygue_fat_descriptor desc;
int rc;
struct fygue_fat_descriptor desc;
int rc;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
//TODO: assume that the first cluster will remain the same ?
if (fygue_fat_open(&(fsinfo->fat), file->path, &desc) != 0)
FYGUE_RET_ERRNO(ENOENT);
if (desc.type != FYGUE_FAT_DESC_TYPE_FILE)
FYGUE_RET_ERRNO(EIO);
rc = fygue_fat_file_sync(
&(fsinfo->fat),
&(desc.file),
desc.file.cluster_entry
);
if (rc != 0)
FYGUE_RET_ERRNO(EIO);
return 0;
//TODO: assume that the first cluster will remain the same ?
if (fygue_fat_open(&(fsinfo->fat), file->path, &desc) != 0)
FYGUE_RET_ERRNO(ENOENT);
if (desc.type != FYGUE_FAT_DESC_TYPE_FILE)
FYGUE_RET_ERRNO(EIO);
rc = fygue_fat_file_sync(
&(fsinfo->fat),
&(desc.file),
desc.file.cluster_entry
);
if (rc != 0)
FYGUE_RET_ERRNO(EIO);
return 0;
}

View file

@ -2,16 +2,16 @@
/* fygue_file_write(): write directory (EISDIR) */
ssize_t fygue_file_write(
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
void *buffer,
size_t size
struct fygue_fsinfo *fsinfo,
struct fygue_file *file,
void *buffer,
size_t size
) {
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
if (buffer == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (size != 0)
FYGUE_RET_ERRNO(EROFS);
return 0;
if (fsinfo == NULL || file == NULL)
FYGUE_RET_ERRNO(EIO);
if (buffer == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (size != 0)
FYGUE_RET_ERRNO(EROFS);
return 0;
}

View file

@ -18,28 +18,28 @@ static struct fygue_fsinfo *__fygue_fsinfo = NULL;
* - assume that this global is const after initialisation */
int fygue_mount(struct fygue_fsinfo **fsinfo)
{
if (fsinfo == NULL)
return -1;
*fsinfo = NULL;
if (__fygue_fsinfo == NULL)
{
__fygue_fsinfo = calloc(1, sizeof(struct fygue_fsinfo));
if (__fygue_fsinfo == NULL)
return -2;
if (fygue_fat_initialize(&(__fygue_fsinfo->fat)) != 0)
{
free(__fygue_fsinfo);
__fygue_fsinfo = NULL;
return -3;
}
__fygue_fsinfo->dirty = false;
}
if (__fygue_fsinfo->dirty)
{
if (fygue_fat_sync(&(__fygue_fsinfo->fat)) != 0)
return -4;
__fygue_fsinfo->dirty = false;
}
*fsinfo = __fygue_fsinfo;
return 0;
if (fsinfo == NULL)
return -1;
*fsinfo = NULL;
if (__fygue_fsinfo == NULL)
{
__fygue_fsinfo = calloc(1, sizeof(struct fygue_fsinfo));
if (__fygue_fsinfo == NULL)
return -2;
if (fygue_fat_initialize(&(__fygue_fsinfo->fat)) != 0)
{
free(__fygue_fsinfo);
__fygue_fsinfo = NULL;
return -3;
}
__fygue_fsinfo->dirty = false;
}
if (__fygue_fsinfo->dirty)
{
if (fygue_fat_sync(&(__fygue_fsinfo->fat)) != 0)
return -4;
__fygue_fsinfo->dirty = false;
}
*fsinfo = __fygue_fsinfo;
return 0;
}

View file

@ -17,71 +17,71 @@
* - automatically mount the filesystem if needed
* - the saved pathname will not be saved in stat */
int fygue_open_resolve(
char const * const path,
struct fygue_descriptor *desc
char const * const path,
struct fygue_descriptor *desc
) {
struct fygue_fat_descriptor fat_desc;
struct fygue_fsinfo *fsinfo;
struct fygue_fat_descriptor fat_desc;
struct fygue_fsinfo *fsinfo;
if (path == NULL || desc == NULL)
return -1;
if (fygue_mount(&fsinfo) != 0)
return -2;
if (fygue_fat_open(&(fsinfo->fat), path, &fat_desc) != 0)
return -3;
memset(desc, 0x00, sizeof(struct fygue_descriptor));
if (fat_desc.type == FYGUE_FAT_DESC_TYPE_DIR)
{
desc->type = FYGUE_DESC_TYPE_DIR;
return fygue_dir_open(fsinfo, &(desc->dir), path, &(fat_desc.dir));
}
desc->type = FYGUE_DESC_TYPE_FILE;
return fygue_file_open(fsinfo, &(desc->file), path, &fat_desc.file);
if (path == NULL || desc == NULL)
return -1;
if (fygue_mount(&fsinfo) != 0)
return -2;
if (fygue_fat_open(&(fsinfo->fat), path, &fat_desc) != 0)
return -3;
memset(desc, 0x00, sizeof(struct fygue_descriptor));
if (fat_desc.type == FYGUE_FAT_DESC_TYPE_DIR)
{
desc->type = FYGUE_DESC_TYPE_DIR;
return fygue_dir_open(fsinfo, &(desc->dir), path, &(fat_desc.dir));
}
desc->type = FYGUE_DESC_TYPE_FILE;
return fygue_file_open(fsinfo, &(desc->file), path, &fat_desc.file);
}
/* fygue_open(): open primitive */
int fygue_open(char const *path, int flags, GUNUSED mode_t mode)
{
struct fygue_descriptor desc;
fs_descriptor_t gint_desc;
int exists;
struct fygue_descriptor desc;
fs_descriptor_t gint_desc;
int exists;
/* preliminary checks */
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if ((flags & O_RDWR) || (flags & O_WRONLY))
FYGUE_RET_ERRNO(EROFS);
/* preliminary checks */
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if ((flags & O_RDWR) || (flags & O_WRONLY))
FYGUE_RET_ERRNO(EROFS);
/* resolve the entry */
exists = fygue_open_resolve(path, &desc);
/* resolve the entry */
exists = fygue_open_resolve(path, &desc);
/* if opening fails and no explicit file creation is required, fail */
if ((exists < 0 && (!(flags & O_CREAT) || (flags & O_DIRECTORY))))
FYGUE_RET_ERRNO(ENOENT);
/* if opening fails and no explicit file creation is required, fail */
if ((exists < 0 && (!(flags & O_CREAT) || (flags & O_DIRECTORY))))
FYGUE_RET_ERRNO(ENOENT);
/* if opening fails and the previous check as not returned an error,
* it is certainly because of a creation request. We are a read-only
* file-system, so, fail */
if (exists < 0)
FYGUE_RET_ERRNO(EROFS);
/* if opening fails and the previous check as not returned an error,
* it is certainly because of a creation request. We are a read-only
* file-system, so, fail */
if (exists < 0)
FYGUE_RET_ERRNO(EROFS);
/* If the entry exists and O_EXCL was requested, fail.
* note that Exclusive open means no sense unless creation is also
* requested */
if(exists >= 0 && (flags & O_EXCL))
FYGUE_RET_ERRNO(EEXIST);
/* If the entry exists and O_EXCL was requested, fail.
* note that Exclusive open means no sense unless creation is also
* requested */
if(exists >= 0 && (flags & O_EXCL))
FYGUE_RET_ERRNO(EEXIST);
/* generate the final file descriptor */
gint_desc.type = &fygue_file_descriptor_type;
gint_desc.data = calloc(1, sizeof(struct fygue_descriptor));
if (gint_desc.data == NULL)
FYGUE_RET_ERRNO(ENOMEM);
memcpy(gint_desc.data, &desc, sizeof(struct fygue_descriptor));
if (flags & O_DIRECTORY)
{
if (desc.type != FYGUE_DESC_TYPE_DIR)
FYGUE_RET_ERRNO(ENOTDIR);
gint_desc.type = &fygue_dir_descriptor_type;
}
return fs_create_descriptor(&gint_desc);
/* generate the final file descriptor */
gint_desc.type = &fygue_file_descriptor_type;
gint_desc.data = calloc(1, sizeof(struct fygue_descriptor));
if (gint_desc.data == NULL)
FYGUE_RET_ERRNO(ENOMEM);
memcpy(gint_desc.data, &desc, sizeof(struct fygue_descriptor));
if (flags & O_DIRECTORY)
{
if (desc.type != FYGUE_DESC_TYPE_DIR)
FYGUE_RET_ERRNO(ENOTDIR);
gint_desc.type = &fygue_dir_descriptor_type;
}
return fs_create_descriptor(&gint_desc);
}

View file

@ -5,18 +5,18 @@
/* fygue_stat(): stat primitive */
int fygue_stat(char const * const path, struct stat *statbuf)
{
struct fygue_descriptor desc;
struct fygue_fsinfo *fsinfo;
struct fygue_descriptor desc;
struct fygue_fsinfo *fsinfo;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (path == NULL || statbuf == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (fygue_mount(&fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
if (fygue_open_resolve(path, &desc) != 0)
FYGUE_RET_ERRNO(ENOENT);
if (desc.type == FYGUE_DESC_TYPE_DIR)
return fygue_fat_dir_stat(&(fsinfo->fat), &(desc.dir.fat), statbuf);
return fygue_fat_file_stat(&(fsinfo->fat), &(desc.file.fat), statbuf);
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (path == NULL || statbuf == NULL)
FYGUE_RET_ERRNO(EFAULT);
if (fygue_mount(&fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
if (fygue_open_resolve(path, &desc) != 0)
FYGUE_RET_ERRNO(ENOENT);
if (desc.type == FYGUE_DESC_TYPE_DIR)
return fygue_fat_dir_stat(&(fsinfo->fat), &(desc.dir.fat), statbuf);
return fygue_fat_file_stat(&(fsinfo->fat), &(desc.file.fat), statbuf);
}

View file

@ -4,12 +4,12 @@
/* fygue_sync() - request filesystem re-synchronisation */
int fygue_sync(void)
{
struct fygue_fsinfo *fsinfo;
struct fygue_fsinfo *fsinfo;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fygue_mount(&fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
fsinfo->dirty = true;
return 0;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (fygue_mount(&fsinfo) != 0)
FYGUE_RET_ERRNO(EIO);
fsinfo->dirty = true;
return 0;
}

View file

@ -4,14 +4,14 @@
/* fygue_syncfs() - request filesystem re-synchronisation */
int fygue_syncfs(void *data)
{
struct fygue_descriptor *desc;
struct fygue_descriptor *desc;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (data == NULL)
FYGUE_RET_ERRNO(EBADF);
desc = data;
desc->dirty = true;
fygue_sync();
return 0;
if(gint[HWFS] != HWFS_FUGUE)
FYGUE_RET_ERRNO(ENOTSUP);
if (data == NULL)
FYGUE_RET_ERRNO(EBADF);
desc = data;
desc->dirty = true;
fygue_sync();
return 0;
}

View file

@ -17,11 +17,11 @@ off_t lseek(int fd, off_t offset, int whence)
/* No seek function: cannot seek */
if(d->type->lseek == NULL)
return 0;
/* BFile_Seek() can flush pending IO write operations. Sync Fygue's
* descriptor to avoid data corruption */
off_t off = d->type->lseek(d->data, offset, whence);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return off;
return 0;
/* BFile_Seek() can flush pending IO write operations. Sync Fygue's
* descriptor to avoid data corruption */
off_t off = d->type->lseek(d->data, offset, whence);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return off;
}

View file

@ -5,6 +5,6 @@ int mkdir(char const *path, mode_t mode)
{
/* Standard mkdir() is the Fugue filesystem only */
int rc = fugue_mkdir(path, mode);
fs_fygue_sync();
return rc;
fs_fygue_sync();
return rc;
}

View file

@ -11,13 +11,13 @@ int open(char const *path, int flags, ...)
va_end(args);
/* Standard open() use Fugue filesystem if a write operation
* is requested, otherwise use the Fygue filesystem */
int rc = -1;
if ((flags & O_WRONLY) || (flags & O_RDWR)) {
rc = fugue_open(path, flags, mode);
fs_fygue_sync();
} else {
rc = fygue_open(path, flags, mode);
}
return rc;
* is requested, otherwise use the Fygue filesystem */
int rc = -1;
if ((flags & O_WRONLY) || (flags & O_RDWR)) {
rc = fugue_open(path, flags, mode);
fs_fygue_sync();
} else {
rc = fygue_open(path, flags, mode);
}
return rc;
}

View file

@ -12,10 +12,10 @@ ssize_t read(int fd, void *buf, size_t size)
/* No read function: we can't read anything */
if(d->type->read == NULL)
return 0;
/* BFile_Read() can flush data in some circumstances, force-sync Fygue */
ssize_t rc = d->type->read(d->data, buf, size);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return rc;
return 0;
/* BFile_Read() can flush data in some circumstances, force-sync Fygue */
ssize_t rc = d->type->read(d->data, buf, size);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return rc;
}

View file

@ -6,6 +6,6 @@ int rename(char const *oldpath, char const *newpath)
{
/* Standard rename() is the Fugue filesystem only */
int rc = fugue_rename(oldpath, newpath);
fs_fygue_sync();
return rc;
fs_fygue_sync();
return rc;
}

View file

@ -5,6 +5,6 @@ int rmdir(char const *path)
{
/* Standard rmdir() is the Fugue filesystem only */
int rc = fugue_rmdir(path);
fs_fygue_sync();
return rc;
fs_fygue_sync();
return rc;
}

View file

@ -4,7 +4,7 @@
int stat(char const * restrict path, struct stat * restrict statbuf)
{
/* Standard stat() is also provided by Fugue, but rely on Casio's
* syscall which do not provide all of the information and request
* a world-switch (internally) to works */
* syscall which do not provide all of the information and request
* a world-switch (internally) to works */
return fygue_stat(path, statbuf);
}

View file

@ -6,6 +6,6 @@ int unlink(char const *path)
{
/* Standard unlink() is the Fugue filesystem only */
int rc = fugue_unlink(path);
fs_fygue_sync();
return rc;
fs_fygue_sync();
return rc;
}

View file

@ -11,11 +11,11 @@ ssize_t write(int fd, const void *buf, size_t size)
}
/* No write function: discard the contents but show no error */
if(d->type->write == NULL)
return 0;
/* A special synchronisation must be performed to ensure that all
* Fygue's descriptor meta information are valid */
size = d->type->write(d->data, buf, size);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return size;
return 0;
/* A special synchronisation must be performed to ensure that all
* Fygue's descriptor meta information are valid */
size = d->type->write(d->data, buf, size);
if (fs_descriptor_is_fugue(d))
fs_fygue_sync();
return size;
}