1015 lines
23 KiB
Diff
1015 lines
23 KiB
Diff
diff --git a/dfs_yaffs2.c b/dfs_yaffs2.c
|
||
new file mode 100644
|
||
index 0000000..4b056ae
|
||
--- /dev/null
|
||
+++ b/dfs_yaffs2.c
|
||
@@ -0,0 +1,405 @@
|
||
+/*
|
||
+ * File : rtthread.h
|
||
+ * This file is part of RT-Thread RTOS
|
||
+ * COPYRIGHT (C) 2006-2011, RT-Thread Development Team
|
||
+ *
|
||
+ * The license and distribution terms for this file may be
|
||
+ * found in the file LICENSE in this distribution or at
|
||
+ * http://www.rt-thread.org/license/LICENSE.
|
||
+ *
|
||
+ * Change Logs:
|
||
+ * Date Author Notes
|
||
+ * 2011-10-22 prife the first version
|
||
+ * 2012-04-14 prife use mtd device interface
|
||
+*/
|
||
+#include <rtthread.h>
|
||
+#include <rtdevice.h>
|
||
+
|
||
+#include "yaffsfs.h"
|
||
+#include "yaffs_nandif.h"
|
||
+
|
||
+#include <dfs_fs.h>
|
||
+#include <dfs_def.h>
|
||
+
|
||
+#define YAFFS_FILE_PATH_MAX 256 /* the longest file path */
|
||
+
|
||
+#define NAND_DEVICE_PART_MAX 4 /* the max partitions on a nand deivce*/
|
||
+struct device_part
|
||
+{
|
||
+ struct rt_mtd_nand_device *dev;
|
||
+ ynandif_Geometry g;
|
||
+};
|
||
+static struct device_part nand_part[NAND_DEVICE_PART_MAX] = {0};
|
||
+
|
||
+extern int yaffs_start(const char * mountpath, ynandif_Geometry * g);
|
||
+extern void yaffs_config(ynandif_Geometry * g, struct rt_mtd_nand_device * dev);
|
||
+
|
||
+static int dfs_yaffs_mount(struct dfs_filesystem* fs,
|
||
+ unsigned long rwflag,
|
||
+ const void* data)
|
||
+{
|
||
+ unsigned index;
|
||
+ ynandif_Geometry *g;
|
||
+
|
||
+ /*1. find a empty entry in partition table */
|
||
+ for (index = 0; index < NAND_DEVICE_PART_MAX ; index ++)
|
||
+ {
|
||
+ if (nand_part[index].dev == RT_NULL)
|
||
+ break;
|
||
+ }
|
||
+ if (index == NAND_DEVICE_PART_MAX)
|
||
+ return -DFS_STATUS_ENOSPC;
|
||
+
|
||
+ /*2. fill nand_part*/
|
||
+ nand_part[index].dev = RT_MTD_NAND_DEVICE(fs->dev_id);
|
||
+ yaffs_config(&nand_part[index].g, RT_MTD_NAND_DEVICE(fs->dev_id));
|
||
+
|
||
+ /*3. start up yaffs2 */
|
||
+ yaffs_start(fs->path, &nand_part[index].g);
|
||
+ if (yaffs_mount(fs->path) < 0)
|
||
+ {
|
||
+ return yaffsfs_GetLastError();
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_unmount(struct dfs_filesystem* fs)
|
||
+{
|
||
+ unsigned index;
|
||
+ if (yaffs_unmount(fs->path) < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+
|
||
+ /* find device index, then umount it */
|
||
+ for (index = 0; index < NAND_DEVICE_PART_MAX; index++)
|
||
+ {
|
||
+ if (nand_part[index].dev == RT_MTD_NAND_DEVICE(fs->dev_id))
|
||
+ {
|
||
+ nand_part[index].dev = RT_NULL;
|
||
+ return DFS_STATUS_OK;
|
||
+ }
|
||
+ }
|
||
+ return -DFS_STATUS_ENOENT;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_mkfs(const char* device_name)
|
||
+{
|
||
+ /* just erase all blocks on this nand partition */
|
||
+ return -DFS_STATUS_ENOSYS;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_statfs(struct dfs_filesystem* fs,
|
||
+ struct statfs *buf)
|
||
+{
|
||
+ struct rt_mtd_nand_device * mtd = RT_MTD_NAND_DEVICE(fs->dev_id);
|
||
+
|
||
+ RT_ASSERT(mtd != RT_NULL);
|
||
+
|
||
+ buf->f_bsize = mtd->page_size;
|
||
+ buf->f_blocks = (mtd->block_size)/(mtd->page_size)*
|
||
+ (mtd->block_start - mtd->block_end + 1);
|
||
+ buf->f_bfree = yaffs_freespace(fs->path) / mtd->page_size;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_open(struct dfs_fd* file)
|
||
+{
|
||
+ int fd;
|
||
+ int oflag;
|
||
+ int result;
|
||
+
|
||
+ oflag = file->flags;
|
||
+ if (oflag & DFS_O_DIRECTORY) /* operations about dir */
|
||
+ {
|
||
+ yaffs_DIR * dir;
|
||
+ if (oflag & DFS_O_CREAT) /* create a dir*/
|
||
+ {
|
||
+ result = yaffs_mkdir(file->path, 0x777); /* the second args not supported by rtt */
|
||
+ if (result < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+ }
|
||
+ /* open dir */
|
||
+ dir = yaffs_opendir(file->path);
|
||
+ if (dir == RT_NULL)
|
||
+ return yaffsfs_GetLastError();
|
||
+ /* save this pointer,will used by dfs_yaffs_getdents*/
|
||
+ file->data = dir;
|
||
+ return 0;
|
||
+ }
|
||
+ /* regular file operations */
|
||
+ fd = yaffs_open(file->path, oflag, S_IREAD | S_IWRITE);
|
||
+ if (fd < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+
|
||
+ /* save this pointer, it will be used when calling read()<29><>write(),
|
||
+ flush(), lessk(), and will be free when calling close()*/
|
||
+ file->data = (void *)fd;
|
||
+ file->pos = yaffs_lseek(fd,0,SEEK_CUR);
|
||
+ file->size = yaffs_lseek(fd,0,SEEK_END);
|
||
+ yaffs_lseek(fd, file->pos, SEEK_SET);
|
||
+
|
||
+ if (oflag & DFS_O_APPEND)
|
||
+ {
|
||
+ file->pos = file->size;
|
||
+ file->size = yaffs_lseek(fd,0,SEEK_END);
|
||
+ }
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_close(struct dfs_fd* file)
|
||
+{
|
||
+ int oflag;
|
||
+ int fd;
|
||
+
|
||
+ oflag = file->flags;
|
||
+ if (oflag & DFS_O_DIRECTORY) /* operations about dir */
|
||
+ {
|
||
+ if (yaffs_closedir((yaffs_DIR *)(file->data)) < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+ return 0;
|
||
+ }
|
||
+ /* regular file operations */
|
||
+ fd = (int)(file->data);
|
||
+
|
||
+ if (yaffs_close(fd) == 0)
|
||
+ return 0;
|
||
+
|
||
+ /* release memory */
|
||
+ return yaffsfs_GetLastError();
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_ioctl(struct dfs_fd* file, int cmd, void* args)
|
||
+{
|
||
+ return -DFS_STATUS_ENOSYS;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_read(struct dfs_fd* file, void* buf, rt_size_t len)
|
||
+{
|
||
+ int fd;
|
||
+ int char_read;
|
||
+
|
||
+ fd = (int)(file->data);
|
||
+ char_read = yaffs_read(fd, buf, len);
|
||
+ if (char_read < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+
|
||
+ /* update position */
|
||
+ file->pos = yaffs_lseek(fd, 0, SEEK_CUR);
|
||
+ return char_read;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_write(struct dfs_fd* file,
|
||
+ const void* buf,
|
||
+ rt_size_t len)
|
||
+{
|
||
+ int fd;
|
||
+ int char_write;
|
||
+
|
||
+ fd = (int)(file->data);
|
||
+
|
||
+ char_write = yaffs_write(fd, buf, len);
|
||
+ if (char_write < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+
|
||
+ /* update position */
|
||
+ file->pos = yaffs_lseek(fd, 0, SEEK_CUR);
|
||
+ return char_write;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_flush(struct dfs_fd* file)
|
||
+{
|
||
+ int fd;
|
||
+ int result;
|
||
+
|
||
+ fd = (int)(file->data);
|
||
+
|
||
+ result = yaffs_flush(fd);
|
||
+ if (result < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_lseek(struct dfs_fd* file,
|
||
+ rt_off_t offset)
|
||
+{
|
||
+ int fd;
|
||
+ int result;
|
||
+
|
||
+ fd = (int)(file->data);
|
||
+
|
||
+ /* set offset as current offset */
|
||
+ result = yaffs_lseek(fd, offset, SEEK_SET);
|
||
+ if (result < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+ return result;
|
||
+}
|
||
+
|
||
+/* return the size of struct dirent*/
|
||
+static int dfs_yaffs_getdents(struct dfs_fd* file,
|
||
+ struct dirent* dirp,
|
||
+ rt_uint32_t count)
|
||
+{
|
||
+ rt_uint32_t index;
|
||
+ char * file_path;
|
||
+ struct dirent* d;
|
||
+ yaffs_DIR* dir;
|
||
+ struct yaffs_dirent * yaffs_d;
|
||
+
|
||
+ dir = (yaffs_DIR*)(file->data);
|
||
+ RT_ASSERT(dir != RT_NULL);
|
||
+
|
||
+ /* make integer count, usually count is 1 */
|
||
+ count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
|
||
+ if (count == 0) return -DFS_STATUS_EINVAL;
|
||
+
|
||
+ /* allocate file name */
|
||
+ file_path = rt_malloc(YAFFS_FILE_PATH_MAX);
|
||
+ if (file_path == RT_NULL)
|
||
+ return -DFS_STATUS_ENOMEM;
|
||
+
|
||
+ index = 0;
|
||
+ /* usually, the while loop should only be looped only once! */
|
||
+ while (1)
|
||
+ {
|
||
+ struct yaffs_stat s;
|
||
+
|
||
+ d = dirp + index;
|
||
+
|
||
+ yaffs_d = yaffs_readdir(dir);
|
||
+ if (yaffs_d == RT_NULL)
|
||
+ {
|
||
+ if (yaffsfs_GetLastError() == EBADF)
|
||
+ return -DFS_STATUS_EBADF;
|
||
+
|
||
+ rt_free(file_path);
|
||
+ return -1; /* a general error */
|
||
+ }
|
||
+
|
||
+ rt_snprintf(file_path, YAFFS_FILE_PATH_MAX, "%s/%s", file->path, yaffs_d->d_name);
|
||
+
|
||
+ yaffs_lstat(file_path, &s);
|
||
+ switch(s.st_mode & S_IFMT)
|
||
+ {
|
||
+ case S_IFREG: d->d_type = DFS_DT_REG; break;
|
||
+
|
||
+ case S_IFDIR: d->d_type = DFS_DT_DIR; break;
|
||
+
|
||
+ case S_IFLNK:
|
||
+ default: d->d_type = DFS_DT_UNKNOWN; break;
|
||
+ }
|
||
+
|
||
+ /* write the rest feilds of struct dirent* dirp */
|
||
+ d->d_namlen = rt_strlen(yaffs_d->d_name);
|
||
+ d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
|
||
+ rt_strncpy(d->d_name, yaffs_d->d_name, rt_strlen(yaffs_d->d_name) + 1);
|
||
+
|
||
+ index ++;
|
||
+ if (index * sizeof(struct dirent) >= count)
|
||
+ break;
|
||
+ }
|
||
+
|
||
+ /* free file name buf */
|
||
+ rt_free(file_path);
|
||
+
|
||
+ if (index == 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+
|
||
+ return index * sizeof(struct dirent);
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_unlink(struct dfs_filesystem* fs, const char* path)
|
||
+{
|
||
+ int result;
|
||
+ struct yaffs_stat s;
|
||
+
|
||
+ /* judge file type, dir is to be delete by yaffs_rmdir, others by yaffs_unlink */
|
||
+ if (yaffs_lstat(path, &s) < 0)
|
||
+ {
|
||
+ return yaffsfs_GetLastError();
|
||
+ }
|
||
+
|
||
+ switch(s.st_mode & S_IFMT)
|
||
+ {
|
||
+ case S_IFREG:
|
||
+ result = yaffs_unlink(path);
|
||
+ break;
|
||
+ case S_IFDIR:
|
||
+ result = yaffs_rmdir(path);
|
||
+ break;
|
||
+ default:
|
||
+ /* unknown file type */
|
||
+ return -1;
|
||
+ }
|
||
+ if (result < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_rename(struct dfs_filesystem* fs,
|
||
+ const char* oldpath,
|
||
+ const char* newpath)
|
||
+{
|
||
+ int result;
|
||
+
|
||
+ result = yaffs_rename(oldpath, newpath);
|
||
+
|
||
+ if (result < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static int dfs_yaffs_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
|
||
+{
|
||
+ int result;
|
||
+ struct yaffs_stat s;
|
||
+ struct rt_mtd_nand_device * mtd;
|
||
+
|
||
+ result = yaffs_stat(path, &s);
|
||
+ if (result < 0)
|
||
+ return yaffsfs_GetLastError();
|
||
+
|
||
+ /* convert to dfs stat structure */
|
||
+ st->st_dev = 0;
|
||
+ st->st_mode = s.st_mode;
|
||
+ st->st_size = s.st_size;
|
||
+ st->st_mtime = s.yst_mtime;
|
||
+
|
||
+ mtd = RT_MTD_NAND_DEVICE(fs->dev_id);
|
||
+ st->st_blksize = mtd->page_size;
|
||
+
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+static const struct dfs_filesystem_operation dfs_yaffs_ops =
|
||
+{
|
||
+ "yaffs2", /* file system type: yaffs2 */
|
||
+#if RTTHREAD_VERSION >= 10100
|
||
+ DFS_FS_FLAG_FULLPATH,
|
||
+#else
|
||
+#error "yaffs2 can only work with rtthread whose version should >= 1.01\n"
|
||
+#endif
|
||
+ dfs_yaffs_mount,
|
||
+ dfs_yaffs_unmount,
|
||
+ dfs_yaffs_mkfs,
|
||
+ dfs_yaffs_statfs,
|
||
+
|
||
+ dfs_yaffs_open,
|
||
+ dfs_yaffs_close,
|
||
+ dfs_yaffs_ioctl,
|
||
+ dfs_yaffs_read,
|
||
+ dfs_yaffs_write,
|
||
+ dfs_yaffs_flush,
|
||
+ dfs_yaffs_lseek,
|
||
+ dfs_yaffs_getdents,
|
||
+ dfs_yaffs_unlink,
|
||
+ dfs_yaffs_stat,
|
||
+ dfs_yaffs_rename,
|
||
+};
|
||
+
|
||
+int dfs_yaffs_init(void)
|
||
+{
|
||
+ /* register fatfs file system */
|
||
+ dfs_register(&dfs_yaffs_ops);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
diff --git a/yaffs/direct/yaffs_list.h b/yaffs/direct/yaffs_list.h
|
||
index f1c5254..17044f5 100644
|
||
--- a/yaffs/direct/yaffs_list.h
|
||
+++ b/yaffs/direct/yaffs_list.h
|
||
@@ -39,7 +39,7 @@ struct list_head {
|
||
|
||
/* Initialise a static list */
|
||
#define LIST_HEAD(name) \
|
||
-struct list_head name = { &(name), &(name)}
|
||
+static struct list_head name = { &(name), &(name)}
|
||
|
||
|
||
|
||
diff --git a/yaffs/direct/yaffs_nandif.c b/yaffs/direct/yaffs_nandif.c
|
||
index b93b55a..3fae80e 100644
|
||
--- a/yaffs/direct/yaffs_nandif.c
|
||
+++ b/yaffs/direct/yaffs_nandif.c
|
||
@@ -18,7 +18,6 @@
|
||
#include "yaffs_nandif.h"
|
||
#include "yaffs_packedtags2.h"
|
||
|
||
-#include "yramsim.h"
|
||
|
||
#include "yaffs_trace.h"
|
||
#include "yaffsfs.h"
|
||
@@ -216,8 +215,8 @@ struct yaffs_dev *
|
||
yaffs_add_dev_from_geometry(const YCHAR *name,
|
||
const ynandif_Geometry *geometry)
|
||
{
|
||
- YCHAR *clonedName = malloc(sizeof(YCHAR) * (strnlen(name,YAFFS_MAX_NAME_LENGTH)+1));
|
||
- struct yaffs_dev *dev = malloc(sizeof(struct yaffs_dev));
|
||
+ YCHAR *clonedName = kmalloc(sizeof(YCHAR) * (strnlen(name,YAFFS_MAX_NAME_LENGTH)+1), GFP_NOFS);
|
||
+ struct yaffs_dev *dev = kmalloc(sizeof(struct yaffs_dev), GFP_NOFS);
|
||
|
||
if(dev && clonedName){
|
||
memset(dev,0,sizeof(struct yaffs_dev));
|
||
@@ -242,16 +241,17 @@ struct yaffs_dev *
|
||
dev->param.n_reserved_blocks = 5;
|
||
dev->driver_context = (void *)geometry;
|
||
|
||
+ /* save rt_mtd_nand_device * dev*/
|
||
+ dev->os_context = (void *)(geometry->privateData);
|
||
yaffs_add_device(dev);
|
||
|
||
return dev;
|
||
}
|
||
|
||
if(dev)
|
||
- free(dev);
|
||
+ kfree(dev);
|
||
if(clonedName)
|
||
- free(clonedName);
|
||
+ kfree(clonedName);
|
||
|
||
return NULL;
|
||
}
|
||
-
|
||
diff --git a/yaffs/direct/ydirectenv.h b/yaffs/direct/ydirectenv.h
|
||
index 7860b84..5add3ec 100644
|
||
--- a/yaffs/direct/ydirectenv.h
|
||
+++ b/yaffs/direct/ydirectenv.h
|
||
@@ -22,16 +22,13 @@
|
||
|
||
// Direct interface
|
||
|
||
-#include "stdlib.h"
|
||
-#include "stdio.h"
|
||
+#include <rtthread.h>
|
||
#include "string.h"
|
||
+
|
||
#include "yaffs_osglue.h"
|
||
#include "yaffs_hweight.h"
|
||
|
||
-#include "assert.h"
|
||
-#define BUG() assert(0)
|
||
-//#define BUG() do { *((int *)0) =1;} while(0)
|
||
-
|
||
+#define BUG() RT_ASSERT(0)
|
||
|
||
#define YCHAR char
|
||
#define YUCHAR unsigned char
|
||
@@ -47,30 +44,24 @@ void yaffs_qsort(void *aa, size_t n, size_t es,
|
||
|
||
#define YAFFS_PATH_DIVIDERS "/"
|
||
|
||
-#ifdef NO_inline
|
||
-#define inline
|
||
-#else
|
||
-#define inline __inline__
|
||
-#endif
|
||
-
|
||
-#define kmalloc(x,flags) yaffsfs_malloc(x)
|
||
+#define GFP_NOFS 0
|
||
+#define kmalloc(x, y) yaffsfs_malloc(x)
|
||
#define kfree(x) yaffsfs_free(x)
|
||
#define vmalloc(x) yaffsfs_malloc(x)
|
||
-#define vfree(x) yaffsfs_free(x)
|
||
+#define vfree(x) yaffsfs_free(x)
|
||
+#define printf rt_kprintf
|
||
|
||
#define cond_resched() do {} while(0)
|
||
|
||
#define yaffs_trace(msk, fmt, ...) do { \
|
||
if(yaffs_trace_mask & (msk)) \
|
||
- printf("yaffs: " fmt "\n", ##__VA_ARGS__); \
|
||
+ rt_kprintf("yaffs: " fmt "\n", ##__VA_ARGS__); \
|
||
} while(0)
|
||
|
||
|
||
#define YAFFS_LOSTNFOUND_NAME "lost+found"
|
||
#define YAFFS_LOSTNFOUND_PREFIX "obj"
|
||
|
||
-#include "yaffscfg.h"
|
||
-
|
||
#define Y_CURRENT_TIME yaffsfs_CurrentTime()
|
||
#define Y_TIME_CONVERT(x) x
|
||
|
||
@@ -79,8 +70,6 @@ void yaffs_qsort(void *aa, size_t n, size_t es,
|
||
|
||
#include "yaffs_list.h"
|
||
|
||
-#include "yaffsfs.h"
|
||
-
|
||
#endif
|
||
|
||
|
||
diff --git a/yaffs/direct/yportenv.h b/yaffs/direct/yportenv.h
|
||
index 939cd3a..f693c16 100644
|
||
--- a/yaffs/direct/yportenv.h
|
||
+++ b/yaffs/direct/yportenv.h
|
||
@@ -17,36 +17,146 @@
|
||
#ifndef __YPORTENV_H__
|
||
#define __YPORTENV_H__
|
||
|
||
+#include <dfs_posix.h>
|
||
+
|
||
+#define CONFIG_YAFFS_DIRECT
|
||
+#define CONFIG_YAFFS_PROVIDE_DEFS
|
||
+#define CONFIG_YAFFSFS_PROVIDE_VALUES
|
||
+
|
||
+#ifdef NO_inline
|
||
+ #define inline
|
||
+#else
|
||
+ #ifdef __CC_ARM
|
||
+ #define inline __inline
|
||
+ #elif defined (__GNUC__) /* GNU GCC Compiler */
|
||
+ #define inline __inline
|
||
+ #else
|
||
+ #error "Please set a macro inline with a valid args"
|
||
+ #endif
|
||
+#endif
|
||
+
|
||
+#if defined(__CC_ARM)
|
||
+ #ifdef RT_USING_NEWLIB
|
||
+ #error "error: when use armcc, please Don't USE NEWLIB!!!"
|
||
+ #endif
|
||
+
|
||
+ #ifndef off_t
|
||
+ typedef long off_t;
|
||
+ #endif
|
||
+
|
||
+ #ifndef loff_t
|
||
+ typedef unsigned long loff_t;
|
||
+ #endif
|
||
+
|
||
+ #ifndef dev_t
|
||
+ typedef long dev_t;
|
||
+ #endif
|
||
+
|
||
+ #ifndef mode_t
|
||
+ typedef int mode_t;
|
||
+ #endif
|
||
+
|
||
+ /* just like strlen(3), but cap the number of bytes we count */
|
||
+ rt_inline size_t strnlen(const char *s, size_t max) {
|
||
+ register const char *p;
|
||
+ for(p = s; *p && max--; ++p);
|
||
+ return(p - s);
|
||
+ }
|
||
+
|
||
+#elif defined (__GNUC__) && !defined(__CC_ARM)
|
||
+
|
||
+ #ifndef loff_t
|
||
+ typedef unsigned long loff_t;
|
||
+ #endif
|
||
+
|
||
+ #ifndef dev_t
|
||
+ typedef long dev_t;
|
||
+ #endif
|
||
+#endif
|
||
|
||
/* Definition of types */
|
||
typedef unsigned char u8;
|
||
typedef unsigned short u16;
|
||
typedef unsigned u32;
|
||
-
|
||
-
|
||
-#ifndef WIN32
|
||
-#include <sys/stat.h>
|
||
-#endif
|
||
-
|
||
+
|
||
+#ifndef S_ISDIR
|
||
+ #ifndef _DEV_T_DEFINED
|
||
+ typedef unsigned int _dev_t; /* device code */
|
||
+ #if !__STDC__
|
||
+ /* Non-ANSI name for compatibility */
|
||
+ typedef unsigned int dev_t;
|
||
+ #endif
|
||
+
|
||
+ #define _DEV_T_DEFINED
|
||
+ #endif
|
||
+
|
||
+ #define __S_IFMT 0170000 /* These bits determine file type. */
|
||
+ /* File types. */
|
||
+ #define __S_IFDIR 0040000 /* Directory. */
|
||
+ #define __S_IFCHR 0020000 /* Character device. */
|
||
+ #define __S_IFBLK 0060000 /* Block device. */
|
||
+ #define __S_IFREG 0100000 /* Regular file. */
|
||
+ #define __S_IFIFO 0010000 /* FIFO. */
|
||
+ #define __S_IFLNK 0120000 /* Symbolic link. */
|
||
+ #define __S_IFSOCK 0140000 /* Socket. */
|
||
+
|
||
+ /* Protection bits. */
|
||
+ #define __S_ISUID 04000 /* Set user ID on execution. */
|
||
+ #define __S_ISGID 02000 /* Set group ID on execution. */
|
||
+ #define __S_ISVTX 01000 /* Save swapped text after use (sticky). */
|
||
+ #define __S_IREAD 0400 /* Read by owner. */
|
||
+ #define __S_IWRITE 0200 /* Write by owner. */
|
||
+ #define __S_IEXEC 0100 /* Execute by owner. */
|
||
+ #define __S_ISTYPE(mode, mask) (((mode) & __S_IFMT) == (mask))
|
||
+
|
||
+ #define S_ISDIR(mode) __S_ISTYPE((mode), __S_IFDIR)
|
||
+ #define S_ISCHR(mode) __S_ISTYPE((mode), __S_IFCHR)
|
||
+ #define S_ISBLK(mode) __S_ISTYPE((mode), __S_IFBLK)
|
||
+ #define S_ISREG(mode) __S_ISTYPE((mode), __S_IFREG)
|
||
+ #define S_ISSOCK(mode) __S_ISTYPE((mode), __S_IFSOCK)
|
||
+ #define S_ISFIFO(mode) __S_ISTYPE((mode), __S_IFSOCK)
|
||
+ #define S_IRUSR __S_IREAD // Read by owner.
|
||
+ #define S_IWUSR __S_IWRITE // Write by owner.
|
||
+ #define S_IXUSR __S_IEXEC // Execute by owner.
|
||
+ #define S_IREAD S_IRUSR
|
||
+ #define S_IWRITE S_IWUSR
|
||
+ #define S_IEXEC S_IXUSR
|
||
+ #define S_IFDIR __S_IFDIR
|
||
+#endif
|
||
|
||
#ifdef CONFIG_YAFFS_PROVIDE_DEFS
|
||
/* File types */
|
||
|
||
+#ifndef DT_UNKNOWN
|
||
+ #define DT_UNKNOWN 0
|
||
+#endif
|
||
+#ifndef DT_FIFO
|
||
+ #define DT_FIFO 1
|
||
+#endif
|
||
|
||
-#define DT_UNKNOWN 0
|
||
-#define DT_FIFO 1
|
||
-#define DT_CHR 2
|
||
-#define DT_DIR 4
|
||
-#define DT_BLK 6
|
||
-#define DT_REG 8
|
||
-#define DT_LNK 10
|
||
-#define DT_SOCK 12
|
||
-#define DT_WHT 14
|
||
-
|
||
+#ifndef DT_CHR
|
||
+ #define DT_CHR 2
|
||
+#endif
|
||
|
||
-#ifndef WIN32
|
||
-#include <sys/stat.h>
|
||
+#ifndef DT_DIR
|
||
+ #define DT_DIR 4
|
||
+#endif
|
||
+#ifndef DT_BLK
|
||
+ #define DT_BLK 6
|
||
+#endif
|
||
+#ifndef DT_REG
|
||
+ #define DT_REG 8
|
||
#endif
|
||
+#ifndef DT_LNK
|
||
+ #define DT_LNK 10
|
||
+#endif
|
||
+#ifndef DT_SOCK
|
||
+ #define DT_SOCK 12
|
||
+#endif
|
||
+#ifndef DT_WHT
|
||
+ #define DT_WHT 14
|
||
+#endif
|
||
+
|
||
|
||
/*
|
||
* Attribute flags.
|
||
@@ -75,7 +185,6 @@ struct iattr {
|
||
#endif
|
||
|
||
|
||
-
|
||
#if defined CONFIG_YAFFS_WINCE
|
||
|
||
#include "ywinceenv.h"
|
||
@@ -267,9 +376,17 @@ struct iattr {
|
||
#endif
|
||
|
||
#else
|
||
-#include <errno.h>
|
||
-#include <sys/stat.h>
|
||
-#include <fcntl.h>
|
||
+//#include <errno.h>
|
||
+//#include <sys/stat.h>
|
||
+//#include <fcntl.h>
|
||
+#ifndef XATTR_CREATE
|
||
+#define XATTR_CREATE 1
|
||
+#endif
|
||
+
|
||
+#ifndef XATTR_REPLACE
|
||
+#define XATTR_REPLACE 2
|
||
+#endif
|
||
+
|
||
#endif
|
||
|
||
#endif
|
||
diff --git a/yaffs_nandcfg.c b/yaffs_nandcfg.c
|
||
new file mode 100644
|
||
index 0000000..099fa38
|
||
--- /dev/null
|
||
+++ b/yaffs_nandcfg.c
|
||
@@ -0,0 +1,149 @@
|
||
+#include <rtthread.h>
|
||
+#include <rtdevice.h>
|
||
+#include <dfs_fs.h>
|
||
+#include <dfs_def.h>
|
||
+
|
||
+#include "yaffsfs.h"
|
||
+#include "yaffs_nandif.h"
|
||
+#include "yaffs_trace.h"
|
||
+
|
||
+/*
|
||
+ * RT-Thread Device Interface for yaffs
|
||
+ */
|
||
+static int nand_init(struct yaffs_dev *dev)
|
||
+{
|
||
+ return YAFFS_OK;
|
||
+}
|
||
+
|
||
+static int nand_deinit(struct yaffs_dev *dev)
|
||
+{
|
||
+ return YAFFS_OK;
|
||
+}
|
||
+
|
||
+/* if block is good, return YAFFS_OK, else return YAFFS_FAIL */
|
||
+static int nand_checkblock(struct yaffs_dev *dev, unsigned block)
|
||
+{
|
||
+ rt_err_t res;
|
||
+ res = rt_mtd_nand_check_block(RT_MTD_NAND_DEVICE(dev->os_context), block);
|
||
+ return res == RT_EOK ? YAFFS_OK : YAFFS_FAIL;
|
||
+}
|
||
+static int nand_markbadblk(struct yaffs_dev *dev, unsigned block)
|
||
+{
|
||
+ rt_err_t res;
|
||
+ res = rt_mtd_nand_mark_badblock(RT_MTD_NAND_DEVICE(dev->os_context), block);
|
||
+ return res == RT_EOK ? YAFFS_OK : YAFFS_FAIL;
|
||
+}
|
||
+
|
||
+static int nand_eraseblock(struct yaffs_dev *dev, unsigned block)
|
||
+{
|
||
+ int res;
|
||
+ res = rt_mtd_nand_erase_block(RT_MTD_NAND_DEVICE(dev->os_context), block);
|
||
+ return res == RT_EOK ? YAFFS_OK : YAFFS_FAIL;
|
||
+}
|
||
+
|
||
+static int nand_readpage(
|
||
+ struct yaffs_dev *dev,
|
||
+ unsigned page,
|
||
+ unsigned char *data, unsigned data_len, /* page data */
|
||
+ unsigned char *spare, unsigned spare_len,/* page spare */
|
||
+ int *ecc_status)
|
||
+{
|
||
+ int res;
|
||
+ unsigned char spare_buf[64];
|
||
+
|
||
+ res = rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->os_context),
|
||
+ page, data, data_len, spare_buf, spare_len + 5);
|
||
+ rt_memcpy(spare, spare_buf + 5, spare_len);
|
||
+ if (res == 0)
|
||
+ *ecc_status = 0;
|
||
+ else if (res == -1)
|
||
+ *ecc_status = 1;
|
||
+ else
|
||
+ *ecc_status = -1;
|
||
+
|
||
+ return YAFFS_OK;
|
||
+}
|
||
+
|
||
+static int nand_writepage(
|
||
+ struct yaffs_dev *dev,
|
||
+ unsigned page,
|
||
+ const unsigned char *data, unsigned data_len, /* page data */
|
||
+ const unsigned char *spare, unsigned spare_len) /* page spare */
|
||
+{
|
||
+ int res;
|
||
+ unsigned char spare_buf[64]; //not use malloc, this can be faster
|
||
+ rt_memset(spare_buf, 0xFF, sizeof(spare_buf));
|
||
+ rt_memcpy(spare_buf+5, spare, spare_len);
|
||
+
|
||
+ res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->os_context),
|
||
+ page, data, data_len, spare_buf, spare_len + 5);
|
||
+ if (res != RT_EOK)
|
||
+ goto __error;
|
||
+
|
||
+ return YAFFS_OK;
|
||
+
|
||
+__error:
|
||
+ return YAFFS_FAIL;
|
||
+}
|
||
+
|
||
+
|
||
+/*
|
||
+ * yaffs2 configuration
|
||
+ */
|
||
+#define CONFIG_YAFFS_ECC_MODE 1 //1 use ecc, 0 no ecc
|
||
+#define CONFIG_YAFFS_INBAND_TAGS 0 //1 use in band tags, 0-no in band tags
|
||
+#define CONFIG_YAFFS_USE_YAFFS2 1 //1 yaffs2, 0-yaffs1
|
||
+
|
||
+void yaffs_config(ynandif_Geometry * g, struct rt_mtd_nand_device * dev)
|
||
+{
|
||
+ rt_memset(g,0,sizeof(ynandif_Geometry));
|
||
+
|
||
+ g->start_block = dev->block_start;
|
||
+ g->end_block = dev->block_end;
|
||
+ g->dataSize = dev->page_size;
|
||
+ g->spareSize = dev->oob_size;
|
||
+ g->pagesPerBlock = dev->block_size / dev->page_size;
|
||
+
|
||
+ g->hasECC = CONFIG_YAFFS_ECC_MODE;
|
||
+ g->inband_tags = CONFIG_YAFFS_INBAND_TAGS;
|
||
+ g->useYaffs2 = CONFIG_YAFFS_USE_YAFFS2;
|
||
+
|
||
+ g->privateData = dev;//will be copy to dev->os_context.
|
||
+
|
||
+ g->initialise = nand_init;
|
||
+ g->deinitialise = nand_deinit;
|
||
+ g->readChunk = nand_readpage;
|
||
+ g->writeChunk = nand_writepage;
|
||
+ g->eraseBlock = nand_eraseblock;
|
||
+ g->checkBlockOk = nand_checkblock;
|
||
+ g->markBlockBad = nand_markbadblk;
|
||
+}
|
||
+
|
||
+static struct yaffs_dev *ynand_CreatePart(const YCHAR *name, ynandif_Geometry * g)
|
||
+{
|
||
+ return yaffs_add_dev_from_geometry(name, g);
|
||
+}
|
||
+
|
||
+/* configuration for yaffs's log */
|
||
+unsigned yaffs_trace_mask =
|
||
+
|
||
+ YAFFS_TRACE_SCAN |
|
||
+ YAFFS_TRACE_GC |
|
||
+ YAFFS_TRACE_ERASE |
|
||
+ YAFFS_TRACE_ERROR |
|
||
+ YAFFS_TRACE_TRACING |
|
||
+ YAFFS_TRACE_ALLOCATE |
|
||
+ YAFFS_TRACE_BAD_BLOCKS |
|
||
+ YAFFS_TRACE_VERIFY |
|
||
+
|
||
+ 0;
|
||
+
|
||
+int yaffs_start(const char * mount_point, ynandif_Geometry * g)
|
||
+{
|
||
+ // Stuff to configure YAFFS
|
||
+ // Stuff to initialise anything special (eg lock semaphore).
|
||
+ yaffsfs_OSInitialisation();
|
||
+ ynand_CreatePart(mount_point, g);
|
||
+
|
||
+ return 0;
|
||
+}
|
||
diff --git a/yaffs_osglue.c b/yaffs_osglue.c
|
||
new file mode 100644
|
||
index 0000000..2c34f99
|
||
--- /dev/null
|
||
+++ b/yaffs_osglue.c
|
||
@@ -0,0 +1,118 @@
|
||
+/*
|
||
+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
|
||
+ *
|
||
+ * Copyright (C) 2002-2011 Aleph One Ltd.
|
||
+ * for Toby Churchill Ltd and Brightstar Engineering
|
||
+ *
|
||
+ * Created by Charles Manning <charles@aleph1.co.uk>
|
||
+ *
|
||
+ * This program is free software; you can redistribute it and/or modify
|
||
+ * it under the terms of the GNU General Public License version 2 as
|
||
+ * published by the Free Software Foundation.
|
||
+ */
|
||
+
|
||
+
|
||
+#include "yaffscfg.h"
|
||
+#include "yaffs_guts.h"
|
||
+#include "yaffsfs.h"
|
||
+#include "yaffs_trace.h"
|
||
+#include <rtthread.h>
|
||
+
|
||
+//#include <errno.h>
|
||
+
|
||
+
|
||
+static int yaffsfs_lastError;
|
||
+
|
||
+void yaffsfs_SetError(int err)
|
||
+{
|
||
+ //Do whatever to set error
|
||
+ yaffsfs_lastError = err;
|
||
+}
|
||
+
|
||
+int yaffsfs_GetLastError(void)
|
||
+{
|
||
+ return yaffsfs_lastError;
|
||
+}
|
||
+
|
||
+
|
||
+#ifdef CONFIG_YAFFS_USE_PTHREADS
|
||
+#include <pthread.h>
|
||
+static pthread_mutex_t mutex1;
|
||
+
|
||
+
|
||
+void yaffsfs_Lock(void)
|
||
+{
|
||
+ pthread_mutex_lock( &mutex1 );
|
||
+}
|
||
+
|
||
+void yaffsfs_Unlock(void)
|
||
+{
|
||
+ pthread_mutex_unlock( &mutex1 );
|
||
+}
|
||
+
|
||
+void yaffsfs_LockInit(void)
|
||
+{
|
||
+ pthread_mutex_init( &mutex1, NULL);
|
||
+}
|
||
+
|
||
+#else
|
||
+
|
||
+static rt_mutex_t mutex = RT_NULL;
|
||
+static rt_sem_t sem = RT_NULL;
|
||
+void yaffsfs_Lock(void)
|
||
+{
|
||
+ rt_mutex_take(mutex, RT_WAITING_FOREVER);
|
||
+}
|
||
+
|
||
+void yaffsfs_Unlock(void)
|
||
+{
|
||
+ rt_mutex_release(mutex);
|
||
+}
|
||
+
|
||
+void yaffsfs_LockInit(void)
|
||
+{
|
||
+ mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO);
|
||
+ if (mutex == RT_NULL)
|
||
+ {
|
||
+ yaffs_trace(YAFFS_TRACE_ERROR,
|
||
+ "**>> yaffs error :yaffs_LockInit can't get a mutex!");
|
||
+ }
|
||
+
|
||
+}
|
||
+#endif
|
||
+
|
||
+u32 yaffsfs_CurrentTime(void)
|
||
+{
|
||
+ return 0;
|
||
+}
|
||
+
|
||
+
|
||
+static int yaffs_kill_alloc = 0;
|
||
+static size_t total_malloced = 0;
|
||
+static size_t malloc_limit = 0 & 6000000;
|
||
+
|
||
+void *yaffsfs_malloc(size_t size)
|
||
+{
|
||
+ void * this;
|
||
+ if(yaffs_kill_alloc)
|
||
+ return NULL;
|
||
+ if(malloc_limit && malloc_limit <(total_malloced + size) )
|
||
+ return NULL;
|
||
+
|
||
+ this = rt_malloc(size);
|
||
+ if(this)
|
||
+ total_malloced += size;
|
||
+ return this;
|
||
+}
|
||
+
|
||
+void yaffsfs_free(void *ptr)
|
||
+{
|
||
+ rt_free(ptr);
|
||
+}
|
||
+
|
||
+void yaffsfs_OSInitialisation(void)
|
||
+{
|
||
+ yaffsfs_LockInit();
|
||
+}
|
||
+
|
||
+
|