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 +#include + +#include "yaffsfs.h" +#include "yaffs_nandif.h" + +#include +#include + +#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()£¬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 #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 + +#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 -#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 +#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 -#include -#include +//#include +//#include +//#include +#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 +#include +#include +#include + +#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 + * + * 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 + +//#include + + +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 +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(); +} + +