提交 fcf01d1d 编写于 作者: B bernard.xiong@gmail.com

fix mutex issue in semaphore.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1927 bbd45198-f89e-11dd-88c7-29a3b14d5316
上级 2f9cd343
...@@ -94,54 +94,41 @@ filesystems/uffs/flash/nand_ids.c ...@@ -94,54 +94,41 @@ filesystems/uffs/flash/nand_ids.c
''' '''
jffs2 = Split(''' jffs2 = Split('''
jffs2/dfs_jffs2.c filesystems/jffs2/dfs_jffs2.c
jffs2/porting.c filesystems/jffs2/porting.c
filesystems/jffs2/cyg/crc/crc16.c
jffs2/cyg/compress/src/adler32.c filesystems/jffs2/cyg/crc/crc32.c
jffs2/cyg/compress/src/compress.c filesystems/jffs2/cyg/crc/posix_crc.c
jffs2/cyg/compress/src/deflate.c filesystems/jffs2/kernel/rbtree.c
jffs2/cyg/compress/src/infback.c filesystems/jffs2/src/build.c
jffs2/cyg/compress/src/infblock.c filesystems/jffs2/src/compr.c
jffs2/cyg/compress/src/inffast.c filesystems/jffs2/src/compr_rtime.c
jffs2/cyg/compress/src/inflate.c filesystems/jffs2/src/compr_rubin.c
jffs2/cyg/compress/src/inftrees.c filesystems/jffs2/src/debug.c
jffs2/cyg/compress/src/maketree.c filesystems/jffs2/src/dir-ecos.c
jffs2/cyg/compress/src/trees.c filesystems/jffs2/src/erase.c
jffs2/cyg/compress/src/uncompr.c filesystems/jffs2/src/flashio.c
jffs2/cyg/compress/src/zutil.c filesystems/jffs2/src/fs-ecos.c
filesystems/jffs2/src/gc.c
jffs2/cyg/crc/crc16.c filesystems/jffs2/src/malloc-ecos.c
jffs2/cyg/crc/crc32.c filesystems/jffs2/src/nodelist.c
jffs2/cyg/crc/posix_crc.c filesystems/jffs2/src/nodemgmt.c
jffs2/kernel/rbtree.c filesystems/jffs2/src/read.c
jffs2/src/build.c filesystems/jffs2/src/readinode.c
jffs2/src/compr.c filesystems/jffs2/src/scan.c
jffs2/src/compr_rtime.c filesystems/jffs2/src/write.c
jffs2/src/compr_rubin.c
jffs2/src/compr_zlib.c
jffs2/src/debug.c
jffs2/src/dir-ecos.c
jffs2/src/erase.c
jffs2/src/flashio.c
jffs2/src/fs-ecos.c
jffs2/src/gc.c
jffs2/src/gcthread.c
jffs2/src/malloc-ecos.c
jffs2/src/nodelist.c
jffs2/src/nodemgmt.c
jffs2/src/read.c
jffs2/src/readinode.c
jffs2/src/scan.c
jffs2/src/write.c
''') ''')
src_local = dfs src_local = dfs
CPPDEFINES = []
# The set of source files associated with this SConscript file. # The set of source files associated with this SConscript file.
path = [RTT_ROOT + '/components/dfs', RTT_ROOT + '/components/dfs/include'] path = [RTT_ROOT + '/components/dfs', RTT_ROOT + '/components/dfs/include']
if GetDepend('RT_USING_DFS_YAFFS2'): if GetDepend('RT_USING_DFS_YAFFS2'):
src_local = src_local + yaffs2_main + yaffs2_comm src_local = src_local + yaffs2_main + yaffs2_comm
path = path + [RTT_ROOT + '/components/dfs/filesystems/yaffs2', RTT_ROOT + '/components/dfs/filesystems/yaffs2/direct'] path = path + [RTT_ROOT + '/components/dfs/filesystems/yaffs2', \
RTT_ROOT + '/components/dfs/filesystems/yaffs2/direct']
if GetDepend('RT_USING_DFS_ELMFAT'): if GetDepend('RT_USING_DFS_ELMFAT'):
if GetDepend('RT_DFS_ELM_USE_LFN'): if GetDepend('RT_DFS_ELM_USE_LFN'):
...@@ -162,12 +149,18 @@ if GetDepend('RT_USING_DFS_DEVFS'): ...@@ -162,12 +149,18 @@ if GetDepend('RT_USING_DFS_DEVFS'):
if GetDepend('RT_USING_DFS_UFFS'): if GetDepend('RT_USING_DFS_UFFS'):
src_local = src_local + uffs src_local = src_local + uffs
path = path + [RTT_ROOT + '/components/dfs/filesystems/uffs/src/inc', RTT_ROOT + '/components/dfs/filesystems/uffs', RTT_ROOT + '/components/dfs/filesystems/uffs/flash'] path = path + [RTT_ROOT + '/components/dfs/filesystems/uffs/src/inc', \
RTT_ROOT + '/components/dfs/filesystems/uffs', \
RTT_ROOT + '/components/dfs/filesystems/uffs/flash']
if GetDepend('RT_USING_DFS_JFFS2'): if GetDepend('RT_USING_DFS_JFFS2'):
src_local = src_local + jffs2 src_local = src_local + jffs2
path = path + [RTT_ROOT + '/components/dfs/filesystems/jffs2/src', RTT_ROOT + '/components/dfs/filesystems/jffs2/kernel', RTT_ROOT + '/components/dfs/filesystems/jffs2/include', RTT_ROOT + '/components/dfs/filesystems/jffs2', RTT_ROOT + '/components/dfs/filesystems/jffs2/cyg/compress'] path = path + [RTT_ROOT + '/components/dfs/filesystems/jffs2/src', \
RTT_ROOT + '/components/dfs/filesystems/jffs2/kernel', \
group = DefineGroup('Filesystem', src_local, depend = ['RT_USING_DFS'], CPPPATH = path) RTT_ROOT + '/components/dfs/filesystems/jffs2/include', \
RTT_ROOT + '/components/dfs/filesystems/jffs2']
CPPDEFINES = CPPDEFINES + ['__ECOS']
group = DefineGroup('Filesystem', src_local, depend = ['RT_USING_DFS'], CPPPATH = path, CPPDEFINES = CPPDEFINES)
Return('group') Return('group')
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <dfs_fs.h> #include <dfs_fs.h>
#include <dfs_def.h> #include <dfs_def.h>
#include <dfs_jffs2.h> #include "dfs_jffs2.h"
#include "porting.h" #include "porting.h"
#define FILE_PATH_MAX 256 /* the longest file path */ #define FILE_PATH_MAX 256 /* the longest file path */
...@@ -165,7 +165,7 @@ static int dfs_jffs2_mount(struct dfs_filesystem* fs, ...@@ -165,7 +165,7 @@ static int dfs_jffs2_mount(struct dfs_filesystem* fs,
* s_dev in struct super_block, and mte->data will be * s_dev in struct super_block, and mte->data will be
* filled with jffs2_sb(see the source of jffs2_mount. * filled with jffs2_sb(see the source of jffs2_mount.
*/ */
mte->data = fs->dev_id; mte->data = (CYG_ADDRWORD)fs->dev_id;
device_partition[index].dev = fs->dev_id; device_partition[index].dev = fs->dev_id;
/* after jffs2_mount, mte->data will not be dev_id any more */ /* after jffs2_mount, mte->data will not be dev_id any more */
......
#ifndef __DFS_JFFS2_H__
#define __DFS_JFFS2_H__
int dfs_jffs2_init(void);
#endif
...@@ -40,7 +40,7 @@ struct jffs2_inode_info { ...@@ -40,7 +40,7 @@ struct jffs2_inode_info {
uint16_t flags; uint16_t flags;
uint8_t usercompr; uint8_t usercompr;
#if !defined (__ECOS) #if !defined (__ECOS) && !defined(RT_THREAD)
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2) #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
struct inode vfs_inode; struct inode vfs_inode;
#endif #endif
......
...@@ -26,13 +26,13 @@ struct semaphore { ...@@ -26,13 +26,13 @@ struct semaphore {
#define DECLARE_MUTEX(x) struct semaphore x = { { .value = 0, } }; #define DECLARE_MUTEX(x) struct semaphore x = { { .value = 0, } };
#define DECLARE_MUTEX_LOCKED(x) struct semaphore x = { { .vlalue = 1 } }; #define DECLARE_MUTEX_LOCKED(x) struct semaphore x = { { .vlalue = 1 } };
#define init_MUTEX(sem) rt_mutex_init((rt_mutex_t *)sem, "mutex", RT_IPC_FLAG_FIFO) #define init_MUTEX(sem) rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO)
#define init_MUTEX_LOCKED(sem) do { \ #define init_MUTEX_LOCKED(sem) do { \
rt_mutex_init((rt_mutex_t *)sem, "mutex", RT_IPC_FLAG_FIFO);\ rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO);\
rt_mutex_take((rt_mutex_t *)sem, RT_WAITING_FOREVER);} \ rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER);} \
while(0) while(0)
#define down(sem) rt_mutex_take((rt_mutex_t *)sem, RT_WAITING_FOREVER) #define down(sem) rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER)
#define down_interruptible(sem) ({rt_mutex_take((rt_mutex_t *)sem, RT_WAITING_FOREVER), 0; }) #define down_interruptible(sem) ({rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER), 0; })
/* /*
Attempt to lock the mutex pointed to by the mutex argument without waiting. Attempt to lock the mutex pointed to by the mutex argument without waiting.
If the mutex is already locked by some other thread then this function If the mutex is already locked by some other thread then this function
...@@ -41,6 +41,6 @@ TRUE is returned. ...@@ -41,6 +41,6 @@ TRUE is returned.
void cyg_drv_mutex_unlock( cyg_drv_mutex *mutex ) void cyg_drv_mutex_unlock( cyg_drv_mutex *mutex )
*/ */
#define down_trylock(sem) rt_mutex_take((rt_mutex_t *)sem, RT_WAITING_NO) #define down_trylock(sem) rt_mutex_take((rt_mutex_t)sem, RT_WAITING_NO)
#define up(sem) rt_mutex_release((rt_mutex_t *)sem) #define up(sem) rt_mutex_release((rt_mutex_t)sem)
#endif /* __ASM_SEMAPHORE_H__ */ #endif /* __ASM_SEMAPHORE_H__ */
#ifndef __LINUX_CONFIG_H__ #ifndef __LINUX_CONFIG_H__
#define __LINUX_CONFIG_H__ #define __LINUX_CONFIG_H__
#define CONFIG_JFFS2_FS_DEBUG 0 #define CONFIG_JFFS2_FS_DEBUG 0
#define GFP_KERNEL 0 #define GFP_KERNEL 0
/* #define CONFIG_JFFS2_FS_WRITEBUFFER 0 */
/* #define CONFIG_JFFS2_PROC */
/* #define CONFIG_JFFS2_RTIME */
/* #define CONFIG_JFFS2_RUBIN */
/* #define CONFIG_JFFS2_ZLIB */
#endif /* __LINUX_CONFIG_H__ */ #endif /* __LINUX_CONFIG_H__ */
#ifndef __LINUX_VERSION_H__ #ifndef __LINUX_VERSION_H__
#define __LINUX_VERSION_H__ #define __LINUX_VERSION_H__
#include <rtthread.h>
#endif /* __LINUX_VERSION_H__ */ #endif /* __LINUX_VERSION_H__ */
...@@ -21,4 +21,4 @@ void jffs2_get_info_from_sb(void * data, struct jffs2_fs_info * info) ...@@ -21,4 +21,4 @@ void jffs2_get_info_from_sb(void * data, struct jffs2_fs_info * info)
info->sector_size = c->sector_size; info->sector_size = c->sector_size;
info->nr_blocks = c->nr_blocks; info->nr_blocks = c->nr_blocks;
info->free_size = c->free_size; //fixme need test! info->free_size = c->free_size; //fixme need test!
} }
\ No newline at end of file
...@@ -35,4 +35,4 @@ struct jffs2_dirent ...@@ -35,4 +35,4 @@ struct jffs2_dirent
// should be used with caution. // should be used with caution.
char d_name[NAME_MAX+1]; char d_name[NAME_MAX+1];
}; };
#endif #endif
\ No newline at end of file
...@@ -22,7 +22,9 @@ ...@@ -22,7 +22,9 @@
#include <linux/jffs2_fs_i.h> #include <linux/jffs2_fs_i.h>
#ifdef __ECOS #ifdef __ECOS
#include "os-ecos.h" #include "os-ecos.h"
#elif defined(RT_THREAD)
#include "os-rtthread.h"
#else #else
#include <linux/mtd/compatmac.h> /* For compatibility with older kernels */ #include <linux/mtd/compatmac.h> /* For compatibility with older kernels */
#include "os-linux.h" #include "os-linux.h"
......
...@@ -15,8 +15,6 @@ ...@@ -15,8 +15,6 @@
#define __JFFS2_OS_ECOS_H__ #define __JFFS2_OS_ECOS_H__
#include <rtthread.h> #include <rtthread.h>
#define malloc rt_malloc
#define free rt_free
#define printf rt_kprintf #define printf rt_kprintf
//#include <pkgconf/fs_jffs2.h> //#include <pkgconf/fs_jffs2.h>
......
/*
* JFFS2 -- Journalling Flash File System, Version 2.
*
* Copyright (C) 2002-2003 Free Software Foundation, Inc.
*
* Created by David Woodhouse <dwmw2@cambridge.redhat.com>
*
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id: os-ecos.h,v 1.24 2005/02/09 09:23:55 pavlov Exp $
*
*/
#ifndef __JFFS2_OS_RTTHREAD_H__
#define __JFFS2_OS_RTTHREAD_H__
#include <rtthread.h>
#define printf rt_kprintf
//#include <pkgconf/fs_jffs2.h>
//#include <cyg/io/io.h>
//#include <sys/types.h>
#include <asm/atomic.h>
#include <linux/stat.h>
#include <linux/compiler.h>
//#include <pkgconf/system.h>
//#include <pkgconf/hal.h>
//#include <pkgconf/io_fileio.h>
//#include <cyg/infra/cyg_trac.h> // tracing macros
//#include <cyg/infra/cyg_ass.h> // assertion macros
//#if defined (__GNUC__)
//#include <unistd.h>
//#elif defined (MSVC)
//#else
//#endif
#include "os_sys_stat.h"//#include <sys/types.h>
//#include <fcntl.h>
//#include <sys/stat.h>
//#include <errno.h> //fixme
//#include <dirent.h>
#define CYGPKG_FILEIO_DIRENT_DTYPE
struct dirent
{
#ifdef CYGPKG_FILEIO_DIRENT_DTYPE
mode_t d_type; // Only supported with FATFS, RAMFS, ROMFS,
// and JFFS2.
// d_type is not part of POSIX so
// should be used with caution.
#endif
char d_name[NAME_MAX+1];
};
#include <stdlib.h>
#include <string.h>
#include <cyg/fileio/fileio.h> //prife
//#include <cyg/hal/drv_api.h>
//#include <cyg/infra/diag.h>
//#include <cyg/io/flash.h>
#include <linux/types.h>
#include <linux/list.h>
#include <asm/bug.h>
//#define printf diag_printf //prife
struct _inode;
struct super_block;
struct iovec {
void *iov_base;
ssize_t iov_len;
};
static inline unsigned int full_name_hash(const unsigned char * name, unsigned int len) {
unsigned hash = 0;
while (len--) {
hash = (hash << 4) | (hash >> 28);
hash ^= *(name++);
}
return hash;
}
#ifdef CYGOPT_FS_JFFS2_WRITE
#define jffs2_is_readonly(c) (0)
#else
#define jffs2_is_readonly(c) (1)
#endif
/* NAND flash not currently supported on eCos */
#define jffs2_can_mark_obsolete(c) (1)
#define JFFS2_INODE_INFO(i) (&(i)->jffs2_i)
#define OFNI_EDONI_2SFFJ(f) ((struct _inode *) ( ((char *)f) - ((char *)(&((struct _inode *)NULL)->jffs2_i)) ) )
#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size)
#define JFFS2_F_I_MODE(f) (OFNI_EDONI_2SFFJ(f)->i_mode)
#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime)
#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime)
#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime)
/* FIXME: eCos doesn't hav a concept of device major/minor numbers */
#define JFFS2_F_I_RDEV_MIN(f) ((OFNI_EDONI_2SFFJ(f)->i_rdev)&0xff)
#define JFFS2_F_I_RDEV_MAJ(f) ((OFNI_EDONI_2SFFJ(f)->i_rdev)>>8)
#define get_seconds cyg_timestamp
struct _inode {
cyg_uint32 i_ino;
int i_count;
mode_t i_mode;
nlink_t i_nlink; // Could we dispense with this?
uid_t i_uid;
gid_t i_gid;
time_t i_atime;
time_t i_mtime;
time_t i_ctime;
// union {
unsigned short i_rdev; // For devices only
struct _inode * i_parent; // For directories only
off_t i_size; // For files only
// };
struct super_block * i_sb;
struct jffs2_inode_info jffs2_i;
struct _inode * i_cache_prev; // We need doubly-linked?
struct _inode * i_cache_next;
};
#define JFFS2_SB_INFO(sb) (&(sb)->jffs2_sb)
#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->jffs2_sb)) ) )
struct super_block {
struct jffs2_sb_info jffs2_sb;
struct _inode * s_root;
unsigned long s_mount_count;
cyg_io_handle_t s_dev;
//#ifdef CYGOPT_FS_JFFS2_GCTHREAD
// cyg_mutex_t s_lock; // Lock the inode cache
// cyg_flag_t s_gc_thread_flags; // Communication with the gcthread
// cyg_handle_t s_gc_thread_handle;
// cyg_thread s_gc_thread;
//#if (CYGNUM_JFFS2_GC_THREAD_STACK_SIZE >= CYGNUM_HAL_STACK_SIZE_MINIMUM)
// char s_gc_thread_stack[CYGNUM_JFFS2_GC_THREAD_STACK_SIZE];
//#else
// char s_gc_thread_stack[CYGNUM_HAL_STACK_SIZE_MINIMUM];
//#endif
// cyg_mtab_entry *mte;
//#endif
#ifdef CYGOPT_FS_JFFS2_GCTHREAD
struct rt_mutex s_lock; // Lock the inode cache
struct rt_event s_gc_thread_flags; // Communication with the gcthread
//void (*s_gc_thread_handle)(void *parameter);
struct rt_thread s_gc_thread;
//#if (CYGNUM_JFFS2_GC_THREAD_STACK_SIZE >= CYGNUM_HAL_STACK_SIZE_MINIMUM)
// char s_gc_thread_stack[CYGNUM_JFFS2_GC_THREAD_STACK_SIZE];
//#else
// char s_gc_thread_stack[CYGNUM_HAL_STACK_SIZE_MINIMUM];
//#endif
#define CYGNUM_JFFS2_GC_THREAD_STACK_SIZE (1024*4)
char s_gc_thread_stack[CYGNUM_JFFS2_GC_THREAD_STACK_SIZE];
cyg_mtab_entry *mte;
#endif
};
#define sleep_on_spinunlock(wq, sl) spin_unlock(sl)
#define EBADFD 32767
/* background.c */
#ifdef CYGOPT_FS_JFFS2_GCTHREAD
void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c);
void jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c);
void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c);
#else
static inline void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c)
{
/* We don't have a GC thread in eCos (yet) */
}
#endif
/* fs-ecos.c */
struct _inode *jffs2_new_inode (struct _inode *dir_i, int mode, struct jffs2_raw_inode *ri);
struct _inode *jffs2_iget(struct super_block *sb, cyg_uint32 ino);
void jffs2_iput(struct _inode * i);
void jffs2_gc_release_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, int inum, int nlink);
unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
unsigned long offset, unsigned long *priv);
void jffs2_gc_release_page(struct jffs2_sb_info *c, unsigned char *pg, unsigned long *priv);
/* Avoid polluting eCos namespace with names not starting in jffs2_ */
#define os_to_jffs2_mode(x) jffs2_from_os_mode(x)
uint32_t jffs2_from_os_mode(uint32_t osmode);
uint32_t jffs2_to_os_mode (uint32_t jmode);
/* flashio.c */
cyg_bool jffs2_flash_read(struct jffs2_sb_info *c, cyg_uint32 read_buffer_offset,
const size_t size, size_t * return_size, unsigned char * write_buffer);
cyg_bool jffs2_flash_write(struct jffs2_sb_info *c, cyg_uint32 write_buffer_offset,
const size_t size, size_t * return_size, unsigned char * read_buffer);
int jffs2_flash_direct_writev(struct jffs2_sb_info *c, const struct iovec *vecs,
unsigned long count, loff_t to, size_t *retlen);
cyg_bool jffs2_flash_erase(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
// dir-ecos.c
struct _inode *jffs2_lookup(struct _inode *dir_i, const unsigned char *name, int namelen);
int jffs2_create(struct _inode *dir_i, const unsigned char *d_name, int mode, struct _inode **new_i);
int jffs2_mkdir (struct _inode *dir_i, const unsigned char *d_name, int mode);
int jffs2_link (struct _inode *old_d_inode, struct _inode *dir_i, const unsigned char *d_name);
int jffs2_unlink(struct _inode *dir_i, struct _inode *d_inode, const unsigned char *d_name);
int jffs2_rmdir (struct _inode *dir_i, struct _inode *d_inode, const unsigned char *d_name);
int jffs2_rename (struct _inode *old_dir_i, struct _inode *d_inode, const unsigned char *old_d_name,
struct _inode *new_dir_i, const unsigned char *new_d_name);
/* erase.c */
static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
{ }
#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) )
#define jffs2_can_mark_obsolete(c) (1)
#define jffs2_cleanmarker_oob(c) (0)
#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
#define jffs2_flush_wbuf_pad(c) (c=c)
#define jffs2_flush_wbuf_gc(c, i) ({ (void)(c), (void) i, 0; })
#define jffs2_nand_read_failcnt(c,jeb) do { ; } while(0)
#define jffs2_write_nand_badblock(c,jeb,p) (0)
#define jffs2_flash_setup(c) (0)
#define jffs2_nand_flash_cleanup(c) do {} while(0)
#define jffs2_wbuf_dirty(c) (0)
#define jffs2_flash_writev(a,b,c,d,e,f) jffs2_flash_direct_writev(a,b,c,d,e)
#define jffs2_wbuf_timeout NULL
#define jffs2_wbuf_process NULL
#define jffs2_nor_ecc(c) (0)
#else
#error no nand yet
#endif
#ifndef BUG_ON
#define BUG_ON(x) do { if (unlikely(x)) BUG(); } while(0)
#endif
#define __init
#endif /* __JFFS2_OS_ECOS_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册