typedef ao_fat_dirent_t dirent_t;
typedef ao_fat_cluster_offset_t cluster_offset_t;
+/* Global FAT lock */
+static uint8_t ao_fat_mutex;
+
/* Partition information, sector numbers */
static uint8_t partition_type;
}
static uint8_t
-ao_fat_cluster_valid(cluster_t cluster)
+_ao_fat_cluster_valid(cluster_t cluster)
{
return (2 <= cluster && cluster < number_cluster);
}
/* Start using a sector */
static uint8_t *
-ao_fat_sector_get(sector_t sector)
+_ao_fat_sector_get(sector_t sector)
{
sector += partition_start;
if (sector >= partition_end)
}
/* Finish using a sector, 'w' is 1 if modified */
-#define ao_fat_sector_put(b,w) ao_bufio_put(b,w)
+#define _ao_fat_sector_put(b,w) ao_bufio_put(b,w)
/* Get the next cluster entry in the chain */
static cluster_t
-ao_fat_entry_read(cluster_t cluster)
+_ao_fat_entry_read(cluster_t cluster)
{
sector_t sector;
cluster_t offset;
uint8_t *buf;
cluster_t ret;
- if (!ao_fat_cluster_valid(cluster))
+ if (!_ao_fat_cluster_valid(cluster))
return 0xfffffff7;
if (fat32)
cluster <<= 1;
sector = cluster >> (SECTOR_SHIFT);
offset = cluster & SECTOR_MASK;
- buf = ao_fat_sector_get(fat_start + sector);
+ buf = _ao_fat_sector_get(fat_start + sector);
if (!buf)
return 0;
if (AO_FAT_IS_LAST_CLUSTER16(ret))
ret |= 0xfff0000;
}
- ao_fat_sector_put(buf, 0);
+ _ao_fat_sector_put(buf, 0);
return ret;
}
* 'new_value'. Return the previous value.
*/
static cluster_t
-ao_fat_entry_replace(cluster_t cluster, cluster_t new_value)
+_ao_fat_entry_replace(cluster_t cluster, cluster_t new_value)
{
sector_t sector;
cluster_offset_t offset;
uint8_t *buf;
- cluster_t ret;
+ cluster_t ret = 0;
cluster_t old_value;
uint8_t fat;
- if (!ao_fat_cluster_valid(cluster))
+ if (!_ao_fat_cluster_valid(cluster))
return 0xfffffff7;
/* Convert from cluster index to byte index */
new_value &= 0xfffffff;
for (fat = 0; fat < number_fat; fat++) {
- buf = ao_fat_sector_get(fat_start + fat * sectors_per_fat + sector);
+ buf = _ao_fat_sector_get(fat_start + fat * sectors_per_fat + sector);
if (!buf)
return 0;
if (fat32) {
}
put_u16(buf + offset, new_value);
}
- ao_fat_sector_put(buf, 1);
+ _ao_fat_sector_put(buf, 1);
}
return ret;
* all of them as free
*/
static void
-ao_fat_free_cluster_chain(cluster_t cluster)
+_ao_fat_free_cluster_chain(cluster_t cluster)
{
- while (ao_fat_cluster_valid(cluster)) {
+ while (_ao_fat_cluster_valid(cluster)) {
if (cluster < next_free) {
next_free = cluster;
fsinfo_dirty = 1;
}
- cluster = ao_fat_entry_replace(cluster, 0x00000000);
+ cluster = _ao_fat_entry_replace(cluster, 0x00000000);
}
}
/*
- * ao_fat_cluster_seek
+ * _ao_fat_cluster_seek
*
* The basic file system operation -- map a file cluster index to a
* partition cluster number. Done by computing the cluster number and
* is damaged somehow
*/
static cluster_t
-ao_fat_cluster_seek(cluster_t cluster, cluster_t distance)
+_ao_fat_cluster_seek(cluster_t cluster, cluster_t distance)
{
while (distance) {
- cluster = ao_fat_entry_read(cluster);
- if (!ao_fat_cluster_valid(cluster))
+ cluster = _ao_fat_entry_read(cluster);
+ if (!_ao_fat_cluster_valid(cluster))
break;
distance--;
}
}
/*
- * ao_fat_cluster_set_size
+ * _ao_fat_cluster_set_size
*
* Set the number of clusters in the specified chain,
* freeing extra ones or alocating new ones as needed
*/
static cluster_t
-ao_fat_cluster_set_size(cluster_t first_cluster, cluster_t size)
+_ao_fat_cluster_set_size(cluster_t first_cluster, cluster_t size)
{
cluster_t have;
cluster_t last_cluster;
DBG("\tclusters:");
for (have = 0; have < size; have++) {
DBG(" %08x", next_cluster);
- if (!ao_fat_cluster_valid(next_cluster))
+ if (!_ao_fat_cluster_valid(next_cluster))
break;
last_cluster = next_cluster;
- next_cluster = ao_fat_entry_read(next_cluster);
+ next_cluster = _ao_fat_entry_read(next_cluster);
}
DBG("\n");
*/
if (have == size) {
/* The file is large enough, truncate as needed */
- if (ao_fat_cluster_valid(next_cluster)) {
+ if (_ao_fat_cluster_valid(next_cluster)) {
DBG("truncate between %08x and %08x\n", last_cluster, next_cluster);
if (last_cluster)
/*
* Otherwise, rewrite the last cluster
* in the chain with a LAST marker
*/
- (void) ao_fat_entry_replace(last_cluster,
+ (void) _ao_fat_entry_replace(last_cluster,
AO_FAT_LAST_CLUSTER);
else
/*
first_cluster = 0;
/* Clear the remaining clusters in the chain */
- ao_fat_free_cluster_chain(next_cluster);
+ _ao_fat_free_cluster_chain(next_cluster);
/* The file system is no longer full (if it was) */
filesystem_full = 0;
break; \
loop_cluster {
- if (!ao_fat_entry_read(free))
+ if (!_ao_fat_entry_read(free))
need--;
next_cluster;
}
*/
need = size - have;
loop_cluster {
- if (ao_fat_entry_read(free) == 0) {
+ if (_ao_fat_entry_read(free) == 0) {
next_free = free + 1;
if (next_free >= number_cluster)
next_free = 2;
fsinfo_dirty = 1;
DBG("\tadd cluster. old %08x new %08x\n", last_cluster, free);
if (last_cluster)
- ao_fat_entry_replace(last_cluster, free);
+ _ao_fat_entry_replace(last_cluster, free);
else
first_cluster = free;
last_cluster = free;
#undef next_cluster
DBG("\tlast cluster %08x\n", last_cluster);
/* Mark the new end of the chain */
- ao_fat_entry_replace(last_cluster, AO_FAT_LAST_CLUSTER);
+ _ao_fat_entry_replace(last_cluster, AO_FAT_LAST_CLUSTER);
}
DBG("\tfirst cluster %08x\n", first_cluster);
/* Start using a root directory entry */
static uint8_t *
-ao_fat_root_get(dirent_t e)
+_ao_fat_root_get(dirent_t e)
{
offset_t byte = e * DIRENT_SIZE;
sector_t sector = byte >> SECTOR_SHIFT;
if (fat32) {
cluster_t cluster_distance = sector / sectors_per_cluster;
sector_t sector_index = sector % sectors_per_cluster;
- cluster_t cluster = ao_fat_cluster_seek(root_cluster, cluster_distance);
+ cluster_t cluster = _ao_fat_cluster_seek(root_cluster, cluster_distance);
- if (ao_fat_cluster_valid(cluster))
+ if (_ao_fat_cluster_valid(cluster))
sector = data_start + (cluster-2) * sectors_per_cluster + sector_index;
else
return NULL;
sector = root_start + sector;
}
- buf = ao_fat_sector_get(sector);
+ buf = _ao_fat_sector_get(sector);
if (!buf)
return NULL;
return buf + offset;
/* Finish using a root directory entry, 'w' is 1 if modified */
static void
-ao_fat_root_put(uint8_t *root, dirent_t e, uint8_t write)
+_ao_fat_root_put(uint8_t *root, dirent_t e, uint8_t write)
{
cluster_offset_t offset = ((e * DIRENT_SIZE) & SECTOR_MASK);
uint8_t *buf = root - offset;
- ao_fat_sector_put(buf, write);
+ _ao_fat_sector_put(buf, write);
}
/*
- * ao_fat_root_extend
+ * _ao_fat_root_extend
*
* On FAT32, make the root directory at least 'ents' entries long
*/
static int8_t
-ao_fat_root_extend(dirent_t ents)
+_ao_fat_root_extend(dirent_t ents)
{
offset_t byte_size;
cluster_t cluster_size;
byte_size = (ents + 1) * 0x20;
cluster_size = (byte_size + bytes_per_cluster - 1) / bytes_per_cluster;
- if (ao_fat_cluster_set_size(root_cluster, cluster_size) != AO_FAT_BAD_CLUSTER)
+ if (_ao_fat_cluster_set_size(root_cluster, cluster_size) != AO_FAT_BAD_CLUSTER)
return 1;
return 0;
}
/*
- * ao_fat_setup_partition
+ * _ao_fat_setup_partition
*
* Load the boot block and find the first partition
*/
static uint8_t
-ao_fat_setup_partition(void)
+_ao_fat_setup_partition(void)
{
uint8_t *mbr;
uint8_t *partition;
}
static uint8_t
-ao_fat_setup_fs(void)
+_ao_fat_setup_fs(void)
{
- uint8_t *boot = ao_fat_sector_get(0);
+ uint8_t *boot = _ao_fat_sector_get(0);
uint32_t data_sectors;
if (!boot)
if (boot[0x1fe] != 0x55 || boot[0x1ff] != 0xaa) {
DBG ("Invalid BOOT signature %02x %02x\n",
boot[0x1fe], boot[0x1ff]);
- ao_fat_sector_put(boot, 0);
+ _ao_fat_sector_put(boot, 0);
return AO_FAT_FILESYSTEM_INVALID_BOOT_SIGNATURE;
}
if (get_u16(boot + 0xb) != SECTOR_SIZE) {
DBG ("Invalid sector size %d\n",
get_u16(boot + 0xb));
- ao_fat_sector_put(boot, 0);
+ _ao_fat_sector_put(boot, 0);
return AO_FAT_FILESYSTEM_INVALID_SECTOR_SIZE;
}
root_cluster = get_u32(boot+0x2c);
fsinfo_sector = get_u16(boot + 0x30);
}
- ao_fat_sector_put(boot, 0);
+ _ao_fat_sector_put(boot, 0);
free_count = 0xffffffff;
next_free = 0;
if (fat32 && fsinfo_sector) {
- uint8_t *fsinfo = ao_fat_sector_get(fsinfo_sector);
+ uint8_t *fsinfo = _ao_fat_sector_get(fsinfo_sector);
if (fsinfo) {
free_count = get_u32(fsinfo + 0x1e8);
next_free = get_u32(fsinfo + 0x1ec);
- ao_fat_sector_put(fsinfo, 0);
+ _ao_fat_sector_put(fsinfo, 0);
}
}
static struct ao_fat_dirent ao_file_dirent[AO_FAT_NFILE];
static struct ao_fat_dirent *
-ao_fat_file_dirent_alloc(struct ao_fat_dirent *want)
+_ao_fat_file_dirent_alloc(struct ao_fat_dirent *want)
{
int8_t d;
struct ao_fat_dirent *free = NULL, *dirent;
static struct ao_file ao_file_table[AO_FAT_NFILE];
static int8_t
-ao_fat_fd_alloc(struct ao_fat_dirent *dirent)
+_ao_fat_fd_alloc(struct ao_fat_dirent *dirent)
{
int8_t fd;
for (fd = 0; fd < AO_FAT_NFILE; fd++)
if (!ao_file_table[fd].busy) {
- ao_file_table[fd].dirent = ao_fat_file_dirent_alloc(dirent);
+ ao_file_table[fd].dirent = _ao_fat_file_dirent_alloc(dirent);
ao_file_table[fd].busy = 1;
ao_file_table[fd].offset = 0;
ao_file_table[fd].cluster_offset = 0;
}
static void
-ao_fat_fd_free(int8_t fd)
+_ao_fat_fd_free(int8_t fd)
{
struct ao_file *file = &ao_file_table[fd];
struct ao_fat_dirent *dirent = file->dirent;
}
static struct ao_file *
-ao_fat_fd_to_file(int8_t fd)
+_ao_fat_fd_to_file(int8_t fd)
{
struct ao_file *file;
if (fd < 0 || AO_FAT_NFILE <= fd)
static uint8_t ao_filesystem_status;
static uint8_t
-ao_fat_setup(void)
+_ao_fat_setup(void)
{
if (!ao_filesystem_setup) {
/* Reset open file table */
memset(&ao_file_table, '\0', sizeof (ao_file_table));
- ao_filesystem_status = ao_fat_setup_partition();
+ ao_filesystem_status = _ao_fat_setup_partition();
if (ao_filesystem_status != AO_FAT_FILESYSTEM_SUCCESS)
return ao_filesystem_status;
- ao_filesystem_status = ao_fat_setup_fs();
+ ao_filesystem_status = _ao_fat_setup_fs();
if (ao_filesystem_status != AO_FAT_FILESYSTEM_SUCCESS)
return ao_filesystem_status;
}
*/
static uint32_t
-ao_fat_current_sector(struct ao_file *file)
+_ao_fat_current_sector(struct ao_file *file)
{
cluster_t cluster_offset;
uint32_t sector_offset;
DBG("current sector offset %d size %d\n",
file->offset, file->dirent->size);
- if (file->offset > file->dirent->size) {
+ if (file->offset > (offset_t) file->dirent->size) {
printf ("file offset %d larger than size %d\n",
file->offset, file->dirent->size);
return 0xffffffff;
DBG("\treset to start of file %08x\n", file->cluster);
}
- if (file->cluster_offset + bytes_per_cluster <= file->offset) {
+ if ((offset_t) (file->cluster_offset + bytes_per_cluster) <= file->offset) {
cluster_t cluster_distance;
cluster_offset = sector_offset / sectors_per_cluster;
cluster_distance = cluster_offset - file->cluster_offset / bytes_per_cluster;
DBG("\tseek forward %d clusters\n", cluster_distance);
- cluster = ao_fat_cluster_seek(file->cluster, cluster_distance);
+ cluster = _ao_fat_cluster_seek(file->cluster, cluster_distance);
- if (!ao_fat_cluster_valid(cluster)) {
+ if (!_ao_fat_cluster_valid(cluster)) {
printf ("invalid cluster %08x\n", cluster);
return 0xffffffff;
}
}
/*
- * ao_fat_invaldate_cluster_offset
+ * _ao_fat_invaldate_cluster_offset
*
* When the file size gets shrunk, invalidate
* any file structures referencing clusters beyond that point
*/
static void
-ao_fat_invalidate_cluster_offset(struct ao_fat_dirent *dirent)
+_ao_fat_invalidate_cluster_offset(struct ao_fat_dirent *dirent)
{
int8_t fd;
struct ao_file *file;
if (!file->busy)
continue;
if (file->dirent == dirent) {
- if (file->cluster_offset >= dirent->size) {
+ if (file->cluster_offset >= (offset_t) dirent->size) {
file->cluster_offset = 0;
file->cluster = dirent->cluster;
}
/*
- * ao_fat_set_size
+ * _ao_fat_set_size
*
* Set the size of the current file, truncating or extending
* the cluster chain as needed
*/
static int8_t
-ao_fat_set_size(struct ao_file *file, uint32_t size)
+_ao_fat_set_size(struct ao_file *file, uint32_t size)
{
uint8_t *dent;
cluster_t first_cluster;
DBG ("\tfirst cluster %08x have %d need %d\n", first_cluster, have_clusters, need_clusters);
if (have_clusters != need_clusters) {
- if (file->cluster && size > file->cluster_offset) {
+ if (file->cluster && (offset_t) size > file->cluster_offset) {
cluster_t offset_clusters = (file->cluster_offset + bytes_per_cluster) / bytes_per_cluster;
cluster_t extra_clusters = need_clusters - offset_clusters;
cluster_t next_cluster;
offset_clusters, extra_clusters);
/* Need one more to account for file->cluster, which we already have */
- next_cluster = ao_fat_cluster_set_size(file->cluster, extra_clusters + 1);
+ next_cluster = _ao_fat_cluster_set_size(file->cluster, extra_clusters + 1);
if (next_cluster == AO_FAT_BAD_CLUSTER)
return -AO_FAT_ENOSPC;
} else {
DBG ("\tset size absolute need_clusters %d\n", need_clusters);
- first_cluster = ao_fat_cluster_set_size(first_cluster, need_clusters);
+ first_cluster = _ao_fat_cluster_set_size(first_cluster, need_clusters);
if (first_cluster == AO_FAT_BAD_CLUSTER)
return -AO_FAT_ENOSPC;
DBG ("\tupdate directory size\n");
/* Update the directory entry */
- dent = ao_fat_root_get(file->dirent->entry);
+ dent = _ao_fat_root_get(file->dirent->entry);
if (!dent) {
printf ("dent update failed\n");
return -AO_FAT_EIO;
put_u16(dent + 0x1a, first_cluster);
if (fat32)
put_u16(dent + 0x14, first_cluster >> 16);
- ao_fat_root_put(dent, file->dirent->entry, 1);
+ _ao_fat_root_put(dent, file->dirent->entry, 1);
file->dirent->size = size;
file->dirent->cluster = first_cluster;
if (have_clusters > need_clusters)
- ao_fat_invalidate_cluster_offset(file->dirent);
+ _ao_fat_invalidate_cluster_offset(file->dirent);
DBG ("set size done\n");
return AO_FAT_SUCCESS;
}
/*
- * ao_fat_root_init
+ * _ao_fat_root_init
*
* Initialize a root directory entry
*/
static void
-ao_fat_root_init(uint8_t *dent, char name[11], uint8_t attr)
+_ao_fat_root_init(uint8_t *dent, char name[11], uint8_t attr)
{
+ (void) attr;
memset(dent, '\0', 0x20);
memmove(dent, name, 11);
static void
-ao_fat_dirent_init(struct ao_fat_dirent *dirent, uint8_t *dent, uint16_t entry)
+_ao_fat_dirent_init(struct ao_fat_dirent *dirent, uint8_t *dent, uint16_t entry)
{
memcpy(dirent->name, dent + 0x00, 11);
dirent->attr = dent[0x0b];
}
/*
- * ao_fat_flush_fsinfo
+ * _ao_fat_flush_fsinfo
*
* Write out any fsinfo changes to disk
*/
static void
-ao_fat_flush_fsinfo(void)
+_ao_fat_flush_fsinfo(void)
{
uint8_t *fsinfo;
if (!fsinfo_sector)
return;
- fsinfo = ao_fat_sector_get(fsinfo_sector);
+ fsinfo = _ao_fat_sector_get(fsinfo_sector);
if (fsinfo) {
put_u32(fsinfo + 0x1e8, free_count);
put_u32(fsinfo + 0x1ec, next_free);
- ao_fat_sector_put(fsinfo, 1);
+ _ao_fat_sector_put(fsinfo, 1);
}
}
* Flush any pending I/O to storage
*/
-void
-ao_fat_sync(void)
+static void
+_ao_fat_sync(void)
{
- if (ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
+ if (_ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
return;
- ao_fat_flush_fsinfo();
+ _ao_fat_flush_fsinfo();
ao_bufio_flush();
}
+void
+ao_fat_sync(void)
+{
+ ao_mutex_get(&ao_fat_mutex);
+ _ao_fat_sync();
+ ao_mutex_put(&ao_fat_mutex);
+}
+
/*
* ao_fat_full
*
int8_t
ao_fat_full(void)
{
- if (ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
+ ao_mutex_get(&ao_fat_mutex);
+ if (_ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS) {
+ ao_mutex_put(&ao_fat_mutex);
return 1;
+ }
+ ao_mutex_put(&ao_fat_mutex);
return filesystem_full;
}
+static int8_t
+_ao_fat_readdir(uint16_t *entry, struct ao_fat_dirent *dirent)
+{
+ uint8_t *dent;
+
+ if (_ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
+ return -AO_FAT_EIO;
+
+ for (;;) {
+ dent = _ao_fat_root_get(*entry);
+ if (!dent)
+ return -AO_FAT_EDIREOF;
+
+ if (dent[0] == AO_FAT_DENT_END) {
+ _ao_fat_root_put(dent, *entry, 0);
+ return -AO_FAT_EDIREOF;
+ }
+ if (dent[0] != AO_FAT_DENT_EMPTY && (dent[0xb] & 0xf) != 0xf) {
+ _ao_fat_dirent_init(dirent, dent, *entry);
+ _ao_fat_root_put(dent, *entry, 0);
+ (*entry)++;
+ return AO_FAT_SUCCESS;
+ }
+ _ao_fat_root_put(dent, *entry, 0);
+ (*entry)++;
+ }
+}
+
+int8_t
+ao_fat_readdir(uint16_t *entry, struct ao_fat_dirent *dirent)
+{
+ int8_t status;
+
+ ao_mutex_get(&ao_fat_mutex);
+ status = _ao_fat_readdir(entry, dirent);
+ ao_mutex_put(&ao_fat_mutex);
+ return status;
+}
+
/*
* ao_fat_open
*
* Open an existing file.
*/
-int8_t
-ao_fat_open(char name[11], uint8_t mode)
+static int8_t
+_ao_fat_open(char name[11], uint8_t mode)
{
uint16_t entry = 0;
- struct ao_fat_dirent dirent;
+ static struct ao_fat_dirent dirent;
int8_t status;
- if (ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
+ if (_ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
return -AO_FAT_EIO;
for (;;) {
- status = ao_fat_readdir(&entry, &dirent);
+ status = _ao_fat_readdir(&entry, &dirent);
if (status < 0) {
if (status == -AO_FAT_EDIREOF)
return -AO_FAT_ENOENT;
return -AO_FAT_EPERM;
if (mode > AO_FAT_OPEN_READ && (dirent.attr & AO_FAT_FILE_READ_ONLY))
return -AO_FAT_EACCESS;
- return ao_fat_fd_alloc(&dirent);
+ return _ao_fat_fd_alloc(&dirent);
}
}
return -AO_FAT_ENOENT;
}
+int8_t
+ao_fat_open(char name[11], uint8_t mode)
+{
+ int8_t status;
+
+ ao_mutex_get(&ao_fat_mutex);
+ status = _ao_fat_open(name, mode);
+ ao_mutex_put(&ao_fat_mutex);
+ return status;
+}
+
+/*
+ * ao_fat_close
+ *
+ * Close the currently open file
+ */
+static int8_t
+_ao_fat_close(int8_t fd)
+{
+ struct ao_file *file;
+
+ file = _ao_fat_fd_to_file(fd);
+ if (!file)
+ return -AO_FAT_EBADF;
+
+ _ao_fat_fd_free(fd);
+ _ao_fat_sync();
+ return AO_FAT_SUCCESS;
+}
+
+int8_t
+ao_fat_close(int8_t fd)
+{
+ int8_t status;
+
+ ao_mutex_get(&ao_fat_mutex);
+ status = _ao_fat_close(fd);
+ ao_mutex_put(&ao_fat_mutex);
+ return status;
+}
+
/*
* ao_fat_creat
*
* Open and truncate an existing file or
* create a new file
*/
-int8_t
-ao_fat_creat(char name[11])
+
+static int8_t
+_ao_fat_creat(char name[11])
{
uint16_t entry;
int8_t fd;
uint8_t *dent;
struct ao_file *file;
- if (ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
+ if (_ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
return -AO_FAT_EIO;
- fd = ao_fat_open(name, AO_FAT_OPEN_WRITE);
+ fd = _ao_fat_open(name, AO_FAT_OPEN_WRITE);
if (fd >= 0) {
file = &ao_file_table[fd];
- status = ao_fat_set_size(file, 0);
+ status = _ao_fat_set_size(file, 0);
if (status < 0) {
- ao_fat_close(fd);
+ _ao_fat_close(fd);
fd = status;
}
} else {
if (fd == -AO_FAT_ENOENT) {
entry = 0;
for (;;) {
- dent = ao_fat_root_get(entry);
+ dent = _ao_fat_root_get(entry);
if (!dent) {
- if (ao_fat_root_extend(entry))
+ if (_ao_fat_root_extend(entry))
continue;
fd = -AO_FAT_ENOSPC;
break;
}
if (dent[0] == AO_FAT_DENT_EMPTY || dent[0] == AO_FAT_DENT_END) {
- fd = ao_fat_fd_alloc(NULL);
+ fd = _ao_fat_fd_alloc(NULL);
if (fd < 0) {
- ao_fat_root_put(dent, entry, 0);
+ _ao_fat_root_put(dent, entry, 0);
break;
}
file = &ao_file_table[fd];
/* Initialize the dent */
- ao_fat_root_init(dent, name, AO_FAT_FILE_REGULAR);
+ _ao_fat_root_init(dent, name, AO_FAT_FILE_REGULAR);
/* Now initialize the dirent from the dent */
- ao_fat_dirent_init(file->dirent, dent, entry);
+ _ao_fat_dirent_init(file->dirent, dent, entry);
/* And write the dent to storage */
- ao_fat_root_put(dent, entry, 1);
+ _ao_fat_root_put(dent, entry, 1);
status = -AO_FAT_SUCCESS;
break;
} else {
- ao_fat_root_put(dent, entry, 0);
+ _ao_fat_root_put(dent, entry, 0);
}
entry++;
}
return fd;
}
-/*
- * ao_fat_close
- *
- * Close the currently open file
- */
int8_t
-ao_fat_close(int8_t fd)
+ao_fat_creat(char name[11])
{
- struct ao_file *file = ao_fat_fd_to_file(fd);
- if (!file)
- return -AO_FAT_EBADF;
+ int8_t status;
- ao_fat_fd_free(fd);
- ao_fat_sync();
- return AO_FAT_SUCCESS;
+ ao_mutex_get(&ao_fat_mutex);
+ status = _ao_fat_creat(name);
+ ao_mutex_put(&ao_fat_mutex);
+ return status;
}
/*
void *buf;
offset = file->offset & SECTOR_MASK;
- sector = ao_fat_current_sector(file);
+ sector = _ao_fat_current_sector(file);
if (sector == 0xffffffff) {
- printf ("invalid sector at offset %d\n", file->offset);
return NULL;
}
- buf = ao_fat_sector_get(sector);
+ buf = _ao_fat_sector_get(sector);
if (!buf)
- printf ("sector get failed. Sector %d. Partition end %d\n", sector, partition_end);
+ return NULL;
if (offset + len < SECTOR_SIZE)
*this_time = len;
else
cluster_offset_t offset;
uint8_t *buf;
int ret = 0;
- struct ao_file *file = ao_fat_fd_to_file(fd);
- if (!file)
- return -AO_FAT_EBADF;
+ struct ao_file *file;
- if (file->offset + len > file->dirent->size)
+ ao_mutex_get(&ao_fat_mutex);
+ file = _ao_fat_fd_to_file(fd);
+ if (!file) {
+ ret = -AO_FAT_EBADF;
+ goto done;
+ }
+
+ if (file->offset + len > (offset_t) file->dirent->size)
len = file->dirent->size - file->offset;
if (len < 0)
while (len) {
buf = ao_fat_map_current(file, len, &offset, &this_time);
if (!buf) {
- printf ("map_current failed\n");
ret = -AO_FAT_EIO;
break;
}
memcpy(dst_b, buf + offset, this_time);
- ao_fat_sector_put(buf, 0);
+ _ao_fat_sector_put(buf, 0);
ret += this_time;
len -= this_time;
dst_b += this_time;
file->offset = file->offset + this_time;
}
+done:
+ ao_mutex_put(&ao_fat_mutex);
return ret;
}
cluster_offset_t offset;
uint8_t *buf;
int ret = 0;
- struct ao_file *file = ao_fat_fd_to_file(fd);
- if (!file)
- return -AO_FAT_EBADF;
+ struct ao_file *file;
- if (file->offset + len > file->dirent->size) {
- ret = ao_fat_set_size(file, file->offset + len);
+ ao_mutex_get(&ao_fat_mutex);
+ file = _ao_fat_fd_to_file(fd);
+ if (!file) {
+ ret = -AO_FAT_EBADF;
+ goto done;
+ }
+
+ if (file->offset + len > (offset_t) file->dirent->size) {
+ ret = _ao_fat_set_size(file, file->offset + len);
if (ret < 0)
- return ret;
+ goto done;
}
while (len) {
buf = ao_fat_map_current(file, len, &offset, &this_time);
if (!buf) {
- printf ("map_current failed\n");
ret = -AO_FAT_EIO;
break;
}
memcpy(buf + offset, src_b, this_time);
- ao_fat_sector_put(buf, 1);
+ _ao_fat_sector_put(buf, 1);
ret += this_time;
len -= this_time;
src_b += this_time;
file->offset = file->offset + this_time;
}
+done:
+ ao_mutex_put(&ao_fat_mutex);
return ret;
}
ao_fat_seek(int8_t fd, int32_t pos, uint8_t whence)
{
offset_t new_offset;
- struct ao_file *file = ao_fat_fd_to_file(fd);
- if (!file)
- return -AO_FAT_EBADF;
+ struct ao_file *file;
+ int32_t ret;
+
+ ao_mutex_get(&ao_fat_mutex);
+ file = _ao_fat_fd_to_file(fd);
+ if (!file) {
+ ret = -AO_FAT_EBADF;
+ goto done;
+ }
new_offset = file->offset;
switch (whence) {
new_offset = file->dirent->size + pos;
break;
}
- file->offset = new_offset;
- return file->offset;
+ ret = file->offset = new_offset;
+done:
+ ao_mutex_put(&ao_fat_mutex);
+ return ret;
}
/*
ao_fat_unlink(char name[11])
{
uint16_t entry = 0;
- struct ao_fat_dirent dirent;
+ static struct ao_fat_dirent dirent;
+ int8_t ret;
- if (ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
- return -AO_FAT_EIO;
+ ao_mutex_get(&ao_fat_mutex);
+ if (_ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS) {
+ ret = -AO_FAT_EIO;
+ goto done;
+ }
while (ao_fat_readdir(&entry, &dirent)) {
if (memcmp(name, dirent.name, 11) == 0) {
uint8_t *ent;
uint8_t delete;
- if (AO_FAT_IS_DIR(dirent.attr))
- return -AO_FAT_EISDIR;
- if (!AO_FAT_IS_FILE(dirent.attr))
- return -AO_FAT_EPERM;
+ if (AO_FAT_IS_DIR(dirent.attr)) {
+ ret = -AO_FAT_EISDIR;
+ goto done;
+ }
+ if (!AO_FAT_IS_FILE(dirent.attr)) {
+ ret = -AO_FAT_EPERM;
+ goto done;
+ }
- ao_fat_free_cluster_chain(dirent.cluster);
- next = ao_fat_root_get(dirent.entry + 1);
+ _ao_fat_free_cluster_chain(dirent.cluster);
+ next = _ao_fat_root_get(dirent.entry + 1);
if (next && next[0] != AO_FAT_DENT_END)
delete = AO_FAT_DENT_EMPTY;
else
delete = AO_FAT_DENT_END;
if (next)
- ao_fat_root_put(next, dirent.entry + 1, 0);
- ent = ao_fat_root_get(dirent.entry);
+ _ao_fat_root_put(next, dirent.entry + 1, 0);
+ ent = _ao_fat_root_get(dirent.entry);
if (ent) {
memset(ent, '\0', DIRENT_SIZE);
*ent = delete;
- ao_fat_root_put(ent, dirent.entry, 1);
+ _ao_fat_root_put(ent, dirent.entry, 1);
}
ao_bufio_flush();
- return AO_FAT_SUCCESS;
+ ret = AO_FAT_SUCCESS;
+ goto done;
}
}
- return -AO_FAT_ENOENT;
+ ret = -AO_FAT_ENOENT;
+done:
+ ao_mutex_put(&ao_fat_mutex);
+ return ret;
}
int8_t
ao_fat_rename(char old[11], char new[11])
{
+ (void) old;
+ (void) new;
return -AO_FAT_EIO;
}
-int8_t
-ao_fat_readdir(uint16_t *entry, struct ao_fat_dirent *dirent)
-{
- uint8_t *dent;
-
- if (ao_fat_setup() != AO_FAT_FILESYSTEM_SUCCESS)
- return -AO_FAT_EIO;
-
- for (;;) {
- dent = ao_fat_root_get(*entry);
- if (!dent)
- return -AO_FAT_EDIREOF;
-
- if (dent[0] == AO_FAT_DENT_END) {
- ao_fat_root_put(dent, *entry, 0);
- return -AO_FAT_EDIREOF;
- }
- if (dent[0] != AO_FAT_DENT_EMPTY && (dent[0xb] & 0xf) != 0xf) {
- ao_fat_dirent_init(dirent, dent, *entry);
- ao_fat_root_put(dent, *entry, 0);
- (*entry)++;
- return AO_FAT_SUCCESS;
- }
- ao_fat_root_put(dent, *entry, 0);
- (*entry)++;
- }
-}
-
#if FAT_COMMANDS
static const char *filesystem_errors[] = {
{
uint8_t status;
- status = ao_fat_setup();
+ ao_mutex_get(&ao_fat_mutex);
+ status = _ao_fat_setup();
if (status == AO_FAT_FILESYSTEM_SUCCESS) {
printf ("partition type: %02x\n", partition_type);
printf ("partition start: %08x\n", partition_start);
} else {
printf ("FAT filesystem not available: %s\n", filesystem_errors[status]);
}
+ ao_mutex_put(&ao_fat_mutex);
}
struct ao_fat_attr {
ao_fat_list_cmd(void)
{
uint16_t entry = 0;
- struct ao_fat_dirent dirent;
+ static struct ao_fat_dirent dirent;
int i;
int8_t status;
putchar('.');
for (; i < 11; i++)
putchar(dirent.name[i]);
- for (i = 0; i < NUM_FAT_ATTR; i++)
+ for (i = 0; i < (int) NUM_FAT_ATTR; i++)
putchar (dirent.attr & ao_fat_attr[i].bit ? ao_fat_attr[i].label : ' ');
printf (" @%08x %d\n", dirent.cluster, dirent.size);
}
printf ("readdir failed: %d\n", status);
}
-static uint8_t
+static void
ao_fat_parse_name(char name[11])
{
uint8_t c;
static void
ao_fat_dump_cmd(void)
{
- char name[11];
+ static char name[11];
int8_t fd;
int cnt, i;
- char buf[32];
+ static char buf[32];
ao_fat_parse_name(name);
if (name[0] == '\0') {
static void
ao_fat_write_cmd(void)
{
- char name[11];
+ static char name[11];
int8_t fd;
- int cnt, i;
- char buf[64];
char c;
int status;