diff options
| author | Bernard Xiong <[email protected]> | 2021-03-16 09:07:15 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2021-03-16 09:07:15 +0800 |
| commit | 0ae1743b61f2dd2a387996a2ba52d5b4e66c38e9 (patch) | |
| tree | 97bd9d40418542da294e438aeb33d6ac0288f212 /components | |
| parent | 2be0c598fd35dc23e18f6e0005e7225dd356330c (diff) | |
| parent | 3ec59a8865b9503f5daa4e6c894b0fc502a43068 (diff) | |
Merge pull request #4449 from yangjie11/yj_dev
[components][dfs] remove jffs2 and uffs
Diffstat (limited to 'components')
213 files changed, 1 insertions, 57161 deletions
diff --git a/components/dfs/Kconfig b/components/dfs/Kconfig index c6b493f0d2..39eca3c507 100644 --- a/components/dfs/Kconfig +++ b/components/dfs/Kconfig @@ -115,7 +115,7 @@ if RT_USING_DFS int "Maximum sector size to be handled." default 512 help - if you use some spi nor flash for fatfs, please set this the erase sector size, for example 4096. + If you use some spi nor flash for fatfs, please set this the erase sector size, for example 4096. config RT_DFS_ELM_USE_ERASE bool "Enable sector erase feature" @@ -140,43 +140,6 @@ if RT_USING_DFS select RT_USING_MEMHEAP default n - config RT_USING_DFS_UFFS - bool "Enable UFFS file system: Ultra-low-cost Flash File System" - select RT_USING_MTD_NAND - default n - - if RT_USING_DFS_UFFS - choice - prompt "UFFS ECC mode" - default RT_UFFS_ECC_MODE_1 - - config RT_UFFS_ECC_MODE_0 - bool "0: Do not use ECC" - - config RT_UFFS_ECC_MODE_1 - bool "1: UFFS calculate the ECC" - - config RT_UFFS_ECC_MODE_2 - bool "2: Flash driver(or by hardware) calculate the ECC" - - config RT_UFFS_ECC_MODE_3 - bool "3: Hardware calculate the ECC and automatically write to spare." - endchoice - - config RT_UFFS_ECC_MODE - int - default 0 if RT_UFFS_ECC_MODE_0 - default 1 if RT_UFFS_ECC_MODE_1 - default 2 if RT_UFFS_ECC_MODE_2 - default 3 if RT_UFFS_ECC_MODE_3 - - endif - - config RT_USING_DFS_JFFS2 - bool "Enable JFFS2 file system" - select RT_USING_MTD_NOR - default n - config RT_USING_DFS_NFS bool "Using NFS v3 client file system" depends on RT_USING_LWIP diff --git a/components/dfs/filesystems/jffs2/SConscript b/components/dfs/filesystems/jffs2/SConscript deleted file mode 100644 index 47854393e3..0000000000 --- a/components/dfs/filesystems/jffs2/SConscript +++ /dev/null @@ -1,50 +0,0 @@ -# RT-Thread building script for component - -from building import * - -cwd = GetCurrentDir() -src = Split(''' -dfs_jffs2.c -porting.c - -cyg/compress/src/adler32.c -cyg/compress/src/compress.c -cyg/compress/src/deflate.c -cyg/compress/src/infback.c -cyg/compress/src/inffast.c -cyg/compress/src/inflate.c -cyg/compress/src/inftrees.c -cyg/compress/src/trees.c -cyg/compress/src/uncompr.c -cyg/compress/src/zutil.c - -cyg/crc/crc16.c -cyg/crc/crc32.c -cyg/crc/posix_crc.c -kernel/rbtree.c -src/build.c -src/compr.c -src/compr_rtime.c -src/compr_rubin.c -src/compr_zlib.c -src/debug.c -src/dir-ecos.c -src/erase.c -src/flashio.c -src/fs-ecos.c -src/gc.c -src/gcthread.c -src/malloc-ecos.c -src/nodelist.c -src/nodemgmt.c -src/read.c -src/readinode.c -src/scan.c -src/write.c -''') - -CPPPATH = [cwd, cwd + '/include', cwd + '/src', cwd + '/cyg', cwd + '/kernel', cwd + '/cyg/compress'] - -group = DefineGroup('Filesystem', src, depend = ['RT_USING_DFS', 'RT_USING_DFS_JFFS2'], CPPPATH = CPPPATH) - -Return('group') diff --git a/components/dfs/filesystems/jffs2/cyg/compress/ChangeLog b/components/dfs/filesystems/jffs2/cyg/compress/ChangeLog deleted file mode 100644 index 295e5cdd48..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/ChangeLog +++ /dev/null @@ -1,218 +0,0 @@ -2009-03-09 John Dallaway <[email protected]> - - * cdl/compress_zlib.cdl: Reference test executable filenames for - compatibility with the eCos Configuration Tool. - -2005-10-16 Peter Korsgaard <[email protected]> - - * cdl/compress_zlib.cdl (CYGFUN_COMPRESS_ZLIB_GZIO): New option to - include zlib stdio-like utility functions. - -2005-07-27 Peter Korsgaard <[email protected]> - - * src/ChangeLog: - * src/configure: - * src/deflate.c: - * src/deflate.h: - * src/FAQ: - * src/gzio.c: - * src/Make_vms.com: - * src/adler32.c: - * src/compress.c: - * src/example.c: - * src/minigzip.c: - * src/infback.c: - * src/inffast.c: - * src/inflate.c: - * src/inflate.h: - * src/inftrees.c: - * src/inftrees.h: - * src/Makefile: - * src/Makefile.in: - * src/README: - * src/README.eCos: - * src/trees.c: - * src/zlib.3: - * src/zutil.c: - * src/zutil.h: - * include/zlib.h: - * include/zconf.h: Upgrade to zlib-1.2.3 - -2005-06-28 Peter Korsgaard <[email protected]> - - * src/ChangeLog: - * src/configure: - * src/deflate.c: - * src/deflate.h: - * src/FAQ: - * src/gzio.c: - * src/INDEX: - * src/infback.c: - * src/inffast.c: - * src/inflate.c: - * src/Makefile: - * src/Makefile.in: - * src/README: - * src/trees.c: - * src/zlib.3: - * src/zutil.h: - * include/zlib.h: - * include/zconf.h: Upgrade to zlib-1.2.2 - -2005-03-27 Andrew Lunn <[email protected]> - - * tests/zlib1.c: Include diag.h for diag_printf proto. - -2004-05-25 Gary Thomas <[email protected]> - - * src/zutil.h: Fix redefine of 'crc32' - - * include/zconf.h: Force define of __ECOS__ to make it easier for - applications to use this library. Also define Z_PREFIX to minimize - namespace pollution. !CYGSEM_COMPRESS_ZLIB_DEFLATE_MAKES_GZIP now - implies NO_GZCOMPRESS and NO_GZIP. - -2004-05-24 Gary Thomas <[email protected]> - - * tests/zlib2.c: - * tests/zlib1.c: - * src/zutil.h: - * src/zutil.c: - * src/zlib.3: - * src/uncompr.c: - * src/trees.c: - * src/minigzip.c: - * src/inftrees.h: - * src/inftrees.c: - * src/inflate.h: - * src/inflate.c: - * src/inffixed.h: - * src/inffast.h: - * src/inffast.c: - * src/infback.c: - * src/gzio.c: - * src/example.c: - * src/deflate.h: - * src/deflate.c: - * src/configure: - * src/compress.c: - * src/algorithm.txt: - * src/adler32.c: - * src/README.eCos: - * src/README: - * src/Makefile.in: - * src/Makefile: - * src/INDEX: - * src/FAQ: - * include/zlib.h: - * include/zconf.h: - * cdl/compress_zlib.cdl: Upgrade to zlib-1.2.1 - -2004-04-29 Oyvind Harboe <[email protected]> - - * src/inffixed.h: added "const" to tables that do not - change in order to save RAM. Ca. 4k. - -2003-11-20 Andrew Lunn <[email protected]> - - * tests/zlib[12].c: Modified the text to the gcc3.3 friendly. - -2003-11-13 Daniel N�ri <[email protected]> - - * Upgrade to zlib 1.1.4 and additional fix for inflate bug on - machines with 16-bit pointers. - -2003-09-08 Thomas Koeller <[email protected]> - - * cdl/compress_zlib.cdl : Displayed package name was wrong. - -2002-10-10 Andrew Lunn <[email protected]> - - * include/zutil.h: - * include/zlib.h: - * src/inflate.c (inflate): Use the CRC function from the CRC - package. - * src/crc32.c: Removed. - -2002-09-09 Mark Salter <[email protected]> - - * inflate.c (inflate): Fix CRC calculation over multiple invocations - with same output buffer. - -2002-02-18 Jesper Skov <[email protected]> - - * src/infblock.c: Applied fix for double-free which could cause a - zlib crash. Fixed indentation. - -2001-10-15 Gary Thomas <[email protected]> - - * include/zconf.h: - * cdl/compress_zlib.cdl: - Define new interface CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC which allows - users of this code (applications) to provide their own allocators. - -2001-04-02 Jesper Skov <[email protected]> - - * tests/zlib2.c: Removed BAD_CRC state. - -2001-03-12 Jesper Skov <[email protected]> - - * src/inflate.c: Remove BAD_CRC state. Do separate CRC for - gzippped data. - * include/zlib.h: Removed Z_BAD_CRC hack. Rename crc32 function. - * src/crc32.c: Include zlib.h header from - include/cyg/compress. Rename function. - * cdl/compress_zlib.cdl: Build the crc32.c file. - -2001-03-09 Jesper Skov <[email protected]> - - * src/compress.c: Include zlib.h header from include/cyg/compress. - * src/uncompr.c: Same. - * tests/zlib1.c: Added. - * tests/zlib2.c: Added. - * cdl/compress_zlib.cdl: Compile tests. Compile - files holding compress/uncompress functions. - - * cdl/compress_zlib.cdl: Don't warn about prototypes when building. - -2001-03-08 Jesper Skov <[email protected]> - - * cdl/compress_zlib.cdl: Add isoinfra requirement. - - * include/zconf.h: Override STDC check. - - * include/zlib.h: Added new BAD_CRC return type. Comment out crc32 - declaration. - - * src/inflate.c: Added additional states to allow for gzip header - decoding. - - * src/adler32.c: Include zlib.h header from include/cyg/compress. - * src/zutil.h: Same. - - * Import zlib 1.1.3 sources, but leave out some sub - directories. See src/README.eCos for details. - -//=========================================================================== -// ####GPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. -// -// This program is free software; you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation; either version 2 or (at your option) any -// later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the -// Free Software Foundation, Inc., 51 Franklin Street, -// Fifth Floor, Boston, MA 02110-1301, USA. -// ------------------------------------------- -// ####GPLCOPYRIGHTEND#### -//=========================================================================== diff --git a/components/dfs/filesystems/jffs2/cyg/compress/cdl/compress_zlib.cdl b/components/dfs/filesystems/jffs2/cyg/compress/cdl/compress_zlib.cdl deleted file mode 100644 index d5787570b7..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/cdl/compress_zlib.cdl +++ /dev/null @@ -1,170 +0,0 @@ -# ==================================================================== -# -# compress_zlib.cdl -# -# Zlib compress/decompress configuration data -# -# ==================================================================== -## ####ECOSGPLCOPYRIGHTBEGIN#### -## ------------------------------------------- -## This file is part of eCos, the Embedded Configurable Operating System. -## Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. -## -## eCos is free software; you can redistribute it and/or modify it under -## the terms of the GNU General Public License as published by the Free -## Software Foundation; either version 2 or (at your option) any later -## version. -## -## eCos is distributed in the hope that it will be useful, but WITHOUT -## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -## for more details. -## -## You should have received a copy of the GNU General Public License -## along with eCos; if not, write to the Free Software Foundation, Inc., -## 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -## -## As a special exception, if other files instantiate templates or use -## macros or inline functions from this file, or you compile this file -## and link it with other works to produce a work based on this file, -## this file does not by itself cause the resulting work to be covered by -## the GNU General Public License. However the source code for this file -## must still be made available in accordance with section (3) of the GNU -## General Public License v2. -## -## This exception does not invalidate any other reasons why a work based -## on this file might be covered by the GNU General Public License. -## ------------------------------------------- -## ####ECOSGPLCOPYRIGHTEND#### -# ==================================================================== -######DESCRIPTIONBEGIN#### -# -# Author(s): jskov -# Contributors: -# Date: 2001-03-06 -# -#####DESCRIPTIONEND#### -# -# ==================================================================== - -cdl_package CYGPKG_COMPRESS_ZLIB { - display "Zlib compress and decompress package" - description " - This package provides support for compression and - decompression." - include_dir cyg/compress - - requires CYGPKG_ISOINFRA - requires CYGPKG_CRC - - compile adler32.c compress.c uncompr.c zutil.c trees.c - compile deflate.c infback.c inffast.c inflate.c inftrees.c - - cdl_interface CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC { - display "Override memory allocation routines." - } - - cdl_option CYGSEM_COMPRESS_ZLIB_DEFLATE_MAKES_GZIP { - display "Should deflate() produce 'gzip' compatible output?" - flavor bool - default_value 1 - description " - If this option is set then the output of calling deflate() - will be wrapped up as a 'gzip' compatible file." - } - - cdl_option CYGSEM_COMPRESS_ZLIB_NEEDS_MALLOC { - display "Does this library need malloc?" - flavor bool - active_if { CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC == 0 } - requires CYGPKG_MEMALLOC - no_define - default_value 1 - description " - This pseudo-option will force the memalloc library to be - required iff the application does not provide it's own - infrastructure." - } - - cdl_option CYGFUN_COMPRESS_ZLIB_GZIO { - display "Include stdio-like utility functions" - flavor bool - requires CYGINT_ISO_STDIO_FILEPOS - requires CYGINT_ISO_STRING_STRFUNCS - requires CYGINT_ISO_STDIO_FORMATTED_IO - requires CYGINT_ISO_STDIO_FILEACCESS - default_value { CYGPKG_LIBC_STDIO_OPEN ? 1 : 0 } - compile gzio.c - description " - This option enables the stdio-like zlib utility functions - (gzread/gzwrite and friends) provided in gzio.c." - } - - -# ==================================================================== - - cdl_component CYGPKG_COMPRESS_ZLIB_OPTIONS { - display "Zlib compress and decompress package build options" - flavor none - no_define - description " - Package specific build options including control over - compiler flags used only in building this package, - and details of which tests are built." - - cdl_option CYGPKG_COMPRESS_ZLIB_CFLAGS_ADD { - display "Additional compiler flags" - flavor data - no_define - default_value { "-D__ECOS__ -DNO_ERRNO_H" } - description " - This option modifies the set of compiler flags for - building this package. These flags are used in addition - to the set of global flags." - } - - cdl_option CYGPKG_COMPRESS_ZLIB_CFLAGS_REMOVE { - display "Suppressed compiler flags" - flavor data - no_define - default_value { "-Wstrict-prototypes" } - description " - This option modifies the set of compiler flags for - building this package. These flags are removed from - the set of global flags if present." - } - - cdl_option CYGPKG_COMPRESS_ZLIB_LDFLAGS_ADD { - display "Additional compiler flags" - flavor data - no_define - default_value { "" } - description " - This option modifies the set of compiler flags for - building this package. These flags are used in addition - to the set of global flags." - } - - cdl_option CYGPKG_COMPRESS_ZLIB_LDFLAGS_REMOVE { - display "Suppressed compiler flags" - flavor data - no_define - default_value { "" } - description " - This option modifies the set of compiler flags for - building this package. These flags are removed from - the set of global flags if present." - } - - } - - cdl_option CYGPKG_COMPRESS_ZLIB_TESTS { - display "zlib tests" - flavor data - no_define - calculated { "tests/zlib1 tests/zlib2" } - } -} - -# ==================================================================== -# EOF compress_zlib.cdl diff --git a/components/dfs/filesystems/jffs2/cyg/compress/include/zconf.h b/components/dfs/filesystems/jffs2/cyg/compress/include/zconf.h deleted file mode 100644 index 09608dcc34..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/include/zconf.h +++ /dev/null @@ -1,349 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -// #ifdef __ECOS__ -#undef __ECOS__ -#define __ECOS__ -#define Z_PREFIX -#include <pkgconf/compress_zlib.h> -#if CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC != 0 -#define MY_ZCALLOC -#endif -#ifdef CYGSEM_COMPRESS_ZLIB_DEFLATE_MAKES_GZIP -#undef MAX_WBITS -#define MAX_WBITS 15+16 /* 32K LZ77 window */ -#else -#define NO_GZIP -#define NO_GZCOMPRESS -#endif -// #endif - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include <windows.h> - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include <sys/types.h> /* for off_t */ -# include <unistd.h> /* for SEEK_* and off_t */ -# ifdef VMS -# include <unixio.h> /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/components/dfs/filesystems/jffs2/cyg/compress/include/zlib.h b/components/dfs/filesystems/jffs2/cyg/compress/include/zlib.h deleted file mode 100644 index 081e7c912f..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/include/zlib.h +++ /dev/null @@ -1,1358 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 - - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.3" -#define ZLIB_VERNUM 0x1230 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - -typedef voidp gzFile; - -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); -/* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); -/* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns 1 if file is being read directly without decompression, otherwise - zero. -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -#ifndef __ECOS__ -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); -/* - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ -#endif // __ECOS__ - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - -/* - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/ChangeLog b/components/dfs/filesystems/jffs2/cyg/compress/src/ChangeLog deleted file mode 100644 index dfdd0295e8..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/ChangeLog +++ /dev/null @@ -1,854 +0,0 @@ - ChangeLog file for zlib - -Changes in 1.2.2 (3 October 2004) -Changes in 1.2.3 (18 July 2005) -- Apply security vulnerability fixes to contrib/infback9 as well -- Clean up some text files (carriage returns, trailing space) -- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant] - -Changes in 1.2.2.4 (11 July 2005) -- Add inflatePrime() function for starting inflation at bit boundary -- Avoid some Visual C warnings in deflate.c -- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit - compile -- Fix some spelling errors in comments [Betts] -- Correct inflateInit2() error return documentation in zlib.h -- Added zran.c example of compressed data random access to examples - directory, shows use of inflatePrime() -- Fix cast for assignments to strm->state in inflate.c and infback.c -- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer] -- Move declarations of gf2 functions to right place in crc32.c [Oberhumer] -- Add cast in trees.c t avoid a warning [Oberhumer] -- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer] -- Update make_vms.com [Zinser] -- Initialize state->write in inflateReset() since copied in inflate_fast() -- Be more strict on incomplete code sets in inflate_table() and increase - ENOUGH and MAXD -- this repairs a possible security vulnerability for - invalid inflate input. Thanks to Tavis Ormandy and Markus Oberhumer for - discovering the vulnerability and providing test cases. -- Add ia64 support to configure for HP-UX [Smith] -- Add error return to gzread() for format or i/o error [Levin] -- Use malloc.h for OS/2 [Necasek] - -Changes in 1.2.2.3 (27 May 2005) -- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile -- Typecast fread() return values in gzio.c [Vollant] -- Remove trailing space in minigzip.c outmode (VC++ can't deal with it) -- Fix crc check bug in gzread() after gzungetc() [Heiner] -- Add the deflateTune() function to adjust internal compression parameters -- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack) -- Remove an incorrect assertion in examples/zpipe.c -- Add C++ wrapper in infback9.h [Donais] -- Fix bug in inflateCopy() when decoding fixed codes -- Note in zlib.h how much deflateSetDictionary() actually uses -- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used) -- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer] -- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer] -- Add gzdirect() function to indicate transparent reads -- Update contrib/minizip [Vollant] -- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer] -- Add casts in crc32.c to avoid warnings [Oberhumer] -- Add contrib/masmx64 [Vollant] -- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant] - -Changes in 1.2.2.2 (30 December 2004) -- Replace structure assignments in deflate.c and inflate.c with zmemcpy to - avoid implicit memcpy calls (portability for no-library compilation) -- Increase sprintf() buffer size in gzdopen() to allow for large numbers -- Add INFLATE_STRICT to check distances against zlib header -- Improve WinCE errno handling and comments [Chang] -- Remove comment about no gzip header processing in FAQ -- Add Z_FIXED strategy option to deflateInit2() to force fixed trees -- Add updated make_vms.com [Coghlan], update README -- Create a new "examples" directory, move gzappend.c there, add zpipe.c, - fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html. -- Add FAQ entry and comments in deflate.c on uninitialized memory access -- Add Solaris 9 make options in configure [Gilbert] -- Allow strerror() usage in gzio.c for STDC -- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer] -- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant] -- Use z_off_t for adler32_combine() and crc32_combine() lengths -- Make adler32() much faster for small len -- Use OS_CODE in deflate() default gzip header - -Changes in 1.2.2.1 (31 October 2004) -- Allow inflateSetDictionary() call for raw inflate -- Fix inflate header crc check bug for file names and comments -- Add deflateSetHeader() and gz_header structure for custom gzip headers -- Add inflateGetheader() to retrieve gzip headers -- Add crc32_combine() and adler32_combine() functions -- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list -- Use zstreamp consistently in zlib.h (inflate_back functions) -- Remove GUNZIP condition from definition of inflate_mode in inflate.h - and in contrib/inflate86/inffast.S [Truta, Anderson] -- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson] -- Update projects/README.projects and projects/visualc6 [Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta] -- Deprecate Z_ASCII; use Z_TEXT instead [Truta] -- Use a new algorithm for setting strm->data_type in trees.c [Truta] -- Do not define an exit() prototype in zutil.c unless DEBUG defined -- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta] -- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate() -- Fix Darwin build version identification [Peterson] - -- Update zlib.h comments on gzip in-memory processing -- Set adler to 1 in inflateReset() to support Java test suite [Walles] -- Add contrib/dotzlib [Ravn] -- Update win32/DLL_FAQ.txt [Truta] -- Update contrib/minizip [Vollant] -- Move contrib/visual-basic.txt to old/ [Truta] -- Fix assembler builds in projects/visualc6/ [Truta] - -Changes in 1.2.1.2 (9 September 2004) -- Update INDEX file -- Fix trees.c to update strm->data_type (no one ever noticed!) -- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown] -- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE) -- Add limited multitasking protection to DYNAMIC_CRC_TABLE -- Add NO_vsnprintf for VMS in zutil.h [Mozilla] -- Don't declare strerror() under VMS [Mozilla] -- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize -- Update contrib/ada [Anisimkov] -- Update contrib/minizip [Vollant] -- Fix configure to not hardcode directories for Darwin [Peterson] -- Fix gzio.c to not return error on empty files [Brown] -- Fix indentation; update version in contrib/delphi/ZLib.pas and - contrib/pascal/zlibpas.pas [Truta] -- Update mkasm.bat in contrib/masmx86 [Truta] -- Update contrib/untgz [Truta] -- Add projects/README.projects [Truta] -- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta] -- Update win32/DLL_FAQ.txt [Truta] -- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta] -- Remove an unnecessary assignment to curr in inftrees.c [Truta] -- Add OS/2 to exe builds in configure [Poltorak] -- Remove err dummy parameter in zlib.h [Kientzle] - -Changes in 1.2.1.1 (9 January 2004) -- Update email address in README -- Several FAQ updates -- Fix a big fat bug in inftrees.c that prevented decoding valid - dynamic blocks with only literals and no distance codes -- - Thanks to "Hot Emu" for the bug report and sample file -- Add a note to puff.c on no distance codes case. - -Changes in 1.2.1 (17 November 2003) -- Remove a tab in contrib/gzappend/gzappend.c -- Update some interfaces in contrib for new zlib functions -- Update zlib version number in some contrib entries -- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta] -- Support shared libraries on Hurd and KFreeBSD [Brown] -- Fix error in NO_DIVIDE option of adler32.c - -Changes in 1.2.0.8 (4 November 2003) -- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas -- Add experimental NO_DIVIDE #define in adler32.c - - Possibly faster on some processors (let me know if it is) -- Correct Z_BLOCK to not return on first inflate call if no wrap -- Fix strm->data_type on inflate() return to correctly indicate EOB -- Add deflatePrime() function for appending in the middle of a byte -- Add contrib/gzappend for an example of appending to a stream -- Update win32/DLL_FAQ.txt [Truta] -- Delete Turbo C comment in README [Truta] -- Improve some indentation in zconf.h [Truta] -- Fix infinite loop on bad input in configure script [Church] -- Fix gzeof() for concatenated gzip files [Johnson] -- Add example to contrib/visual-basic.txt [Michael B.] -- Add -p to mkdir's in Makefile.in [vda] -- Fix configure to properly detect presence or lack of printf functions -- Add AS400 support [Monnerat] -- Add a little Cygwin support [Wilson] - -Changes in 1.2.0.7 (21 September 2003) -- Correct some debug formats in contrib/infback9 -- Cast a type in a debug statement in trees.c -- Change search and replace delimiter in configure from % to # [Beebe] -- Update contrib/untgz to 0.2 with various fixes [Truta] -- Add build support for Amiga [Nikl] -- Remove some directories in old that have been updated to 1.2 -- Add dylib building for Mac OS X in configure and Makefile.in -- Remove old distribution stuff from Makefile -- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X -- Update links in README - -Changes in 1.2.0.6 (13 September 2003) -- Minor FAQ updates -- Update contrib/minizip to 1.00 [Vollant] -- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta] -- Update POSTINC comment for 68060 [Nikl] -- Add contrib/infback9 with deflate64 decoding (unsupported) -- For MVS define NO_vsnprintf and undefine FAR [van Burik] -- Add pragma for fdopen on MVS [van Burik] - -Changes in 1.2.0.5 (8 September 2003) -- Add OF to inflateBackEnd() declaration in zlib.h -- Remember start when using gzdopen in the middle of a file -- Use internal off_t counters in gz* functions to properly handle seeks -- Perform more rigorous check for distance-too-far in inffast.c -- Add Z_BLOCK flush option to return from inflate at block boundary -- Set strm->data_type on return from inflate - - Indicate bits unused, if at block boundary, and if in last block -- Replace size_t with ptrdiff_t in crc32.c, and check for correct size -- Add condition so old NO_DEFLATE define still works for compatibility -- FAQ update regarding the Windows DLL [Truta] -- INDEX update: add qnx entry, remove aix entry [Truta] -- Install zlib.3 into mandir [Wilson] -- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta] -- Adapt the zlib interface to the new DLL convention guidelines [Truta] -- Introduce ZLIB_WINAPI macro to allow the export of functions using - the WINAPI calling convention, for Visual Basic [Vollant, Truta] -- Update msdos and win32 scripts and makefiles [Truta] -- Export symbols by name, not by ordinal, in win32/zlib.def [Truta] -- Add contrib/ada [Anisimkov] -- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta] -- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant] -- Add contrib/masm686 [Truta] -- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm - [Truta, Vollant] -- Update contrib/delphi; rename to contrib/pascal; add example [Truta] -- Remove contrib/delphi2; add a new contrib/delphi [Truta] -- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream, - and fix some method prototypes [Truta] -- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip - [Truta] -- Avoid the use of backslash (\) in contrib/minizip [Vollant] -- Fix file time handling in contrib/untgz; update makefiles [Truta] -- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines - [Vollant] -- Remove contrib/vstudio/vc15_16 [Vollant] -- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta] -- Update README.contrib [Truta] -- Invert the assignment order of match_head and s->prev[...] in - INSERT_STRING [Truta] -- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings - [Truta] -- Compare function pointers with 0, not with NULL or Z_NULL [Truta] -- Fix prototype of syncsearch in inflate.c [Truta] -- Introduce ASMINF macro to be enabled when using an ASM implementation - of inflate_fast [Truta] -- Change NO_DEFLATE to NO_GZCOMPRESS [Truta] -- Modify test_gzio in example.c to take a single file name as a - parameter [Truta] -- Exit the example.c program if gzopen fails [Truta] -- Add type casts around strlen in example.c [Truta] -- Remove casting to sizeof in minigzip.c; give a proper type - to the variable compared with SUFFIX_LEN [Truta] -- Update definitions of STDC and STDC99 in zconf.h [Truta] -- Synchronize zconf.h with the new Windows DLL interface [Truta] -- Use SYS16BIT instead of __32BIT__ to distinguish between - 16- and 32-bit platforms [Truta] -- Use far memory allocators in small 16-bit memory models for - Turbo C [Truta] -- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in - zlibCompileFlags [Truta] -- Cygwin has vsnprintf [Wilson] -- In Windows16, OS_CODE is 0, as in MSDOS [Truta] -- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson] - -Changes in 1.2.0.4 (10 August 2003) -- Minor FAQ updates -- Be more strict when checking inflateInit2's windowBits parameter -- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well -- Add gzip wrapper option to deflateInit2 using windowBits -- Add updated QNX rule in configure and qnx directory [Bonnefoy] -- Make inflate distance-too-far checks more rigorous -- Clean up FAR usage in inflate -- Add casting to sizeof() in gzio.c and minigzip.c - -Changes in 1.2.0.3 (19 July 2003) -- Fix silly error in gzungetc() implementation [Vollant] -- Update contrib/minizip and contrib/vstudio [Vollant] -- Fix printf format in example.c -- Correct cdecl support in zconf.in.h [Anisimkov] -- Minor FAQ updates - -Changes in 1.2.0.2 (13 July 2003) -- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons -- Attempt to avoid warnings in crc32.c for pointer-int conversion -- Add AIX to configure, remove aix directory [Bakker] -- Add some casts to minigzip.c -- Improve checking after insecure sprintf() or vsprintf() calls -- Remove #elif's from crc32.c -- Change leave label to inf_leave in inflate.c and infback.c to avoid - library conflicts -- Remove inflate gzip decoding by default--only enable gzip decoding by - special request for stricter backward compatibility -- Add zlibCompileFlags() function to return compilation information -- More typecasting in deflate.c to avoid warnings -- Remove leading underscore from _Capital #defines [Truta] -- Fix configure to link shared library when testing -- Add some Windows CE target adjustments [Mai] -- Remove #define ZLIB_DLL in zconf.h [Vollant] -- Add zlib.3 [Rodgers] -- Update RFC URL in deflate.c and algorithm.txt [Mai] -- Add zlib_dll_FAQ.txt to contrib [Truta] -- Add UL to some constants [Truta] -- Update minizip and vstudio [Vollant] -- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h -- Expand use of NO_DUMMY_DECL to avoid all dummy structures -- Added iostream3 to contrib [Schwardt] -- Replace rewind() with fseek() for WinCE [Truta] -- Improve setting of zlib format compression level flags - - Report 0 for huffman and rle strategies and for level == 0 or 1 - - Report 2 only for level == 6 -- Only deal with 64K limit when necessary at compile time [Truta] -- Allow TOO_FAR check to be turned off at compile time [Truta] -- Add gzclearerr() function [Souza] -- Add gzungetc() function - -Changes in 1.2.0.1 (17 March 2003) -- Add Z_RLE strategy for run-length encoding [Truta] - - When Z_RLE requested, restrict matches to distance one - - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE -- Correct FASTEST compilation to allow level == 0 -- Clean up what gets compiled for FASTEST -- Incorporate changes to zconf.in.h [Vollant] - - Refine detection of Turbo C need for dummy returns - - Refine ZLIB_DLL compilation - - Include additional header file on VMS for off_t typedef -- Try to use _vsnprintf where it supplants vsprintf [Vollant] -- Add some casts in inffast.c -- Enchance comments in zlib.h on what happens if gzprintf() tries to - write more than 4095 bytes before compression -- Remove unused state from inflateBackEnd() -- Remove exit(0) from minigzip.c, example.c -- Get rid of all those darn tabs -- Add "check" target to Makefile.in that does the same thing as "test" -- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in -- Update contrib/inflate86 [Anderson] -- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant] -- Add msdos and win32 directories with makefiles [Truta] -- More additions and improvements to the FAQ - -Changes in 1.2.0 (9 March 2003) -- New and improved inflate code - - About 20% faster - - Does not allocate 32K window unless and until needed - - Automatically detects and decompresses gzip streams - - Raw inflate no longer needs an extra dummy byte at end - - Added inflateBack functions using a callback interface--even faster - than inflate, useful for file utilities (gzip, zip) - - Added inflateCopy() function to record state for random access on - externally generated deflate streams (e.g. in gzip files) - - More readable code (I hope) -- New and improved crc32() - - About 50% faster, thanks to suggestions from Rodney Brown -- Add deflateBound() and compressBound() functions -- Fix memory leak in deflateInit2() -- Permit setting dictionary for raw deflate (for parallel deflate) -- Fix const declaration for gzwrite() -- Check for some malloc() failures in gzio.c -- Fix bug in gzopen() on single-byte file 0x1f -- Fix bug in gzread() on concatenated file with 0x1f at end of buffer - and next buffer doesn't start with 0x8b -- Fix uncompress() to return Z_DATA_ERROR on truncated input -- Free memory at end of example.c -- Remove MAX #define in trees.c (conflicted with some libraries) -- Fix static const's in deflate.c, gzio.c, and zutil.[ch] -- Declare malloc() and free() in gzio.c if STDC not defined -- Use malloc() instead of calloc() in zutil.c if int big enough -- Define STDC for AIX -- Add aix/ with approach for compiling shared library on AIX -- Add HP-UX support for shared libraries in configure -- Add OpenUNIX support for shared libraries in configure -- Use $cc instead of gcc to build shared library -- Make prefix directory if needed when installing -- Correct Macintosh avoidance of typedef Byte in zconf.h -- Correct Turbo C memory allocation when under Linux -- Use libz.a instead of -lz in Makefile (assure use of compiled library) -- Update configure to check for snprintf or vsnprintf functions and their - return value, warn during make if using an insecure function -- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that - is lost when library is used--resolution is to build new zconf.h -- Documentation improvements (in zlib.h): - - Document raw deflate and inflate - - Update RFCs URL - - Point out that zlib and gzip formats are different - - Note that Z_BUF_ERROR is not fatal - - Document string limit for gzprintf() and possible buffer overflow - - Note requirement on avail_out when flushing - - Note permitted values of flush parameter of inflate() -- Add some FAQs (and even answers) to the FAQ -- Add contrib/inflate86/ for x86 faster inflate -- Add contrib/blast/ for PKWare Data Compression Library decompression -- Add contrib/puff/ simple inflate for deflate format description - -Changes in 1.1.4 (11 March 2002) -- ZFREE was repeated on same allocation on some error conditions. - This creates a security problem described in - http://www.zlib.org/advisory-2002-03-11.txt -- Returned incorrect error (Z_MEM_ERROR) on some invalid data -- Avoid accesses before window for invalid distances with inflate window - less than 32K. -- force windowBits > 8 to avoid a bug in the encoder for a window size - of 256 bytes. (A complete fix will be available in 1.1.5). - -Changes in 1.1.3 (9 July 1998) -- fix "an inflate input buffer bug that shows up on rare but persistent - occasions" (Mark) -- fix gzread and gztell for concatenated .gz files (Didier Le Botlan) -- fix gzseek(..., SEEK_SET) in write mode -- fix crc check after a gzeek (Frank Faubert) -- fix miniunzip when the last entry in a zip file is itself a zip file - (J Lillge) -- add contrib/asm586 and contrib/asm686 (Brian Raiter) - See http://www.muppetlabs.com/~breadbox/software/assembly.html -- add support for Delphi 3 in contrib/delphi (Bob Dellaca) -- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti) -- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren) -- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks) -- added a FAQ file - -- Support gzdopen on Mac with Metrowerks (Jason Linhart) -- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart) -- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young) -- avoid some warnings with Borland C (Tom Tanner) -- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant) -- emulate utime() for WIN32 in contrib/untgz (Gilles Vollant) -- allow several arguments to configure (Tim Mooney, Frodo Looijaard) -- use libdir and includedir in Makefile.in (Tim Mooney) -- support shared libraries on OSF1 V4 (Tim Mooney) -- remove so_locations in "make clean" (Tim Mooney) -- fix maketree.c compilation error (Glenn, Mark) -- Python interface to zlib now in Python 1.5 (Jeremy Hylton) -- new Makefile.riscos (Rich Walker) -- initialize static descriptors in trees.c for embedded targets (Nick Smith) -- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith) -- add the OS/2 files in Makefile.in too (Andrew Zabolotny) -- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane) -- fix maketree.c to allow clean compilation of inffixed.h (Mark) -- fix parameter check in deflateCopy (Gunther Nikl) -- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler) -- Many portability patches by Christian Spieler: - . zutil.c, zutil.h: added "const" for zmem* - . Make_vms.com: fixed some typos - . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists - . msdos/Makefile.msc: remove "default rtl link library" info from obj files - . msdos/Makefile.*: use model-dependent name for the built zlib library - . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc: - new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT) -- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane) -- replace __far with _far for better portability (Christian Spieler, Tom Lane) -- fix test for errno.h in configure (Tim Newsham) - -Changes in 1.1.2 (19 March 98) -- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant) - See http://www.winimage.com/zLibDll/unzip.html -- preinitialize the inflate tables for fixed codes, to make the code - completely thread safe (Mark) -- some simplifications and slight speed-up to the inflate code (Mark) -- fix gzeof on non-compressed files (Allan Schrum) -- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs) -- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn) -- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny) -- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori) -- do not wrap extern "C" around system includes (Tom Lane) -- mention zlib binding for TCL in README (Andreas Kupries) -- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert) -- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson) -- allow "configure --prefix $HOME" (Tim Mooney) -- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson) -- move Makefile.sas to amiga/Makefile.sas - -Changes in 1.1.1 (27 Feb 98) -- fix macros _tr_tally_* in deflate.h for debug mode (Glenn Randers-Pehrson) -- remove block truncation heuristic which had very marginal effect for zlib - (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the - compression ratio on some files. This also allows inlining _tr_tally for - matches in deflate_slow. -- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier) - -Changes in 1.1.0 (24 Feb 98) -- do not return STREAM_END prematurely in inflate (John Bowler) -- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler) -- compile with -DFASTEST to get compression code optimized for speed only -- in minigzip, try mmap'ing the input file first (Miguel Albrecht) -- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain - on Sun but significant on HP) - -- add a pointer to experimental unzip library in README (Gilles Vollant) -- initialize variable gcc in configure (Chris Herborth) - -Changes in 1.0.9 (17 Feb 1998) -- added gzputs and gzgets functions -- do not clear eof flag in gzseek (Mark Diekhans) -- fix gzseek for files in transparent mode (Mark Diekhans) -- do not assume that vsprintf returns the number of bytes written (Jens Krinke) -- replace EXPORT with ZEXPORT to avoid conflict with other programs -- added compress2 in zconf.h, zlib.def, zlib.dnt -- new asm code from Gilles Vollant in contrib/asm386 -- simplify the inflate code (Mark): - . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new() - . ZALLOC the length list in inflate_trees_fixed() instead of using stack - . ZALLOC the value area for huft_build() instead of using stack - . Simplify Z_FINISH check in inflate() - -- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8 -- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi) -- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with - the declaration of FAR (Gilles VOllant) -- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann) -- read_buf buf parameter of type Bytef* instead of charf* -- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout) -- do not redeclare unlink in minigzip.c for WIN32 (John Bowler) -- fix check for presence of directories in "make install" (Ian Willis) - -Changes in 1.0.8 (27 Jan 1998) -- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant) -- fix gzgetc and gzputc for big endian systems (Markus Oberhumer) -- added compress2() to allow setting the compression level -- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong) -- use constant arrays for the static trees in trees.c instead of computing - them at run time (thanks to Ken Raeburn for this suggestion). To create - trees.h, compile with GEN_TREES_H and run "make test". -- check return code of example in "make test" and display result -- pass minigzip command line options to file_compress -- simplifying code of inflateSync to avoid gcc 2.8 bug - -- support CC="gcc -Wall" in configure -s (QingLong) -- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn) -- fix test for shared library support to avoid compiler warnings -- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant) -- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit) -- do not use fdopen for Metrowerks on Mac (Brad Pettit)) -- add checks for gzputc and gzputc in example.c -- avoid warnings in gzio.c and deflate.c (Andreas Kleinert) -- use const for the CRC table (Ken Raeburn) -- fixed "make uninstall" for shared libraries -- use Tracev instead of Trace in infblock.c -- in example.c use correct compressed length for test_sync -- suppress +vnocompatwarnings in configure for HPUX (not always supported) - -Changes in 1.0.7 (20 Jan 1998) -- fix gzseek which was broken in write mode -- return error for gzseek to negative absolute position -- fix configure for Linux (Chun-Chung Chen) -- increase stack space for MSC (Tim Wegner) -- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant) -- define EXPORTVA for gzprintf (Gilles Vollant) -- added man page zlib.3 (Rick Rodgers) -- for contrib/untgz, fix makedir() and improve Makefile - -- check gzseek in write mode in example.c -- allocate extra buffer for seeks only if gzseek is actually called -- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant) -- add inflateSyncPoint in zconf.h -- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def - -Changes in 1.0.6 (19 Jan 1998) -- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and - gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code) -- Fix a deflate bug occurring only with compression level 0 (thanks to - Andy Buckler for finding this one). -- In minigzip, pass transparently also the first byte for .Z files. -- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress() -- check Z_FINISH in inflate (thanks to Marc Schluper) -- Implement deflateCopy (thanks to Adam Costello) -- make static libraries by default in configure, add --shared option. -- move MSDOS or Windows specific files to directory msdos -- suppress the notion of partial flush to simplify the interface - (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4) -- suppress history buffer provided by application to simplify the interface - (this feature was not implemented anyway in 1.0.4) -- next_in and avail_in must be initialized before calling inflateInit or - inflateInit2 -- add EXPORT in all exported functions (for Windows DLL) -- added Makefile.nt (thanks to Stephen Williams) -- added the unsupported "contrib" directory: - contrib/asm386/ by Gilles Vollant <[email protected]> - 386 asm code replacing longest_match(). - contrib/iostream/ by Kevin Ruland <[email protected]> - A C++ I/O streams interface to the zlib gz* functions - contrib/iostream2/ by Tyge L�vset <[email protected]> - Another C++ I/O streams interface - contrib/untgz/ by "Pedro A. Aranda Guti\irrez" <[email protected]> - A very simple tar.gz file extractor using zlib - contrib/visual-basic.txt by Carlos Rios <[email protected]> - How to use compress(), uncompress() and the gz* functions from VB. -- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression - level) in minigzip (thanks to Tom Lane) - -- use const for rommable constants in deflate -- added test for gzseek and gztell in example.c -- add undocumented function inflateSyncPoint() (hack for Paul Mackerras) -- add undocumented function zError to convert error code to string - (for Tim Smithers) -- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code. -- Use default memcpy for Symantec MSDOS compiler. -- Add EXPORT keyword for check_func (needed for Windows DLL) -- add current directory to LD_LIBRARY_PATH for "make test" -- create also a link for libz.so.1 -- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura) -- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX) -- added -soname for Linux in configure (Chun-Chung Chen, -- assign numbers to the exported functions in zlib.def (for Windows DLL) -- add advice in zlib.h for best usage of deflateSetDictionary -- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn) -- allow compilation with ANSI keywords only enabled for TurboC in large model -- avoid "versionString"[0] (Borland bug) -- add NEED_DUMMY_RETURN for Borland -- use variable z_verbose for tracing in debug mode (L. Peter Deutsch). -- allow compilation with CC -- defined STDC for OS/2 (David Charlap) -- limit external names to 8 chars for MVS (Thomas Lund) -- in minigzip.c, use static buffers only for 16-bit systems -- fix suffix check for "minigzip -d foo.gz" -- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee) -- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau) -- added makelcc.bat for lcc-win32 (Tom St Denis) -- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe) -- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion. -- check for unistd.h in configure (for off_t) -- remove useless check parameter in inflate_blocks_free -- avoid useless assignment of s->check to itself in inflate_blocks_new -- do not flush twice in gzclose (thanks to Ken Raeburn) -- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h -- use NO_ERRNO_H instead of enumeration of operating systems with errno.h -- work around buggy fclose on pipes for HP/UX -- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson) -- fix configure if CC is already equal to gcc - -Changes in 1.0.5 (3 Jan 98) -- Fix inflate to terminate gracefully when fed corrupted or invalid data -- Use const for rommable constants in inflate -- Eliminate memory leaks on error conditions in inflate -- Removed some vestigial code in inflate -- Update web address in README - -Changes in 1.0.4 (24 Jul 96) -- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF - bit, so the decompressor could decompress all the correct data but went - on to attempt decompressing extra garbage data. This affected minigzip too. -- zlibVersion and gzerror return const char* (needed for DLL) -- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno) -- use z_error only for DEBUG (avoid problem with DLLs) - -Changes in 1.0.3 (2 Jul 96) -- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS - small and medium models; this makes the library incompatible with previous - versions for these models. (No effect in large model or on other systems.) -- return OK instead of BUF_ERROR if previous deflate call returned with - avail_out as zero but there is nothing to do -- added memcmp for non STDC compilers -- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly) -- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO) -- better check for 16-bit mode MSC (avoids problem with Symantec) - -Changes in 1.0.2 (23 May 96) -- added Windows DLL support -- added a function zlibVersion (for the DLL support) -- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model) -- Bytef is define's instead of typedef'd only for Borland C -- avoid reading uninitialized memory in example.c -- mention in README that the zlib format is now RFC1950 -- updated Makefile.dj2 -- added algorithm.doc - -Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion] -- fix array overlay in deflate.c which sometimes caused bad compressed data -- fix inflate bug with empty stored block -- fix MSDOS medium model which was broken in 0.99 -- fix deflateParams() which could generated bad compressed data. -- Bytef is define'd instead of typedef'ed (work around Borland bug) -- added an INDEX file -- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32), - Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas) -- speed up adler32 for modern machines without auto-increment -- added -ansi for IRIX in configure -- static_init_done in trees.c is an int -- define unlink as delete for VMS -- fix configure for QNX -- add configure branch for SCO and HPUX -- avoid many warnings (unused variables, dead assignments, etc...) -- no fdopen for BeOS -- fix the Watcom fix for 32 bit mode (define FAR as empty) -- removed redefinition of Byte for MKWERKS -- work around an MWKERKS bug (incorrect merge of all .h files) - -Changes in 0.99 (27 Jan 96) -- allow preset dictionary shared between compressor and decompressor -- allow compression level 0 (no compression) -- add deflateParams in zlib.h: allow dynamic change of compression level - and compression strategy. -- test large buffers and deflateParams in example.c -- add optional "configure" to build zlib as a shared library -- suppress Makefile.qnx, use configure instead -- fixed deflate for 64-bit systems (detected on Cray) -- fixed inflate_blocks for 64-bit systems (detected on Alpha) -- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2) -- always return Z_BUF_ERROR when deflate() has nothing to do -- deflateInit and inflateInit are now macros to allow version checking -- prefix all global functions and types with z_ with -DZ_PREFIX -- make falloc completely reentrant (inftrees.c) -- fixed very unlikely race condition in ct_static_init -- free in reverse order of allocation to help memory manager -- use zlib-1.0/* instead of zlib/* inside the tar.gz -- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith - -Wconversion -Wstrict-prototypes -Wmissing-prototypes" -- allow gzread on concatenated .gz files -- deflateEnd now returns Z_DATA_ERROR if it was premature -- deflate is finally (?) fully deterministic (no matches beyond end of input) -- Document Z_SYNC_FLUSH -- add uninstall in Makefile -- Check for __cpluplus in zlib.h -- Better test in ct_align for partial flush -- avoid harmless warnings for Borland C++ -- initialize hash_head in deflate.c -- avoid warning on fdopen (gzio.c) for HP cc -Aa -- include stdlib.h for STDC compilers -- include errno.h for Cray -- ignore error if ranlib doesn't exist -- call ranlib twice for NeXTSTEP -- use exec_prefix instead of prefix for libz.a -- renamed ct_* as _tr_* to avoid conflict with applications -- clear z->msg in inflateInit2 before any error return -- initialize opaque in example.c, gzio.c, deflate.c and inflate.c -- fixed typo in zconf.h (_GNUC__ => __GNUC__) -- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode) -- fix typo in Make_vms.com (f$trnlnm -> f$getsyi) -- in fcalloc, normalize pointer if size > 65520 bytes -- don't use special fcalloc for 32 bit Borland C++ -- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc... -- use Z_BINARY instead of BINARY -- document that gzclose after gzdopen will close the file -- allow "a" as mode in gzopen. -- fix error checking in gzread -- allow skipping .gz extra-field on pipes -- added reference to Perl interface in README -- put the crc table in FAR data (I dislike more and more the medium model :) -- added get_crc_table -- added a dimension to all arrays (Borland C can't count). -- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast -- guard against multiple inclusion of *.h (for precompiled header on Mac) -- Watcom C pretends to be Microsoft C small model even in 32 bit mode. -- don't use unsized arrays to avoid silly warnings by Visual C++: - warning C4746: 'inflate_mask' : unsized array treated as '__far' - (what's wrong with far data in far model?). -- define enum out of inflate_blocks_state to allow compilation with C++ - -Changes in 0.95 (16 Aug 95) -- fix MSDOS small and medium model (now easier to adapt to any compiler) -- inlined send_bits -- fix the final (:-) bug for deflate with flush (output was correct but - not completely flushed in rare occasions). -- default window size is same for compression and decompression - (it's now sufficient to set MAX_WBITS in zconf.h). -- voidp -> voidpf and voidnp -> voidp (for consistency with other - typedefs and because voidnp was not near in large model). - -Changes in 0.94 (13 Aug 95) -- support MSDOS medium model -- fix deflate with flush (could sometimes generate bad output) -- fix deflateReset (zlib header was incorrectly suppressed) -- added support for VMS -- allow a compression level in gzopen() -- gzflush now calls fflush -- For deflate with flush, flush even if no more input is provided. -- rename libgz.a as libz.a -- avoid complex expression in infcodes.c triggering Turbo C bug -- work around a problem with gcc on Alpha (in INSERT_STRING) -- don't use inline functions (problem with some gcc versions) -- allow renaming of Byte, uInt, etc... with #define. -- avoid warning about (unused) pointer before start of array in deflate.c -- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c -- avoid reserved word 'new' in trees.c - -Changes in 0.93 (25 June 95) -- temporarily disable inline functions -- make deflate deterministic -- give enough lookahead for PARTIAL_FLUSH -- Set binary mode for stdin/stdout in minigzip.c for OS/2 -- don't even use signed char in inflate (not portable enough) -- fix inflate memory leak for segmented architectures - -Changes in 0.92 (3 May 95) -- don't assume that char is signed (problem on SGI) -- Clear bit buffer when starting a stored block -- no memcpy on Pyramid -- suppressed inftest.c -- optimized fill_window, put longest_match inline for gcc -- optimized inflate on stored blocks. -- untabify all sources to simplify patches - -Changes in 0.91 (2 May 95) -- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h -- Document the memory requirements in zconf.h -- added "make install" -- fix sync search logic in inflateSync -- deflate(Z_FULL_FLUSH) now works even if output buffer too short -- after inflateSync, don't scare people with just "lo world" -- added support for DJGPP - -Changes in 0.9 (1 May 95) -- don't assume that zalloc clears the allocated memory (the TurboC bug - was Mark's bug after all :) -- let again gzread copy uncompressed data unchanged (was working in 0.71) -- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented -- added a test of inflateSync in example.c -- moved MAX_WBITS to zconf.h because users might want to change that. -- document explicitly that zalloc(64K) on MSDOS must return a normalized - pointer (zero offset) -- added Makefiles for Microsoft C, Turbo C, Borland C++ -- faster crc32() - -Changes in 0.8 (29 April 95) -- added fast inflate (inffast.c) -- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this - is incompatible with previous versions of zlib which returned Z_OK. -- work around a TurboC compiler bug (bad code for b << 0, see infutil.h) - (actually that was not a compiler bug, see 0.81 above) -- gzread no longer reads one extra byte in certain cases -- In gzio destroy(), don't reference a freed structure -- avoid many warnings for MSDOS -- avoid the ERROR symbol which is used by MS Windows - -Changes in 0.71 (14 April 95) -- Fixed more MSDOS compilation problems :( There is still a bug with - TurboC large model. - -Changes in 0.7 (14 April 95) -- Added full inflate support. -- Simplified the crc32() interface. The pre- and post-conditioning - (one's complement) is now done inside crc32(). WARNING: this is - incompatible with previous versions; see zlib.h for the new usage. - -Changes in 0.61 (12 April 95) -- workaround for a bug in TurboC. example and minigzip now work on MSDOS. - -Changes in 0.6 (11 April 95) -- added minigzip.c -- added gzdopen to reopen a file descriptor as gzFile -- added transparent reading of non-gziped files in gzread. -- fixed bug in gzread (don't read crc as data) -- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose). -- don't allocate big arrays in the stack (for MSDOS) -- fix some MSDOS compilation problems - -Changes in 0.5: -- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but - not yet Z_FULL_FLUSH. -- support decompression but only in a single step (forced Z_FINISH) -- added opaque object for zalloc and zfree. -- added deflateReset and inflateReset -- added a variable zlib_version for consistency checking. -- renamed the 'filter' parameter of deflateInit2 as 'strategy'. - Added Z_FILTERED and Z_HUFFMAN_ONLY constants. - -Changes in 0.4: -- avoid "zip" everywhere, use zlib instead of ziplib. -- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush - if compression method == 8. -- added adler32 and crc32 -- renamed deflateOptions as deflateInit2, call one or the other but not both -- added the method parameter for deflateInit2. -- added inflateInit2 -- simplied considerably deflateInit and inflateInit by not supporting - user-provided history buffer. This is supported only in deflateInit2 - and inflateInit2. - -Changes in 0.3: -- prefix all macro names with Z_ -- use Z_FINISH instead of deflateEnd to finish compression. -- added Z_HUFFMAN_ONLY -- added gzerror() diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/FAQ b/components/dfs/filesystems/jffs2/cyg/compress/src/FAQ deleted file mode 100644 index 441d910daa..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/FAQ +++ /dev/null @@ -1,339 +0,0 @@ - - Frequently Asked Questions about zlib - - -If your question is not there, please check the zlib home page -http://www.zlib.org which may have more recent information. -The lastest zlib FAQ is at http://www.gzip.org/zlib/zlib_faq.html - - - 1. Is zlib Y2K-compliant? - - Yes. zlib doesn't handle dates. - - 2. Where can I get a Windows DLL version? - - The zlib sources can be compiled without change to produce a DLL. - See the file win32/DLL_FAQ.txt in the zlib distribution. - Pointers to the precompiled DLL are found in the zlib web site at - http://www.zlib.org. - - 3. Where can I get a Visual Basic interface to zlib? - - See - * http://www.dogma.net/markn/articles/zlibtool/zlibtool.htm - * contrib/visual-basic.txt in the zlib distribution - * win32/DLL_FAQ.txt in the zlib distribution - - 4. compress() returns Z_BUF_ERROR. - - Make sure that before the call of compress, the length of the compressed - buffer is equal to the total size of the compressed buffer and not - zero. For Visual Basic, check that this parameter is passed by reference - ("as any"), not by value ("as long"). - - 5. deflate() or inflate() returns Z_BUF_ERROR. - - Before making the call, make sure that avail_in and avail_out are not - zero. When setting the parameter flush equal to Z_FINISH, also make sure - that avail_out is big enough to allow processing all pending input. - Note that a Z_BUF_ERROR is not fatal--another call to deflate() or - inflate() can be made with more input or output space. A Z_BUF_ERROR - may in fact be unavoidable depending on how the functions are used, since - it is not possible to tell whether or not there is more output pending - when strm.avail_out returns with zero. - - 6. Where's the zlib documentation (man pages, etc.)? - - It's in zlib.h for the moment, and Francis S. Lin has converted it to a - web page zlib.html. Volunteers to transform this to Unix-style man pages, - please contact us ([email protected]). Examples of zlib usage are in the files - example.c and minigzip.c. - - 7. Why don't you use GNU autoconf or libtool or ...? - - Because we would like to keep zlib as a very small and simple - package. zlib is rather portable and doesn't need much configuration. - - 8. I found a bug in zlib. - - Most of the time, such problems are due to an incorrect usage of - zlib. Please try to reproduce the problem with a small program and send - the corresponding source to us at [email protected] . Do not send - multi-megabyte data files without prior agreement. - - 9. Why do I get "undefined reference to gzputc"? - - If "make test" produces something like - - example.o(.text+0x154): undefined reference to `gzputc' - - check that you don't have old files libz.* in /usr/lib, /usr/local/lib or - /usr/X11R6/lib. Remove any old versions, then do "make install". - -10. I need a Delphi interface to zlib. - - See the contrib/delphi directory in the zlib distribution. - -11. Can zlib handle .zip archives? - - Not by itself, no. See the directory contrib/minizip in the zlib - distribution. - -12. Can zlib handle .Z files? - - No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt - the code of uncompress on your own. - -13. How can I make a Unix shared library? - - make clean - ./configure -s - make - -14. How do I install a shared zlib library on Unix? - - After the above, then: - - make install - - However, many flavors of Unix come with a shared zlib already installed. - Before going to the trouble of compiling a shared version of zlib and - trying to install it, you may want to check if it's already there! If you - can #include <zlib.h>, it's there. The -lz option will probably link to it. - -15. I have a question about OttoPDF. - - We are not the authors of OttoPDF. The real author is on the OttoPDF web - site: Joel Hainley, [email protected]. - -16. Can zlib decode Flate data in an Adobe PDF file? - - Yes. See http://www.fastio.com/ (ClibPDF), or http://www.pdflib.com/ . - To modify PDF forms, see http://sourceforge.net/projects/acroformtool/ . - -17. Why am I getting this "register_frame_info not found" error on Solaris? - - After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib - generates an error such as: - - ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: - symbol __register_frame_info: referenced symbol not found - - The symbol __register_frame_info is not part of zlib, it is generated by - the C compiler (cc or gcc). You must recompile applications using zlib - which have this problem. This problem is specific to Solaris. See - http://www.sunfreeware.com for Solaris versions of zlib and applications - using zlib. - -18. Why does gzip give an error on a file I make with compress/deflate? - - The compress and deflate functions produce data in the zlib format, which - is different and incompatible with the gzip format. The gz* functions in - zlib on the other hand use the gzip format. Both the zlib and gzip - formats use the same compressed data format internally, but have different - headers and trailers around the compressed data. - -19. Ok, so why are there two different formats? - - The gzip format was designed to retain the directory information about - a single file, such as the name and last modification date. The zlib - format on the other hand was designed for in-memory and communication - channel applications, and has a much more compact header and trailer and - uses a faster integrity check than gzip. - -20. Well that's nice, but how do I make a gzip file in memory? - - You can request that deflate write the gzip format instead of the zlib - format using deflateInit2(). You can also request that inflate decode - the gzip format using inflateInit2(). Read zlib.h for more details. - -21. Is zlib thread-safe? - - Yes. However any library routines that zlib uses and any application- - provided memory allocation routines must also be thread-safe. zlib's gz* - functions use stdio library routines, and most of zlib's functions use the - library memory allocation routines by default. zlib's Init functions allow - for the application to provide custom memory allocation routines. - - Of course, you should only operate on any given zlib or gzip stream from a - single thread at a time. - -22. Can I use zlib in my commercial application? - - Yes. Please read the license in zlib.h. - -23. Is zlib under the GNU license? - - No. Please read the license in zlib.h. - -24. The license says that altered source versions must be "plainly marked". So - what exactly do I need to do to meet that requirement? - - You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In - particular, the final version number needs to be changed to "f", and an - identification string should be appended to ZLIB_VERSION. Version numbers - x.x.x.f are reserved for modifications to zlib by others than the zlib - maintainers. For example, if the version of the base zlib you are altering - is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and - ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also - update the version strings in deflate.c and inftrees.c. - - For altered source distributions, you should also note the origin and - nature of the changes in zlib.h, as well as in ChangeLog and README, along - with the dates of the alterations. The origin should include at least your - name (or your company's name), and an email address to contact for help or - issues with the library. - - Note that distributing a compiled zlib library along with zlib.h and - zconf.h is also a source distribution, and so you should change - ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes - in zlib.h as you would for a full source distribution. - -25. Will zlib work on a big-endian or little-endian architecture, and can I - exchange compressed data between them? - - Yes and yes. - -26. Will zlib work on a 64-bit machine? - - It should. It has been tested on 64-bit machines, and has no dependence - on any data types being limited to 32-bits in length. If you have any - difficulties, please provide a complete problem report to [email protected] - -27. Will zlib decompress data from the PKWare Data Compression Library? - - No. The PKWare DCL uses a completely different compressed data format - than does PKZIP and zlib. However, you can look in zlib's contrib/blast - directory for a possible solution to your problem. - -28. Can I access data randomly in a compressed stream? - - No, not without some preparation. If when compressing you periodically - use Z_FULL_FLUSH, carefully write all the pending data at those points, - and keep an index of those locations, then you can start decompression - at those points. You have to be careful to not use Z_FULL_FLUSH too - often, since it can significantly degrade compression. - -29. Does zlib work on MVS, OS/390, CICS, etc.? - - We don't know for sure. We have heard occasional reports of success on - these systems. If you do use it on one of these, please provide us with - a report, instructions, and patches that we can reference when we get - these questions. Thanks. - -30. Is there some simpler, easier to read version of inflate I can look at - to understand the deflate format? - - First off, you should read RFC 1951. Second, yes. Look in zlib's - contrib/puff directory. - -31. Does zlib infringe on any patents? - - As far as we know, no. In fact, that was originally the whole point behind - zlib. Look here for some more information: - - http://www.gzip.org/#faq11 - -32. Can zlib work with greater than 4 GB of data? - - Yes. inflate() and deflate() will process any amount of data correctly. - Each call of inflate() or deflate() is limited to input and output chunks - of the maximum value that can be stored in the compiler's "unsigned int" - type, but there is no limit to the number of chunks. Note however that the - strm.total_in and strm_total_out counters may be limited to 4 GB. These - counters are provided as a convenience and are not used internally by - inflate() or deflate(). The application can easily set up its own counters - updated after each call of inflate() or deflate() to count beyond 4 GB. - compress() and uncompress() may be limited to 4 GB, since they operate in a - single call. gzseek() and gztell() may be limited to 4 GB depending on how - zlib is compiled. See the zlibCompileFlags() function in zlib.h. - - The word "may" appears several times above since there is a 4 GB limit - only if the compiler's "long" type is 32 bits. If the compiler's "long" - type is 64 bits, then the limit is 16 exabytes. - -33. Does zlib have any security vulnerabilities? - - The only one that we are aware of is potentially in gzprintf(). If zlib - is compiled to use sprintf() or vsprintf(), then there is no protection - against a buffer overflow of a 4K string space, other than the caller of - gzprintf() assuring that the output will not exceed 4K. On the other - hand, if zlib is compiled to use snprintf() or vsnprintf(), which should - normally be the case, then there is no vulnerability. The ./configure - script will display warnings if an insecure variation of sprintf() will - be used by gzprintf(). Also the zlibCompileFlags() function will return - information on what variant of sprintf() is used by gzprintf(). - - If you don't have snprintf() or vsnprintf() and would like one, you can - find a portable implementation here: - - http://www.ijs.si/software/snprintf/ - - Note that you should be using the most recent version of zlib. Versions - 1.1.3 and before were subject to a double-free vulnerability. - -34. Is there a Java version of zlib? - - Probably what you want is to use zlib in Java. zlib is already included - as part of the Java SDK in the java.util.zip package. If you really want - a version of zlib written in the Java language, look on the zlib home - page for links: http://www.zlib.org/ - -35. I get this or that compiler or source-code scanner warning when I crank it - up to maximally-pedantic. Can't you guys write proper code? - - Many years ago, we gave up attempting to avoid warnings on every compiler - in the universe. It just got to be a waste of time, and some compilers - were downright silly. So now, we simply make sure that the code always - works. - -36. Valgrind (or some similar memory access checker) says that deflate is - performing a conditional jump that depends on an uninitialized value. - Isn't that a bug? - - No. That is intentional for performance reasons, and the output of - deflate is not affected. This only started showing up recently since - zlib 1.2.x uses malloc() by default for allocations, whereas earlier - versions used calloc(), which zeros out the allocated memory. - -37. Will zlib read the (insert any ancient or arcane format here) compressed - data format? - - Probably not. Look in the comp.compression FAQ for pointers to various - formats and associated software. - -38. How can I encrypt/decrypt zip files with zlib? - - zlib doesn't support encryption. The original PKZIP encryption is very weak - and can be broken with freely available programs. To get strong encryption, - use GnuPG, http://www.gnupg.org/ , which already includes zlib compression. - For PKZIP compatible "encryption", look at http://www.info-zip.org/ - -39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? - - "gzip" is the gzip format, and "deflate" is the zlib format. They should - probably have called the second one "zlib" instead to avoid confusion - with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 - correctly points to the zlib specification in RFC 1950 for the "deflate" - transfer encoding, there have been reports of servers and browsers that - incorrectly produce or expect raw deflate data per the deflate - specficiation in RFC 1951, most notably Microsoft. So even though the - "deflate" transfer encoding using the zlib format would be the more - efficient approach (and in fact exactly what the zlib format was designed - for), using the "gzip" transfer encoding is probably more reliable due to - an unfortunate choice of name on the part of the HTTP 1.1 authors. - - Bottom line: use the gzip format for HTTP 1.1 encoding. - -40. Does zlib support the new "Deflate64" format introduced by PKWare? - - No. PKWare has apparently decided to keep that format proprietary, since - they have not documented it as they have previous compression formats. - In any case, the compression improvements are so modest compared to other - more modern approaches, that it's not worth the effort to implement. - -41. Can you please sign these lengthy legal documents and fax them back to us - so that we can use your software in our product? - - No. Go away. Shoo. diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/INDEX b/components/dfs/filesystems/jffs2/cyg/compress/src/INDEX deleted file mode 100644 index 0587e5902b..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/INDEX +++ /dev/null @@ -1,51 +0,0 @@ -ChangeLog history of changes -FAQ Frequently Asked Questions about zlib -INDEX this file -Makefile makefile for Unix (generated by configure) -Makefile.in makefile for Unix (template for configure) -README guess what -algorithm.txt description of the (de)compression algorithm -configure configure script for Unix -zconf.in.h template for zconf.h (used by configure) - -amiga/ makefiles for Amiga SAS C -as400/ makefiles for IBM AS/400 -msdos/ makefiles for MSDOS -old/ makefiles for various architectures and zlib documentation - files that have not yet been updated for zlib 1.2.x -projects/ projects for various Integrated Development Environments -qnx/ makefiles for QNX -win32/ makefiles for Windows - - zlib public header files (must be kept): -zconf.h -zlib.h - - private source files used to build the zlib library: -adler32.c -compress.c -crc32.c -crc32.h -deflate.c -deflate.h -gzio.c -infback.c -inffast.c -inffast.h -inffixed.h -inflate.c -inflate.h -inftrees.c -inftrees.h -trees.c -trees.h -uncompr.c -zutil.c -zutil.h - - source files for sample programs: -example.c -minigzip.c - - unsupported contribution by third parties -See contrib/README.contrib diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/Make_vms.com b/components/dfs/filesystems/jffs2/cyg/compress/src/Make_vms.com deleted file mode 100644 index c2a1fb54b2..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/Make_vms.com +++ /dev/null @@ -1,461 +0,0 @@ -$! make libz under VMS written by -$! Martin P.J. Zinser -$! <[email protected] or [email protected]> -$! -$ on error then goto err_exit -$! -$! -$! Just some general constants... -$! -$ true = 1 -$ false = 0 -$ tmpnam = "temp_" + f$getjpi("","pid") -$ SAY = "WRITE SYS$OUTPUT" -$! -$! Setup variables holding "config" information -$! -$ Make = "" -$ name = "Zlib" -$ version = "?.?.?" -$ v_string = "ZLIB_VERSION" -$ v_file = "zlib.h" -$ ccopt = "" -$ lopts = "" -$ linkonly = false -$ optfile = name + ".opt" -$ its_decc = false -$ its_vaxc = false -$ its_gnuc = false -$ axp = f$getsyi("HW_MODEL").ge.1024 -$ s_case = false -$! Check for MMK/MMS -$! -$ If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS" -$ If F$Type (MMK) .eqs. "STRING" Then Make = "MMK" -$! -$! -$ gosub find_version -$! -$ gosub check_opts -$! -$! Look for the compiler used -$! -$ gosub check_compiler -$ if its_decc -$ then -$ ccopt = "/prefix=all" + ccopt -$ if f$trnlnm("SYS") .eqs. "" -$ then -$ if axp -$ then -$ define sys sys$library: -$ else -$ ccopt = "/decc" + ccopt -$ define sys decc$library_include: -$ endif -$ endif -$ endif -$ if its_vaxc .or. its_gnuc -$ then -$ if f$trnlnm("SYS").eqs."" then define sys sys$library: -$ endif -$! -$! Build the thing plain or with mms -$! -$ write sys$output "Compiling Zlib sources ..." -$ if make.eqs."" -$ then -$ dele example.obj;*,minigzip.obj;* -$ CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" - - adler32.c zlib.h zconf.h -$ CALL MAKE compress.OBJ "CC ''CCOPT' compress" - - compress.c zlib.h zconf.h -$ CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" - - crc32.c zlib.h zconf.h -$ CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" - - deflate.c deflate.h zutil.h zlib.h zconf.h -$ CALL MAKE gzio.OBJ "CC ''CCOPT' gzio" - - gzio.c zutil.h zlib.h zconf.h -$ CALL MAKE infback.OBJ "CC ''CCOPT' infback" - - infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h -$ CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" - - inffast.c zutil.h zlib.h zconf.h inffast.h -$ CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" - - inflate.c zutil.h zlib.h zconf.h infblock.h -$ CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" - - inftrees.c zutil.h zlib.h zconf.h inftrees.h -$ CALL MAKE trees.OBJ "CC ''CCOPT' trees" - - trees.c deflate.h zutil.h zlib.h zconf.h -$ CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" - - uncompr.c zlib.h zconf.h -$ CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" - - zutil.c zutil.h zlib.h zconf.h -$ write sys$output "Building Zlib ..." -$ CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ -$ write sys$output "Building example..." -$ CALL MAKE example.OBJ "CC ''CCOPT' example" - - example.c zlib.h zconf.h -$ call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb -$ if f$search("x11vms:xvmsutils.olb") .nes. "" -$ then -$ write sys$output "Building minigzip..." -$ CALL MAKE minigzip.OBJ "CC ''CCOPT' minigzip" - - minigzip.c zlib.h zconf.h -$ call make minigzip.exe - - "LINK minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib" - - minigzip.obj libz.olb -$ endif -$ else -$ gosub crea_mms -$ SAY "Make ''name' ''version' with ''Make' " -$ 'make' -$ endif -$! -$! Alpha gets a shareable image -$! -$ If axp -$ Then -$ gosub crea_olist -$ write sys$output "Creating libzshr.exe" -$ call anal_obj_axp modules.opt _link.opt -$ if s_case -$ then -$ open/append optf modules.opt -$ write optf "case_sensitive=YES" -$ close optf -$ endif -$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,_link.opt/opt -$ endif -$ write sys$output "Zlib build completed" -$ exit -$CC_ERR: -$ write sys$output "C compiler required to build ''name'" -$ goto err_exit -$ERR_EXIT: -$ set message/facil/ident/sever/text -$ write sys$output "Exiting..." -$ exit 2 -$! -$! -$MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES -$ V = 'F$Verify(0) -$! P1 = What we are trying to make -$! P2 = Command to make it -$! P3 - P8 What it depends on -$ -$ If F$Search(P1) .Eqs. "" Then Goto Makeit -$ Time = F$CvTime(F$File(P1,"RDT")) -$arg=3 -$Loop: -$ Argument = P'arg -$ If Argument .Eqs. "" Then Goto Exit -$ El=0 -$Loop2: -$ File = F$Element(El," ",Argument) -$ If File .Eqs. " " Then Goto Endl -$ AFile = "" -$Loop3: -$ OFile = AFile -$ AFile = F$Search(File) -$ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl -$ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit -$ Goto Loop3 -$NextEL: -$ El = El + 1 -$ Goto Loop2 -$EndL: -$ arg=arg+1 -$ If arg .Le. 8 Then Goto Loop -$ Goto Exit -$ -$Makeit: -$ VV=F$VERIFY(0) -$ write sys$output P2 -$ 'P2 -$ VV='F$Verify(VV) -$Exit: -$ If V Then Set Verify -$ENDSUBROUTINE -$!------------------------------------------------------------------------------ -$! -$! Check command line options and set symbols accordingly -$! -$ CHECK_OPTS: -$ i = 1 -$ OPT_LOOP: -$ if i .lt. 9 -$ then -$ cparm = f$edit(p'i',"upcase") -$ if cparm .eqs. "DEBUG" -$ then -$ ccopt = ccopt + "/noopt/deb" -$ lopts = lopts + "/deb" -$ endif -$ if f$locate("CCOPT=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ ccopt = ccopt + f$extract(start,len,cparm) -$ if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) - - then s_case = true -$ endif -$ if cparm .eqs. "LINK" then linkonly = true -$ if f$locate("LOPTS=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ lopts = lopts + f$extract(start,len,cparm) -$ endif -$ if f$locate("CC=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ cc_com = f$extract(start,len,cparm) - if (cc_com .nes. "DECC") .and. - - (cc_com .nes. "VAXC") .and. - - (cc_com .nes. "GNUC") -$ then -$ write sys$output "Unsupported compiler choice ''cc_com' ignored" -$ write sys$output "Use DECC, VAXC, or GNUC instead" -$ else -$ if cc_com .eqs. "DECC" then its_decc = true -$ if cc_com .eqs. "VAXC" then its_vaxc = true -$ if cc_com .eqs. "GNUC" then its_gnuc = true -$ endif -$ endif -$ if f$locate("MAKE=",cparm) .lt. f$length(cparm) -$ then -$ start = f$locate("=",cparm) + 1 -$ len = f$length(cparm) - start -$ mmks = f$extract(start,len,cparm) -$ if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS") -$ then -$ make = mmks -$ else -$ write sys$output "Unsupported make choice ''mmks' ignored" -$ write sys$output "Use MMK or MMS instead" -$ endif -$ endif -$ i = i + 1 -$ goto opt_loop -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Look for the compiler used -$! -$CHECK_COMPILER: -$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) -$ then -$ its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "") -$ its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "") -$ its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "") -$ endif -$! -$! Exit if no compiler available -$! -$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc)) -$ then goto CC_ERR -$ else -$ if its_decc then write sys$output "CC compiler check ... Compaq C" -$ if its_vaxc then write sys$output "CC compiler check ... VAX C" -$ if its_gnuc then write sys$output "CC compiler check ... GNU C" -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! If MMS/MMK are available dump out the descrip.mms if required -$! -$CREA_MMS: -$ write sys$output "Creating descrip.mms..." -$ create descrip.mms -$ open/append out descrip.mms -$ copy sys$input: out -$ deck -# descrip.mms: MMS description file for building zlib on VMS -# written by Martin P.J. Zinser -# <[email protected] or [email protected]> - -OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj, infback.obj\ - deflate.obj, trees.obj, zutil.obj, inflate.obj, \ - inftrees.obj, inffast.obj - -$ eod -$ write out "CFLAGS=", ccopt -$ write out "LOPTS=", lopts -$ copy sys$input: out -$ deck - -all : example.exe minigzip.exe libz.olb - @ write sys$output " Example applications available" - -libz.olb : libz.olb($(OBJS)) - @ write sys$output " libz available" - -example.exe : example.obj libz.olb - link $(LOPTS) example,libz.olb/lib - -minigzip.exe : minigzip.obj libz.olb - link $(LOPTS) minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib - -clean : - delete *.obj;*,libz.olb;*,*.opt;*,*.exe;* - - -# Other dependencies. -adler32.obj : adler32.c zutil.h zlib.h zconf.h -compress.obj : compress.c zlib.h zconf.h -crc32.obj : crc32.c zutil.h zlib.h zconf.h -deflate.obj : deflate.c deflate.h zutil.h zlib.h zconf.h -example.obj : example.c zlib.h zconf.h -gzio.obj : gzio.c zutil.h zlib.h zconf.h -inffast.obj : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h -inflate.obj : inflate.c zutil.h zlib.h zconf.h -inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h -minigzip.obj : minigzip.c zlib.h zconf.h -trees.obj : trees.c deflate.h zutil.h zlib.h zconf.h -uncompr.obj : uncompr.c zlib.h zconf.h -zutil.obj : zutil.c zutil.h zlib.h zconf.h -infback.obj : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h -$ eod -$ close out -$ return -$!------------------------------------------------------------------------------ -$! -$! Read list of core library sources from makefile.in and create options -$! needed to build shareable image -$! -$CREA_OLIST: -$ open/read min makefile.in -$ open/write mod modules.opt -$ src_check = "OBJS =" -$MRLOOP: -$ read/end=mrdone min rec -$ if (f$extract(0,6,rec) .nes. src_check) then goto mrloop -$ rec = rec - src_check -$ gosub extra_filnam -$ if (f$element(1,"\",rec) .eqs. "\") then goto mrdone -$MRSLOOP: -$ read/end=mrdone min rec -$ gosub extra_filnam -$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop -$MRDONE: -$ close min -$ close mod -$ return -$!------------------------------------------------------------------------------ -$! -$! Take record extracted in crea_olist and split it into single filenames -$! -$EXTRA_FILNAM: -$ myrec = f$edit(rec - "\", "trim,compress") -$ i = 0 -$FELOOP: -$ srcfil = f$element(i," ", myrec) -$ if (srcfil .nes. " ") -$ then -$ write mod f$parse(srcfil,,,"NAME"), ".obj" -$ i = i + 1 -$ goto feloop -$ endif -$ return -$!------------------------------------------------------------------------------ -$! -$! Find current Zlib version number -$! -$FIND_VERSION: -$ open/read h_in 'v_file' -$hloop: -$ read/end=hdone h_in rec -$ rec = f$edit(rec,"TRIM") -$ if (f$extract(0,1,rec) .nes. "#") then goto hloop -$ rec = f$edit(rec - "#", "TRIM") -$ if f$element(0," ",rec) .nes. "define" then goto hloop -$ if f$element(1," ",rec) .eqs. v_string -$ then -$ version = 'f$element(2," ",rec)' -$ goto hdone -$ endif -$ goto hloop -$hdone: -$ close h_in -$ return -$!------------------------------------------------------------------------------ -$! -$! Analyze Object files for OpenVMS AXP to extract Procedure and Data -$! information to build a symbol vector for a shareable image -$! All the "brains" of this logic was suggested by Hartmut Becker -$! ([email protected]). All the bugs were introduced by me -$! ([email protected]), so if you do have problem reports please do not -$! bother Hartmut/HP, but get in touch with me -$! -$ ANAL_OBJ_AXP: Subroutine -$ V = 'F$Verify(0) -$ SAY := "WRITE_ SYS$OUTPUT" -$ -$ IF F$SEARCH("''P1'") .EQS. "" -$ THEN -$ SAY "ANAL_OBJ_AXP-E-NOSUCHFILE: Error, inputfile ''p1' not available" -$ goto exit_aa -$ ENDIF -$ IF "''P2'" .EQS. "" -$ THEN -$ SAY "ANAL_OBJ_AXP: Error, no output file provided" -$ goto exit_aa -$ ENDIF -$ -$ open/read in 'p1 -$ create a.tmp -$ open/append atmp a.tmp -$ loop: -$ read/end=end_loop in line -$ f= f$search(line) -$ if f .eqs. "" -$ then -$ write sys$output "ANAL_OBJ_AXP-w-nosuchfile, ''line'" -$ goto loop -$ endif -$ define/user sys$output nl: -$ define/user sys$error nl: -$ anal/obj/gsd 'f /out=x.tmp -$ open/read xtmp x.tmp -$ XLOOP: -$ read/end=end_xloop xtmp xline -$ xline = f$edit(xline,"compress") -$ write atmp xline -$ goto xloop -$ END_XLOOP: -$ close xtmp -$ goto loop -$ end_loop: -$ close in -$ close atmp -$ if f$search("a.tmp") .eqs. "" - - then $ exit -$ ! all global definitions -$ search a.tmp "symbol:","EGSY$V_DEF 1","EGSY$V_NORM 1"/out=b.tmp -$ ! all procedures -$ search b.tmp "EGSY$V_NORM 1"/wind=(0,1) /out=c.tmp -$ search c.tmp "symbol:"/out=d.tmp -$ define/user sys$output nl: -$ edito/edt/command=sys$input d.tmp -sub/symbol: "/symbol_vector=(/whole -sub/"/=PROCEDURE)/whole -exit -$ ! all data -$ search b.tmp "EGSY$V_DEF 1"/wind=(0,1) /out=e.tmp -$ search e.tmp "symbol:"/out=f.tmp -$ define/user sys$output nl: -$ edito/edt/command=sys$input f.tmp -sub/symbol: "/symbol_vector=(/whole -sub/"/=DATA)/whole -exit -$ sort/nodupl d.tmp,f.tmp 'p2' -$ delete a.tmp;*,b.tmp;*,c.tmp;*,d.tmp;*,e.tmp;*,f.tmp;* -$ if f$search("x.tmp") .nes. "" - - then $ delete x.tmp;* -$! -$ EXIT_AA: -$ if V then set verify -$ endsubroutine -$!------------------------------------------------------------------------------ diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile b/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile deleted file mode 100644 index 2fd6e45c48..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile +++ /dev/null @@ -1,154 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2005 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# ./configure; make test -# The call of configure is optional if you don't have special requirements -# If you wish to build zlib as a shared library, use: ./configure -s - -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o - -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: -# make install -# To install in $HOME instead of /usr/local, use: -# make install prefix=$HOME - -CC=cc - -CFLAGS=-O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DDEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -LDFLAGS=libz.a -LDSHARED=$(CC) -CPP=$(CC) -E - -LIBS=libz.a -SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.3 -SHAREDLIBM=libz.so.1 - -AR=ar rc -RANLIB=ranlib -TAR=tar -SHELL=/bin/sh -EXE= - -prefix = /usr/local -exec_prefix = ${prefix} -libdir = ${exec_prefix}/lib -includedir = ${prefix}/include -mandir = ${prefix}/share/man -man3dir = ${mandir}/man3 - -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infback.o inftrees.o inffast.o - -OBJA = -# to use the asm code: make OBJA=match.o - -TEST_OBJS = example.o minigzip.o - -all: example$(EXE) minigzip$(EXE) - -check: test -test: all - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - echo hello world | ./minigzip | ./minigzip -d || \ - echo ' *** minigzip test FAILED ***' ; \ - if ./example; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; \ - fi - -libz.a: $(OBJS) $(OBJA) - $(AR) $@ $(OBJS) $(OBJA) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -match.o: match.S - $(CPP) match.S > _match.s - $(CC) -c _match.s - mv _match.o match.o - rm -f _match.s - -$(SHAREDLIBV): $(OBJS) - $(LDSHARED) -o $@ $(OBJS) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) - -example$(EXE): example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) - -minigzip$(EXE): minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) - -install: $(LIBS) - -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi - -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi - -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi - -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi - cp zlib.h zconf.h $(includedir) - chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h - cp $(LIBS) $(libdir) - cd $(libdir); chmod 755 $(LIBS) - -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 - cd $(libdir); if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIB) $(SHAREDLIBM); \ - ln -s $(SHAREDLIBV) $(SHAREDLIB); \ - ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ - (ldconfig || true) >/dev/null 2>&1; \ - fi - cp zlib.3 $(man3dir) - chmod 644 $(man3dir)/zlib.3 -# The ranlib in install is needed on NeXTSTEP which checks file times -# ldconfig is for Linux - -uninstall: - cd $(includedir); \ - cd $(libdir); rm -f libz.a; \ - if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ - fi - cd $(man3dir); rm -f zlib.3 - -mostlyclean: clean -clean: - rm -f *.o *~ example$(EXE) minigzip$(EXE) \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o - -maintainer-clean: distclean -distclean: clean - cp -p Makefile.in Makefile - cp -p zconf.in.h zconf.h - rm -f .DS_Store - -tags: - etags *.[ch] - -depend: - makedepend -- $(CFLAGS) -- *.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile.in b/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile.in deleted file mode 100644 index 2fd6e45c48..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile.in +++ /dev/null @@ -1,154 +0,0 @@ -# Makefile for zlib -# Copyright (C) 1995-2005 Jean-loup Gailly. -# For conditions of distribution and use, see copyright notice in zlib.h - -# To compile and test, type: -# ./configure; make test -# The call of configure is optional if you don't have special requirements -# If you wish to build zlib as a shared library, use: ./configure -s - -# To use the asm code, type: -# cp contrib/asm?86/match.S ./match.S -# make LOC=-DASMV OBJA=match.o - -# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: -# make install -# To install in $HOME instead of /usr/local, use: -# make install prefix=$HOME - -CC=cc - -CFLAGS=-O -#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 -#CFLAGS=-g -DDEBUG -#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ -# -Wstrict-prototypes -Wmissing-prototypes - -LDFLAGS=libz.a -LDSHARED=$(CC) -CPP=$(CC) -E - -LIBS=libz.a -SHAREDLIB=libz.so -SHAREDLIBV=libz.so.1.2.3 -SHAREDLIBM=libz.so.1 - -AR=ar rc -RANLIB=ranlib -TAR=tar -SHELL=/bin/sh -EXE= - -prefix = /usr/local -exec_prefix = ${prefix} -libdir = ${exec_prefix}/lib -includedir = ${prefix}/include -mandir = ${prefix}/share/man -man3dir = ${mandir}/man3 - -OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \ - zutil.o inflate.o infback.o inftrees.o inffast.o - -OBJA = -# to use the asm code: make OBJA=match.o - -TEST_OBJS = example.o minigzip.o - -all: example$(EXE) minigzip$(EXE) - -check: test -test: all - @LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ - echo hello world | ./minigzip | ./minigzip -d || \ - echo ' *** minigzip test FAILED ***' ; \ - if ./example; then \ - echo ' *** zlib test OK ***'; \ - else \ - echo ' *** zlib test FAILED ***'; \ - fi - -libz.a: $(OBJS) $(OBJA) - $(AR) $@ $(OBJS) $(OBJA) - -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 - -match.o: match.S - $(CPP) match.S > _match.s - $(CC) -c _match.s - mv _match.o match.o - rm -f _match.s - -$(SHAREDLIBV): $(OBJS) - $(LDSHARED) -o $@ $(OBJS) - rm -f $(SHAREDLIB) $(SHAREDLIBM) - ln -s $@ $(SHAREDLIB) - ln -s $@ $(SHAREDLIBM) - -example$(EXE): example.o $(LIBS) - $(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS) - -minigzip$(EXE): minigzip.o $(LIBS) - $(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS) - -install: $(LIBS) - -@if [ ! -d $(exec_prefix) ]; then mkdir -p $(exec_prefix); fi - -@if [ ! -d $(includedir) ]; then mkdir -p $(includedir); fi - -@if [ ! -d $(libdir) ]; then mkdir -p $(libdir); fi - -@if [ ! -d $(man3dir) ]; then mkdir -p $(man3dir); fi - cp zlib.h zconf.h $(includedir) - chmod 644 $(includedir)/zlib.h $(includedir)/zconf.h - cp $(LIBS) $(libdir) - cd $(libdir); chmod 755 $(LIBS) - -@(cd $(libdir); $(RANLIB) libz.a || true) >/dev/null 2>&1 - cd $(libdir); if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIB) $(SHAREDLIBM); \ - ln -s $(SHAREDLIBV) $(SHAREDLIB); \ - ln -s $(SHAREDLIBV) $(SHAREDLIBM); \ - (ldconfig || true) >/dev/null 2>&1; \ - fi - cp zlib.3 $(man3dir) - chmod 644 $(man3dir)/zlib.3 -# The ranlib in install is needed on NeXTSTEP which checks file times -# ldconfig is for Linux - -uninstall: - cd $(includedir); \ - cd $(libdir); rm -f libz.a; \ - if test -f $(SHAREDLIBV); then \ - rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \ - fi - cd $(man3dir); rm -f zlib.3 - -mostlyclean: clean -clean: - rm -f *.o *~ example$(EXE) minigzip$(EXE) \ - libz.* foo.gz so_locations \ - _match.s maketree contrib/infback9/*.o - -maintainer-clean: distclean -distclean: clean - cp -p Makefile.in Makefile - cp -p zconf.in.h zconf.h - rm -f .DS_Store - -tags: - etags *.[ch] - -depend: - makedepend -- $(CFLAGS) -- *.[ch] - -# DO NOT DELETE THIS LINE -- make depend depends on it. - -adler32.o: zlib.h zconf.h -compress.o: zlib.h zconf.h -crc32.o: crc32.h zlib.h zconf.h -deflate.o: deflate.h zutil.h zlib.h zconf.h -example.o: zlib.h zconf.h -gzio.o: zutil.h zlib.h zconf.h -inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h -inftrees.o: zutil.h zlib.h zconf.h inftrees.h -minigzip.o: zlib.h zconf.h -trees.o: deflate.h zutil.h zlib.h zconf.h trees.h -uncompr.o: zlib.h zconf.h -zutil.o: zutil.h zlib.h zconf.h diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile.riscos b/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile.riscos deleted file mode 100644 index d97f449237..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/Makefile.riscos +++ /dev/null @@ -1,151 +0,0 @@ -# Project: zlib_1_03 -# Patched for zlib 1.1.2 [email protected] 19980430 -# test works out-of-the-box, installs `somewhere' on demand - -# Toolflags: -CCflags = -c -depend !Depend -IC: -g -throwback -DRISCOS -fah -C++flags = -c -depend !Depend -IC: -throwback -Linkflags = -aif -c++ -o $@ -ObjAsmflags = -throwback -NoCache -depend !Depend -CMHGflags = -LibFileflags = -c -l -o $@ -Squeezeflags = -o $@ - -# change the line below to where _you_ want the library installed. -libdest = lib:zlib - -# Final targets: [email protected]: @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \ - @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \ - @.o.uncompr @.o.zutil - LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \ - @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \ - @.o.trees @.o.uncompr @.o.zutil -test: @.minigzip @.example @.lib - @copy @.lib @.libc A~C~DF~L~N~P~Q~RS~TV - @echo running tests: hang on. - @/@.minigzip -f -9 libc - @/@.minigzip -d libc-gz - @/@.minigzip -f -1 libc - @/@.minigzip -d libc-gz - @/@.minigzip -h -9 libc - @/@.minigzip -d libc-gz - @/@.minigzip -h -1 libc - @/@.minigzip -d libc-gz - @/@.minigzip -9 libc - @/@.minigzip -d libc-gz - @/@.minigzip -1 libc - @/@.minigzip -d libc-gz - @diff @.lib @.libc - @echo that should have reported '@.lib and @.libc identical' if you have diff. - @/@.example @.fred @.fred - @echo that will have given lots of hello!'s. - [email protected]: @.o.minigzip @.lib C:o.Stubs - Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs [email protected]: @.o.example @.lib C:o.Stubs - Link $(Linkflags) @.o.example @.lib C:o.Stubs - -install: @.lib - cdir $(libdest) - cdir $(libdest).h - @copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV - @copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV - @copy @.lib $(libdest).lib A~C~DF~L~N~P~Q~RS~TV - @echo okay, installed zlib in $(libdest) - -clean:; remove @.minigzip - remove @.example - remove @.libc - -wipe @.o.* F~r~cV - remove @.fred - -# User-editable dependencies: -.c.o: - cc $(ccflags) -o $@ $< - -# Static dependencies: - -# Dynamic dependencies: -o.example: c.example -o.example: h.zlib -o.example: h.zconf -o.minigzip: c.minigzip -o.minigzip: h.zlib -o.minigzip: h.zconf -o.adler32: c.adler32 -o.adler32: h.zlib -o.adler32: h.zconf -o.compress: c.compress -o.compress: h.zlib -o.compress: h.zconf -o.crc32: c.crc32 -o.crc32: h.zlib -o.crc32: h.zconf -o.deflate: c.deflate -o.deflate: h.deflate -o.deflate: h.zutil -o.deflate: h.zlib -o.deflate: h.zconf -o.gzio: c.gzio -o.gzio: h.zutil -o.gzio: h.zlib -o.gzio: h.zconf -o.infblock: c.infblock -o.infblock: h.zutil -o.infblock: h.zlib -o.infblock: h.zconf -o.infblock: h.infblock -o.infblock: h.inftrees -o.infblock: h.infcodes -o.infblock: h.infutil -o.infcodes: c.infcodes -o.infcodes: h.zutil -o.infcodes: h.zlib -o.infcodes: h.zconf -o.infcodes: h.inftrees -o.infcodes: h.infblock -o.infcodes: h.infcodes -o.infcodes: h.infutil -o.infcodes: h.inffast -o.inffast: c.inffast -o.inffast: h.zutil -o.inffast: h.zlib -o.inffast: h.zconf -o.inffast: h.inftrees -o.inffast: h.infblock -o.inffast: h.infcodes -o.inffast: h.infutil -o.inffast: h.inffast -o.inflate: c.inflate -o.inflate: h.zutil -o.inflate: h.zlib -o.inflate: h.zconf -o.inflate: h.infblock -o.inftrees: c.inftrees -o.inftrees: h.zutil -o.inftrees: h.zlib -o.inftrees: h.zconf -o.inftrees: h.inftrees -o.inftrees: h.inffixed -o.infutil: c.infutil -o.infutil: h.zutil -o.infutil: h.zlib -o.infutil: h.zconf -o.infutil: h.infblock -o.infutil: h.inftrees -o.infutil: h.infcodes -o.infutil: h.infutil -o.trees: c.trees -o.trees: h.deflate -o.trees: h.zutil -o.trees: h.zlib -o.trees: h.zconf -o.trees: h.trees -o.uncompr: c.uncompr -o.uncompr: h.zlib -o.uncompr: h.zconf -o.zutil: c.zutil -o.zutil: h.zutil -o.zutil: h.zlib -o.zutil: h.zconf diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/README b/components/dfs/filesystems/jffs2/cyg/compress/src/README deleted file mode 100644 index 758cc50020..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/README +++ /dev/null @@ -1,125 +0,0 @@ -ZLIB DATA COMPRESSION LIBRARY - -zlib 1.2.3 is a general purpose data compression library. All the code is -thread safe. The data format used by the zlib library is described by RFCs -(Request for Comments) 1950 to 1952 in the files -http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) -and rfc1952.txt (gzip format). These documents are also available in other -formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html - -All functions of the compression library are documented in the file zlib.h -(volunteer to write man pages welcome, contact [email protected]). A usage example -of the library is given in the file example.c which also tests that the library -is working correctly. Another example is given in the file minigzip.c. The -compression library itself is composed of all source files except example.c and -minigzip.c. - -To compile all files and run the test program, follow the instructions given at -the top of Makefile. In short "make test; make install" should work for most -machines. For Unix: "./configure; make test; make install". For MSDOS, use one -of the special makefiles such as Makefile.msc. For VMS, use make_vms.com. - -Questions about zlib should be sent to <[email protected]>, or to Gilles Vollant -<[email protected]> for the Windows DLL version. The zlib home page is -http://www.zlib.org or http://www.gzip.org/zlib/ Before reporting a problem, -please check this site to verify that you have the latest version of zlib; -otherwise get the latest version and check whether the problem still exists or -not. - -PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html before asking -for help. - -Mark Nelson <[email protected]> wrote an article about zlib for the Jan. 1997 -issue of Dr. Dobb's Journal; a copy of the article is available in -http://dogma.net/markn/articles/zlibtool/zlibtool.htm - -The changes made in version 1.2.3 are documented in the file ChangeLog. - -Unsupported third party contributions are provided in directory "contrib". - -A Java implementation of zlib is available in the Java Development Kit -http://java.sun.com/j2se/1.4.2/docs/api/java/util/zip/package-summary.html -See the zlib home page http://www.zlib.org for details. - -A Perl interface to zlib written by Paul Marquess <[email protected]> is in the -CPAN (Comprehensive Perl Archive Network) sites -http://www.cpan.org/modules/by-module/Compress/ - -A Python interface to zlib written by A.M. Kuchling <[email protected]> is -available in Python 1.5 and later versions, see -http://www.python.org/doc/lib/module-zlib.html - -A zlib binding for TCL written by Andreas Kupries <[email protected]> is -availlable at http://www.oche.de/~akupries/soft/trf/trf_zip.html - -An experimental package to read and write files in .zip format, written on top -of zlib by Gilles Vollant <[email protected]>, is available in the -contrib/minizip directory of zlib. - - -Notes for some targets: - -- For Windows DLL versions, please see win32/DLL_FAQ.txt - -- For 64-bit Irix, deflate.c must be compiled without any optimization. With - -O, one libpng test fails. The test works in 32 bit mode (with the -n32 - compiler flag). The compiler bug has been reported to SGI. - -- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works - when compiled with cc. - -- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is - necessary to get gzprintf working correctly. This is done by configure. - -- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with - other compilers. Use "make test" to check your compiler. - -- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers. - -- For PalmOs, see http://palmzlib.sourceforge.net/ - -- When building a shared, i.e. dynamic library on Mac OS X, the library must be - installed before testing (do "make install" before "make test"), since the - library location is specified in the library. - - -Acknowledgments: - - The deflate format used by zlib was defined by Phil Katz. The deflate - and zlib specifications were written by L. Peter Deutsch. Thanks to all the - people who reported problems and suggested various improvements in zlib; - they are too numerous to cite here. - -Copyright notice: - - (C) 1995-2004 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - -If you use the zlib library in a product, we would appreciate *not* -receiving lengthy legal documents to sign. The sources are provided -for free but without warranty of any kind. The library has been -entirely written by Jean-loup Gailly and Mark Adler; it does not -include third-party code. - -If you redistribute modified sources, we would appreciate that you include -in the file ChangeLog history information documenting your changes. Please -read the FAQ for more information on the distribution of modified source -versions. diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/README.eCos b/components/dfs/filesystems/jffs2/cyg/compress/src/README.eCos deleted file mode 100644 index 88011312f9..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/README.eCos +++ /dev/null @@ -1,27 +0,0 @@ -See the main site http://www.gzip.org/zlib/ for places to download the -complete sources. Currently based on zlib-1.2.3 - -Note that these are not the complete zlib sources - the following -directories have been deleted since they are irrelevant for the -eCos support: - -amiga/ -as400/ -contrib/ -msdos/ -old/ -projects/ -qnx/ -win32/ - -Additionally, local changes has been made to the remaining files. Code -changes are marked by __ECOS__ (comments or definitions). Finally, the -headers zlib.h and zconf.h have been moved out of the directory into -../include. - -crc32.c + crc32.h has also been removed as it is provided by services/crc/. - -Note: zconf.h always defines __ECOS__. This is necessary to support -programs built outside of the eCos tree which may wish to use this -library (so those programs needn't worry about defining __ECOS__) - diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/adler32.c b/components/dfs/filesystems/jffs2/cyg/compress/src/adler32.c deleted file mode 100644 index 2522ee2120..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/adler32.c +++ /dev/null @@ -1,153 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#ifdef __ECOS__ -#include <cyg/compress/zlib.h> -#else -#include "zlib.h" -#endif // __ECOS__ - -#define BASE 65521UL /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware */ -#ifdef NO_DIVIDE -# define MOD(a) \ - do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD4(a) \ - do { \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD4(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD4(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* the derivation of this formula is left as an exercise for the reader */ - rem = (unsigned)(len2 % BASE); - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 > BASE) sum1 -= BASE; - if (sum1 > BASE) sum1 -= BASE; - if (sum2 > (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 > BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/algorithm.txt b/components/dfs/filesystems/jffs2/cyg/compress/src/algorithm.txt deleted file mode 100644 index b022dde312..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/algorithm.txt +++ /dev/null @@ -1,209 +0,0 @@ -1. Compression algorithm (deflate) - -The deflation algorithm used by gzip (also zip and zlib) is a variation of -LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in -the input data. The second occurrence of a string is replaced by a -pointer to the previous string, in the form of a pair (distance, -length). Distances are limited to 32K bytes, and lengths are limited -to 258 bytes. When a string does not occur anywhere in the previous -32K bytes, it is emitted as a sequence of literal bytes. (In this -description, `string' must be taken as an arbitrary sequence of bytes, -and is not restricted to printable characters.) - -Literals or match lengths are compressed with one Huffman tree, and -match distances are compressed with another tree. The trees are stored -in a compact form at the start of each block. The blocks can have any -size (except that the compressed data for one block must fit in -available memory). A block is terminated when deflate() determines that -it would be useful to start another block with fresh trees. (This is -somewhat similar to the behavior of LZW-based _compress_.) - -Duplicated strings are found using a hash table. All input strings of -length 3 are inserted in the hash table. A hash index is computed for -the next 3 bytes. If the hash chain for this index is not empty, all -strings in the chain are compared with the current input string, and -the longest match is selected. - -The hash chains are searched starting with the most recent strings, to -favor small distances and thus take advantage of the Huffman encoding. -The hash chains are singly linked. There are no deletions from the -hash chains, the algorithm simply discards matches that are too old. - -To avoid a worst-case situation, very long hash chains are arbitrarily -truncated at a certain length, determined by a runtime option (level -parameter of deflateInit). So deflate() does not always find the longest -possible match but generally finds a match which is long enough. - -deflate() also defers the selection of matches with a lazy evaluation -mechanism. After a match of length N has been found, deflate() searches for -a longer match at the next input byte. If a longer match is found, the -previous match is truncated to a length of one (thus producing a single -literal byte) and the process of lazy evaluation begins again. Otherwise, -the original match is kept, and the next match search is attempted only N -steps later. - -The lazy match evaluation is also subject to a runtime parameter. If -the current match is long enough, deflate() reduces the search for a longer -match, thus speeding up the whole process. If compression ratio is more -important than speed, deflate() attempts a complete second search even if -the first match is already long enough. - -The lazy match evaluation is not performed for the fastest compression -modes (level parameter 1 to 3). For these fast modes, new strings -are inserted in the hash table only when no match was found, or -when the match is not too long. This degrades the compression ratio -but saves time since there are both fewer insertions and fewer searches. - - -2. Decompression algorithm (inflate) - -2.1 Introduction - -The key question is how to represent a Huffman code (or any prefix code) so -that you can decode fast. The most important characteristic is that shorter -codes are much more common than longer codes, so pay attention to decoding the -short codes fast, and let the long codes take longer to decode. - -inflate() sets up a first level table that covers some number of bits of -input less than the length of longest code. It gets that many bits from the -stream, and looks it up in the table. The table will tell if the next -code is that many bits or less and how many, and if it is, it will tell -the value, else it will point to the next level table for which inflate() -grabs more bits and tries to decode a longer code. - -How many bits to make the first lookup is a tradeoff between the time it -takes to decode and the time it takes to build the table. If building the -table took no time (and if you had infinite memory), then there would only -be a first level table to cover all the way to the longest code. However, -building the table ends up taking a lot longer for more bits since short -codes are replicated many times in such a table. What inflate() does is -simply to make the number of bits in the first table a variable, and then -to set that variable for the maximum speed. - -For inflate, which has 286 possible codes for the literal/length tree, the size -of the first table is nine bits. Also the distance trees have 30 possible -values, and the size of the first table is six bits. Note that for each of -those cases, the table ended up one bit longer than the ``average'' code -length, i.e. the code length of an approximately flat code which would be a -little more than eight bits for 286 symbols and a little less than five bits -for 30 symbols. - - -2.2 More details on the inflate table lookup - -Ok, you want to know what this cleverly obfuscated inflate tree actually -looks like. You are correct that it's not a Huffman tree. It is simply a -lookup table for the first, let's say, nine bits of a Huffman symbol. The -symbol could be as short as one bit or as long as 15 bits. If a particular -symbol is shorter than nine bits, then that symbol's translation is duplicated -in all those entries that start with that symbol's bits. For example, if the -symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a -symbol is nine bits long, it appears in the table once. - -If the symbol is longer than nine bits, then that entry in the table points -to another similar table for the remaining bits. Again, there are duplicated -entries as needed. The idea is that most of the time the symbol will be short -and there will only be one table look up. (That's whole idea behind data -compression in the first place.) For the less frequent long symbols, there -will be two lookups. If you had a compression method with really long -symbols, you could have as many levels of lookups as is efficient. For -inflate, two is enough. - -So a table entry either points to another table (in which case nine bits in -the above example are gobbled), or it contains the translation for the symbol -and the number of bits to gobble. Then you start again with the next -ungobbled bit. - -You may wonder: why not just have one lookup table for how ever many bits the -longest symbol is? The reason is that if you do that, you end up spending -more time filling in duplicate symbol entries than you do actually decoding. -At least for deflate's output that generates new trees every several 10's of -kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code -would take too long if you're only decoding several thousand symbols. At the -other extreme, you could make a new table for every bit in the code. In fact, -that's essentially a Huffman tree. But then you spend two much time -traversing the tree while decoding, even for short symbols. - -So the number of bits for the first lookup table is a trade of the time to -fill out the table vs. the time spent looking at the second level and above of -the table. - -Here is an example, scaled down: - -The code being decoded, with 10 symbols, from 1 to 6 bits long: - -A: 0 -B: 10 -C: 1100 -D: 11010 -E: 11011 -F: 11100 -G: 11101 -H: 11110 -I: 111110 -J: 111111 - -Let's make the first table three bits long (eight entries): - -000: A,1 -001: A,1 -010: A,1 -011: A,1 -100: B,2 -101: B,2 -110: -> table X (gobble 3 bits) -111: -> table Y (gobble 3 bits) - -Each entry is what the bits decode as and how many bits that is, i.e. how -many bits to gobble. Or the entry points to another table, with the number of -bits to gobble implicit in the size of the table. - -Table X is two bits long since the longest code starting with 110 is five bits -long: - -00: C,1 -01: C,1 -10: D,2 -11: E,2 - -Table Y is three bits long since the longest code starting with 111 is six -bits long: - -000: F,2 -001: F,2 -010: G,2 -011: G,2 -100: H,2 -101: H,2 -110: I,3 -111: J,3 - -So what we have here are three tables with a total of 20 entries that had to -be constructed. That's compared to 64 entries for a single table. Or -compared to 16 entries for a Huffman tree (six two entry tables and one four -entry table). Assuming that the code ideally represents the probability of -the symbols, it takes on the average 1.25 lookups per symbol. That's compared -to one lookup for the single table, or 1.66 lookups per symbol for the -Huffman tree. - -There, I think that gives you a picture of what's going on. For inflate, the -meaning of a particular symbol is often more than just a letter. It can be a -byte (a "literal"), or it can be either a length or a distance which -indicates a base value and a number of bits to fetch after the code that is -added to the base value. Or it might be the special end-of-block code. The -data structures created in inftrees.c try to encode all that information -compactly in the tables. - - -Jean-loup Gailly Mark Adler - - -References: - -[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data -Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, -pp. 337-343. - -``DEFLATE Compressed Data Format Specification'' available in -http://www.ietf.org/rfc/rfc1951.txt diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/compress.c b/components/dfs/filesystems/jffs2/cyg/compress/src/compress.c deleted file mode 100644 index f94974537f..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/compress.c +++ /dev/null @@ -1,83 +0,0 @@ -/* compress.c -- compress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#ifdef __ECOS__ -#include <cyg/compress/zlib.h> -#else -#include "zlib.h" -#endif // __ECOS__ - -/* =========================================================================== - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least 0.1% larger than sourceLen plus - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; -#ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; -#endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit(&stream, level); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; -} - -/* =========================================================================== - */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); -} - -/* =========================================================================== - If the default memLevel or windowBits for deflateInit() is changed, then - this function needs to be updated. - */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; -{ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/configure b/components/dfs/filesystems/jffs2/cyg/compress/src/configure deleted file mode 100644 index d7ffdc3458..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/configure +++ /dev/null @@ -1,459 +0,0 @@ -#!/bin/sh -# configure script for zlib. This script is needed only if -# you wish to build a shared library and your system supports them, -# of if you need special compiler, flags or install directory. -# Otherwise, you can just use directly "make test; make install" -# -# To create a shared library, use "configure --shared"; by default a static -# library is created. If the primitive shared library support provided here -# does not work, use ftp://prep.ai.mit.edu/pub/gnu/libtool-*.tar.gz -# -# To impose specific compiler or flags or install directory, use for example: -# prefix=$HOME CC=cc CFLAGS="-O4" ./configure -# or for csh/tcsh users: -# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) -# LDSHARED is the command to be used to create a shared library - -# Incorrect settings of CC or CFLAGS may prevent creating a shared library. -# If you have problems, try without defining CC and CFLAGS before reporting -# an error. - -LIBS=libz.a -LDFLAGS="-L. ${LIBS}" -VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h` -VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h` -VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h` -AR=${AR-"ar rc"} -RANLIB=${RANLIB-"ranlib"} -prefix=${prefix-/usr/local} -exec_prefix=${exec_prefix-'${prefix}'} -libdir=${libdir-'${exec_prefix}/lib'} -includedir=${includedir-'${prefix}/include'} -mandir=${mandir-'${prefix}/share/man'} -shared_ext='.so' -shared=0 -gcc=0 -old_cc="$CC" -old_cflags="$CFLAGS" - -while test $# -ge 1 -do -case "$1" in - -h* | --h*) - echo 'usage:' - echo ' configure [--shared] [--prefix=PREFIX] [--exec_prefix=EXPREFIX]' - echo ' [--libdir=LIBDIR] [--includedir=INCLUDEDIR]' - exit 0;; - -p*=* | --p*=*) prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -e*=* | --e*=*) exec_prefix=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -l*=* | --libdir=*) libdir=`echo $1 | sed 's/[-a-z_]*=//'`; shift;; - -i*=* | --includedir=*) includedir=`echo $1 | sed 's/[-a-z_]*=//'`;shift;; - -p* | --p*) prefix="$2"; shift; shift;; - -e* | --e*) exec_prefix="$2"; shift; shift;; - -l* | --l*) libdir="$2"; shift; shift;; - -i* | --i*) includedir="$2"; shift; shift;; - -s* | --s*) shared=1; shift;; - *) echo "unknown option: $1"; echo "$0 --help for help"; exit 1;; - esac -done - -test=ztest$$ -cat > $test.c <<EOF -extern int getchar(); -int hello() {return getchar();} -EOF - -test -z "$CC" && echo Checking for gcc... -cc=${CC-gcc} -cflags=${CFLAGS-"-O3"} -# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure -case "$cc" in - *gcc*) gcc=1;; -esac - -if test "$gcc" -eq 1 && ($cc -c $cflags $test.c) 2>/dev/null; then - CC="$cc" - SFLAGS=${CFLAGS-"-fPIC -O3"} - CFLAGS="$cflags" - case `(uname -s || echo unknown) 2>/dev/null` in - Linux | linux | GNU | GNU/*) LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1"};; - CYGWIN* | Cygwin* | cygwin* | OS/2* ) - EXE='.exe';; - QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 - # ([email protected]) - LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"};; - HP-UX*) - LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"} - case `(uname -m || echo unknown) 2>/dev/null` in - ia64) - shared_ext='.so' - SHAREDLIB='libz.so';; - *) - shared_ext='.sl' - SHAREDLIB='libz.sl';; - esac;; - Darwin*) shared_ext='.dylib' - SHAREDLIB=libz$shared_ext - SHAREDLIBV=libz.$VER$shared_ext - SHAREDLIBM=libz.$VER1$shared_ext - LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER"};; - *) LDSHARED=${LDSHARED-"$cc -shared"};; - esac -else - # find system name and corresponding cc options - CC=${CC-cc} - case `(uname -sr || echo unknown) 2>/dev/null` in - HP-UX*) SFLAGS=${CFLAGS-"-O +z"} - CFLAGS=${CFLAGS-"-O"} -# LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"} - LDSHARED=${LDSHARED-"ld -b"} - case `(uname -m || echo unknown) 2>/dev/null` in - ia64) - shared_ext='.so' - SHAREDLIB='libz.so';; - *) - shared_ext='.sl' - SHAREDLIB='libz.sl';; - esac;; - IRIX*) SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."} - CFLAGS=${CFLAGS-"-ansi -O2"} - LDSHARED=${LDSHARED-"cc -shared"};; - OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"} - CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"};; - OSF1*) SFLAGS=${CFLAGS-"-O -std1"} - CFLAGS=${CFLAGS-"-O -std1"} - LDSHARED=${LDSHARED-"cc -shared"};; - QNX*) SFLAGS=${CFLAGS-"-4 -O"} - CFLAGS=${CFLAGS-"-4 -O"} - LDSHARED=${LDSHARED-"cc"} - RANLIB=${RANLIB-"true"} - AR="cc -A";; - SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "} - CFLAGS=${CFLAGS-"-O3"} - LDSHARED=${LDSHARED-"cc -dy -KPIC -G"};; - SunOS\ 5*) SFLAGS=${CFLAGS-"-fast -xcg89 -KPIC -R."} - CFLAGS=${CFLAGS-"-fast -xcg89"} - LDSHARED=${LDSHARED-"cc -G"};; - SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"} - CFLAGS=${CFLAGS-"-O2"} - LDSHARED=${LDSHARED-"ld"};; - SunStudio\ 9*) SFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"} - CFLAGS=${CFLAGS-"-DUSE_MMAP -fast -xtarget=ultra3 -xarch=v9b"} - LDSHARED=${LDSHARED-"cc -xarch=v9b"};; - UNIX_System_V\ 4.2.0) - SFLAGS=${CFLAGS-"-KPIC -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; - UNIX_SV\ 4.2MP) - SFLAGS=${CFLAGS-"-Kconform_pic -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; - OpenUNIX\ 5) - SFLAGS=${CFLAGS-"-KPIC -O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -G"};; - AIX*) # Courtesy of [email protected] - SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} - LDSHARED=${LDSHARED-"xlc -G"};; - # send working options for other systems to [email protected] - *) SFLAGS=${CFLAGS-"-O"} - CFLAGS=${CFLAGS-"-O"} - LDSHARED=${LDSHARED-"cc -shared"};; - esac -fi - -SHAREDLIB=${SHAREDLIB-"libz$shared_ext"} -SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"} -SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"} - -if test $shared -eq 1; then - echo Checking for shared library support... - # we must test in two steps (cc then ld), required at least on SunOS 4.x - if test "`($CC -c $SFLAGS $test.c) 2>&1`" = "" && - test "`($LDSHARED -o $test$shared_ext $test.o) 2>&1`" = ""; then - CFLAGS="$SFLAGS" - LIBS="$SHAREDLIBV" - echo Building shared library $SHAREDLIBV with $CC. - elif test -z "$old_cc" -a -z "$old_cflags"; then - echo No shared library support. - shared=0; - else - echo 'No shared library support; try without defining CC and CFLAGS' - shared=0; - fi -fi -if test $shared -eq 0; then - LDSHARED="$CC" - echo Building static library $LIBS version $VER with $CC. -else - LDFLAGS="-L. ${SHAREDLIBV}" -fi - -cat > $test.c <<EOF -#include <unistd.h> -int main() { return 0; } -EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - sed < zconf.in.h "/HAVE_UNISTD_H/s%0%1%" > zconf.h - echo "Checking for unistd.h... Yes." -else - cp -p zconf.in.h zconf.h - echo "Checking for unistd.h... No." -fi - -cat > $test.c <<EOF -#include <stdio.h> -#include <stdarg.h> -#include "zconf.h" - -int main() -{ -#ifndef STDC - choke me -#endif - - return 0; -} -EOF - -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()" - - cat > $test.c <<EOF -#include <stdio.h> -#include <stdarg.h> - -int mytest(char *fmt, ...) -{ - char buf[20]; - va_list ap; - - va_start(ap, fmt); - vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return 0; -} - -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - - if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then - echo "Checking for vsnprintf() in stdio.h... Yes." - - cat >$test.c <<EOF -#include <stdio.h> -#include <stdarg.h> - -int mytest(char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - - va_start(ap, fmt); - n = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return n; -} - -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - - if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for return value of vsnprintf()... Yes." - else - CFLAGS="$CFLAGS -DHAS_vsnprintf_void" - echo "Checking for return value of vsnprintf()... No." - echo " WARNING: apparently vsnprintf() does not return a value. zlib" - echo " can build but will be open to possible string-format security" - echo " vulnerabilities." - fi - else - CFLAGS="$CFLAGS -DNO_vsnprintf" - echo "Checking for vsnprintf() in stdio.h... No." - echo " WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" - echo " can build but will be open to possible buffer-overflow security" - echo " vulnerabilities." - - cat >$test.c <<EOF -#include <stdio.h> -#include <stdarg.h> - -int mytest(char *fmt, ...) -{ - int n; - char buf[20]; - va_list ap; - - va_start(ap, fmt); - n = vsprintf(buf, fmt, ap); - va_end(ap); - return n; -} - -int main() -{ - return (mytest("Hello%d\n", 1)); -} -EOF - - if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for return value of vsprintf()... Yes." - else - CFLAGS="$CFLAGS -DHAS_vsprintf_void" - echo "Checking for return value of vsprintf()... No." - echo " WARNING: apparently vsprintf() does not return a value. zlib" - echo " can build but will be open to possible string-format security" - echo " vulnerabilities." - fi - fi -else - echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()" - - cat >$test.c <<EOF -#include <stdio.h> - -int mytest() -{ - char buf[20]; - - snprintf(buf, sizeof(buf), "%s", "foo"); - return 0; -} - -int main() -{ - return (mytest()); -} -EOF - - if test "`($CC $CFLAGS -o $test $test.c) 2>&1`" = ""; then - echo "Checking for snprintf() in stdio.h... Yes." - - cat >$test.c <<EOF -#include <stdio.h> - -int mytest() -{ - char buf[20]; - - return snprintf(buf, sizeof(buf), "%s", "foo"); -} - -int main() -{ - return (mytest()); -} -EOF - - if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for return value of snprintf()... Yes." - else - CFLAGS="$CFLAGS -DHAS_snprintf_void" - echo "Checking for return value of snprintf()... No." - echo " WARNING: apparently snprintf() does not return a value. zlib" - echo " can build but will be open to possible string-format security" - echo " vulnerabilities." - fi - else - CFLAGS="$CFLAGS -DNO_snprintf" - echo "Checking for snprintf() in stdio.h... No." - echo " WARNING: snprintf() not found, falling back to sprintf(). zlib" - echo " can build but will be open to possible buffer-overflow security" - echo " vulnerabilities." - - cat >$test.c <<EOF -#include <stdio.h> - -int mytest() -{ - char buf[20]; - - return sprintf(buf, "%s", "foo"); -} - -int main() -{ - return (mytest()); -} -EOF - - if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for return value of sprintf()... Yes." - else - CFLAGS="$CFLAGS -DHAS_sprintf_void" - echo "Checking for return value of sprintf()... No." - echo " WARNING: apparently sprintf() does not return a value. zlib" - echo " can build but will be open to possible string-format security" - echo " vulnerabilities." - fi - fi -fi - -cat >$test.c <<EOF -#include <errno.h> -int main() { return 0; } -EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - echo "Checking for errno.h... Yes." -else - echo "Checking for errno.h... No." - CFLAGS="$CFLAGS -DNO_ERRNO_H" -fi - -cat > $test.c <<EOF -#include <sys/types.h> -#include <sys/mman.h> -#include <sys/stat.h> -caddr_t hello() { - return mmap((caddr_t)0, (off_t)0, PROT_READ, MAP_SHARED, 0, (off_t)0); -} -EOF -if test "`($CC -c $CFLAGS $test.c) 2>&1`" = ""; then - CFLAGS="$CFLAGS -DUSE_MMAP" - echo Checking for mmap support... Yes. -else - echo Checking for mmap support... No. -fi - -CPP=${CPP-"$CC -E"} -case $CFLAGS in - *ASMV*) - if test "`nm $test.o | grep _hello`" = ""; then - CPP="$CPP -DNO_UNDERLINE" - echo Checking for underline in external names... No. - else - echo Checking for underline in external names... Yes. - fi;; -esac - -rm -f $test.[co] $test $test$shared_ext - -# udpate Makefile -sed < Makefile.in " -/^CC *=/s#=.*#=$CC# -/^CFLAGS *=/s#=.*#=$CFLAGS# -/^CPP *=/s#=.*#=$CPP# -/^LDSHARED *=/s#=.*#=$LDSHARED# -/^LIBS *=/s#=.*#=$LIBS# -/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# -/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# -/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# -/^AR *=/s#=.*#=$AR# -/^RANLIB *=/s#=.*#=$RANLIB# -/^EXE *=/s#=.*#=$EXE# -/^prefix *=/s#=.*#=$prefix# -/^exec_prefix *=/s#=.*#=$exec_prefix# -/^libdir *=/s#=.*#=$libdir# -/^includedir *=/s#=.*#=$includedir# -/^mandir *=/s#=.*#=$mandir# -/^LDFLAGS *=/s#=.*#=$LDFLAGS# -" > Makefile diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/deflate.c b/components/dfs/filesystems/jffs2/cyg/compress/src/deflate.c deleted file mode 100644 index 29ce1f64a5..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/deflate.c +++ /dev/null @@ -1,1736 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifndef FASTEST -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif -#endif -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match)); - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) - return Z_STREAM_ERROR; - - s = strm->state; - if (s->wrap) - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > MAX_DIST(s)) { - length = MAX_DIST(s); - dictionary += dictLength - length; /* use the tail of the dictionary */ - } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if (func != configuration_table[level].func && strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_PARTIAL_FLUSH); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds - * for every combination of windowBits and memLevel, as well as wrap. - * But even the conservative upper bound of about 14% expansion does not - * seem onerous for output buffer allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong destLen; - - /* conservative upper bound */ - destLen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11; - - /* if can't get parameters, return conservative bound */ - if (strm == Z_NULL || strm->state == Z_NULL) - return destLen; - - /* if not default parameters, return conservative bound */ - s = strm->state; - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return destLen; - - /* default settings: return tight bound for that case */ - return compressBound(sourceLen); -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len = strm->state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, strm->state->pending_out, len); - strm->next_out += len; - strm->state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_FINISH || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = (*(configuration_table[s->level].func))(s, flush); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy(dest, source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); - } -#endif - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ -#endif /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for level == 1 or strategy == Z_RLE only - */ -local uInt longest_match_fast(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - /* %%% avoid this when Z_RLE */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, eof) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (eof)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, eof) { \ - FLUSH_BLOCK_ONLY(s, eof); \ - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ -#ifdef FASTEST - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) || - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) { - s->match_length = longest_match_fast (s, hash_head); - } -#else - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } -#endif - /* longest_match() or longest_match_fast() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head = NIL; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) { - s->match_length = longest_match (s, hash_head); - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) { - s->match_length = longest_match_fast (s, hash_head); - } - /* longest_match() or longest_match_fast() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif /* FASTEST */ - -#if 0 -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt run; /* length of run */ - uInt max; /* maximum length of run */ - uInt prev; /* byte at distance one to match */ - Bytef *scan; /* scan for end of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest encodable run. - */ - if (s->lookahead < MAX_MATCH) { - fill_window(s); - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - run = 0; - if (s->strstart > 0) { /* if there is a previous byte, that is */ - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH; - scan = s->window + s->strstart - 1; - prev = *scan++; - do { - if (*scan++ != prev) - break; - } while (++run < max); - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (run >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, run); - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush); - s->lookahead -= run; - s->strstart += run; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/deflate.h b/components/dfs/filesystems/jffs2/cyg/compress/src/deflate.h deleted file mode 100644 index 05a5ab3a2c..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/deflate.h +++ /dev/null @@ -1,331 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2004 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - - /* in trees.c */ -void _tr_init OF((deflate_state *s)); -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); -void _tr_align OF((deflate_state *s)); -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len, - int eof)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch _length_code[]; - extern uch _dist_code[]; -#else - extern const uch _length_code[]; - extern const uch _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/descrip.mms b/components/dfs/filesystems/jffs2/cyg/compress/src/descrip.mms deleted file mode 100644 index 9d364598a2..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/descrip.mms +++ /dev/null @@ -1,48 +0,0 @@ -# descrip.mms: MMS description file for building zlib on VMS -# written by Martin P.J. Zinser <[email protected]> - -cc_defs = -c_deb = - -.ifdef __DECC__ -pref = /prefix=all -.endif - -OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\ - deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\ - inftrees.obj, infcodes.obj, infutil.obj, inffast.obj - -CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF) - -all : example.exe minigzip.exe - @ write sys$output " Example applications available" -libz.olb : libz.olb($(OBJS)) - @ write sys$output " libz available" - -example.exe : example.obj libz.olb - link example,libz.olb/lib - -minigzip.exe : minigzip.obj libz.olb - link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib - -clean : - delete *.obj;*,libz.olb;* - - -# Other dependencies. -adler32.obj : zutil.h zlib.h zconf.h -compress.obj : zlib.h zconf.h -crc32.obj : zutil.h zlib.h zconf.h -deflate.obj : deflate.h zutil.h zlib.h zconf.h -example.obj : zlib.h zconf.h -gzio.obj : zutil.h zlib.h zconf.h -infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h -infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h -inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h -inflate.obj : zutil.h zlib.h zconf.h infblock.h -inftrees.obj : zutil.h zlib.h zconf.h inftrees.h -infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h -minigzip.obj : zlib.h zconf.h -trees.obj : deflate.h zutil.h zlib.h zconf.h -uncompr.obj : zlib.h zconf.h -zutil.obj : zutil.h zlib.h zconf.h diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/example.c b/components/dfs/filesystems/jffs2/cyg/compress/src/example.c deleted file mode 100644 index 6c8a0ee763..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/example.c +++ /dev/null @@ -1,565 +0,0 @@ -/* example.c -- usage example of the zlib compression library - * Copyright (C) 1995-2004 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include <stdio.h> -#include "zlib.h" - -#ifdef STDC -# include <string.h> -# include <stdlib.h> -#endif - -#if defined(VMS) || defined(RISCOS) -# define TESTFILE "foo-gz" -#else -# define TESTFILE "foo.gz" -#endif - -#define CHECK_ERR(err, msg) { \ - if (err != Z_OK) { \ - fprintf(stderr, "%s error: %d\n", msg, err); \ - exit(1); \ - } \ -} - -const char hello[] = "hello, hello!"; -/* "hello world" would be more standard, but the repeated "hello" - * stresses the compression code better, sorry... - */ - -const char dictionary[] = "hello"; -uLong dictId; /* Adler32 value of the dictionary */ - -void test_compress OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_gzio OF((const char *fname, - Byte *uncompr, uLong uncomprLen)); -void test_deflate OF((Byte *compr, uLong comprLen)); -void test_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_large_deflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_large_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_flush OF((Byte *compr, uLong *comprLen)); -void test_sync OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -void test_dict_deflate OF((Byte *compr, uLong comprLen)); -void test_dict_inflate OF((Byte *compr, uLong comprLen, - Byte *uncompr, uLong uncomprLen)); -int main OF((int argc, char *argv[])); - -/* =========================================================================== - * Test compress() and uncompress() - */ -void test_compress(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - uLong len = (uLong)strlen(hello)+1; - - err = compress(compr, &comprLen, (const Bytef*)hello, len); - CHECK_ERR(err, "compress"); - - strcpy((char*)uncompr, "garbage"); - - err = uncompress(uncompr, &uncomprLen, compr, comprLen); - CHECK_ERR(err, "uncompress"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad uncompress\n"); - exit(1); - } else { - printf("uncompress(): %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Test read/write of .gz files - */ -void test_gzio(fname, uncompr, uncomprLen) - const char *fname; /* compressed file name */ - Byte *uncompr; - uLong uncomprLen; -{ -#ifdef NO_GZCOMPRESS - fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); -#else - int err; - int len = (int)strlen(hello)+1; - gzFile file; - z_off_t pos; - - file = gzopen(fname, "wb"); - if (file == NULL) { - fprintf(stderr, "gzopen error\n"); - exit(1); - } - gzputc(file, 'h'); - if (gzputs(file, "ello") != 4) { - fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err)); - exit(1); - } - if (gzprintf(file, ", %s!", "hello") != 8) { - fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err)); - exit(1); - } - gzseek(file, 1L, SEEK_CUR); /* add one zero byte */ - gzclose(file); - - file = gzopen(fname, "rb"); - if (file == NULL) { - fprintf(stderr, "gzopen error\n"); - exit(1); - } - strcpy((char*)uncompr, "garbage"); - - if (gzread(file, uncompr, (unsigned)uncomprLen) != len) { - fprintf(stderr, "gzread err: %s\n", gzerror(file, &err)); - exit(1); - } - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad gzread: %s\n", (char*)uncompr); - exit(1); - } else { - printf("gzread(): %s\n", (char*)uncompr); - } - - pos = gzseek(file, -8L, SEEK_CUR); - if (pos != 6 || gztell(file) != pos) { - fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n", - (long)pos, (long)gztell(file)); - exit(1); - } - - if (gzgetc(file) != ' ') { - fprintf(stderr, "gzgetc error\n"); - exit(1); - } - - if (gzungetc(' ', file) != ' ') { - fprintf(stderr, "gzungetc error\n"); - exit(1); - } - - gzgets(file, (char*)uncompr, (int)uncomprLen); - if (strlen((char*)uncompr) != 7) { /* " hello!" */ - fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err)); - exit(1); - } - if (strcmp((char*)uncompr, hello + 6)) { - fprintf(stderr, "bad gzgets after gzseek\n"); - exit(1); - } else { - printf("gzgets() after gzseek: %s\n", (char*)uncompr); - } - - gzclose(file); -#endif -} - -/* =========================================================================== - * Test deflate() with small buffers - */ -void test_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - uLong len = (uLong)strlen(hello)+1; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_in = (Bytef*)hello; - c_stream.next_out = compr; - - while (c_stream.total_in != len && c_stream.total_out < comprLen) { - c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - } - /* Finish the stream, still forcing small buffers: */ - for (;;) { - c_stream.avail_out = 1; - err = deflate(&c_stream, Z_FINISH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "deflate"); - } - - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with small buffers - */ -void test_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = 0; - d_stream.next_out = uncompr; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { - d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "inflate"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad inflate\n"); - exit(1); - } else { - printf("inflate(): %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Test deflate() with large buffers and dynamic change of compression level - */ -void test_large_deflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_BEST_SPEED); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_out = compr; - c_stream.avail_out = (uInt)comprLen; - - /* At this point, uncompr is still mostly zeroes, so it should compress - * very well: - */ - c_stream.next_in = uncompr; - c_stream.avail_in = (uInt)uncomprLen; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - if (c_stream.avail_in != 0) { - fprintf(stderr, "deflate not greedy\n"); - exit(1); - } - - /* Feed in already compressed data and switch to no compression: */ - deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); - c_stream.next_in = compr; - c_stream.avail_in = (uInt)comprLen/2; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - - /* Switch back to compressing mode: */ - deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); - c_stream.next_in = uncompr; - c_stream.avail_in = (uInt)uncomprLen; - err = deflate(&c_stream, Z_NO_FLUSH); - CHECK_ERR(err, "deflate"); - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - fprintf(stderr, "deflate should report Z_STREAM_END\n"); - exit(1); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with large buffers - */ -void test_large_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = (uInt)comprLen; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - for (;;) { - d_stream.next_out = uncompr; /* discard the output */ - d_stream.avail_out = (uInt)uncomprLen; - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - CHECK_ERR(err, "large inflate"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (d_stream.total_out != 2*uncomprLen + comprLen/2) { - fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out); - exit(1); - } else { - printf("large_inflate(): OK\n"); - } -} - -/* =========================================================================== - * Test deflate() with full flush - */ -void test_flush(compr, comprLen) - Byte *compr; - uLong *comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - uInt len = (uInt)strlen(hello)+1; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - c_stream.next_in = (Bytef*)hello; - c_stream.next_out = compr; - c_stream.avail_in = 3; - c_stream.avail_out = (uInt)*comprLen; - err = deflate(&c_stream, Z_FULL_FLUSH); - CHECK_ERR(err, "deflate"); - - compr[3]++; /* force an error in first compressed block */ - c_stream.avail_in = len - 3; - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - CHECK_ERR(err, "deflate"); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); - - *comprLen = c_stream.total_out; -} - -/* =========================================================================== - * Test inflateSync() - */ -void test_sync(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = 2; /* just read the zlib header */ - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - d_stream.next_out = uncompr; - d_stream.avail_out = (uInt)uncomprLen; - - inflate(&d_stream, Z_NO_FLUSH); - CHECK_ERR(err, "inflate"); - - d_stream.avail_in = (uInt)comprLen-2; /* read all compressed data */ - err = inflateSync(&d_stream); /* but skip the damaged part */ - CHECK_ERR(err, "inflateSync"); - - err = inflate(&d_stream, Z_FINISH); - if (err != Z_DATA_ERROR) { - fprintf(stderr, "inflate should report DATA_ERROR\n"); - /* Because of incorrect adler32 */ - exit(1); - } - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - printf("after inflateSync(): hel%s\n", (char *)uncompr); -} - -/* =========================================================================== - * Test deflate() with preset dictionary - */ -void test_dict_deflate(compr, comprLen) - Byte *compr; - uLong comprLen; -{ - z_stream c_stream; /* compression stream */ - int err; - - c_stream.zalloc = (alloc_func)0; - c_stream.zfree = (free_func)0; - c_stream.opaque = (voidpf)0; - - err = deflateInit(&c_stream, Z_BEST_COMPRESSION); - CHECK_ERR(err, "deflateInit"); - - err = deflateSetDictionary(&c_stream, - (const Bytef*)dictionary, sizeof(dictionary)); - CHECK_ERR(err, "deflateSetDictionary"); - - dictId = c_stream.adler; - c_stream.next_out = compr; - c_stream.avail_out = (uInt)comprLen; - - c_stream.next_in = (Bytef*)hello; - c_stream.avail_in = (uInt)strlen(hello)+1; - - err = deflate(&c_stream, Z_FINISH); - if (err != Z_STREAM_END) { - fprintf(stderr, "deflate should report Z_STREAM_END\n"); - exit(1); - } - err = deflateEnd(&c_stream); - CHECK_ERR(err, "deflateEnd"); -} - -/* =========================================================================== - * Test inflate() with a preset dictionary - */ -void test_dict_inflate(compr, comprLen, uncompr, uncomprLen) - Byte *compr, *uncompr; - uLong comprLen, uncomprLen; -{ - int err; - z_stream d_stream; /* decompression stream */ - - strcpy((char*)uncompr, "garbage"); - - d_stream.zalloc = (alloc_func)0; - d_stream.zfree = (free_func)0; - d_stream.opaque = (voidpf)0; - - d_stream.next_in = compr; - d_stream.avail_in = (uInt)comprLen; - - err = inflateInit(&d_stream); - CHECK_ERR(err, "inflateInit"); - - d_stream.next_out = uncompr; - d_stream.avail_out = (uInt)uncomprLen; - - for (;;) { - err = inflate(&d_stream, Z_NO_FLUSH); - if (err == Z_STREAM_END) break; - if (err == Z_NEED_DICT) { - if (d_stream.adler != dictId) { - fprintf(stderr, "unexpected dictionary"); - exit(1); - } - err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary, - sizeof(dictionary)); - } - CHECK_ERR(err, "inflate with dict"); - } - - err = inflateEnd(&d_stream); - CHECK_ERR(err, "inflateEnd"); - - if (strcmp((char*)uncompr, hello)) { - fprintf(stderr, "bad inflate with dict\n"); - exit(1); - } else { - printf("inflate with dictionary: %s\n", (char *)uncompr); - } -} - -/* =========================================================================== - * Usage: example [output.gz [input.gz]] - */ - -int main(argc, argv) - int argc; - char *argv[]; -{ - Byte *compr, *uncompr; - uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ - uLong uncomprLen = comprLen; - static const char* myVersion = ZLIB_VERSION; - - if (zlibVersion()[0] != myVersion[0]) { - fprintf(stderr, "incompatible zlib version\n"); - exit(1); - - } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) { - fprintf(stderr, "warning: different zlib version\n"); - } - - printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n", - ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags()); - - compr = (Byte*)calloc((uInt)comprLen, 1); - uncompr = (Byte*)calloc((uInt)uncomprLen, 1); - /* compr and uncompr are cleared to avoid reading uninitialized - * data and to ensure that uncompr compresses well. - */ - if (compr == Z_NULL || uncompr == Z_NULL) { - printf("out of memory\n"); - exit(1); - } - test_compress(compr, comprLen, uncompr, uncomprLen); - - test_gzio((argc > 1 ? argv[1] : TESTFILE), - uncompr, uncomprLen); - - test_deflate(compr, comprLen); - test_inflate(compr, comprLen, uncompr, uncomprLen); - - test_large_deflate(compr, comprLen, uncompr, uncomprLen); - test_large_inflate(compr, comprLen, uncompr, uncomprLen); - - test_flush(compr, &comprLen); - test_sync(compr, comprLen, uncompr, uncomprLen); - comprLen = uncomprLen; - - test_dict_deflate(compr, comprLen); - test_dict_inflate(compr, comprLen, uncompr, uncomprLen); - - free(compr); - free(uncompr); - - return 0; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/gzio.c b/components/dfs/filesystems/jffs2/cyg/compress/src/gzio.c deleted file mode 100644 index 7e90f4928f..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/gzio.c +++ /dev/null @@ -1,1026 +0,0 @@ -/* gzio.c -- IO on .gz files - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code. - */ - -/* @(#) $Id$ */ - -#include <stdio.h> - -#include "zutil.h" - -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS -#endif - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -#ifndef Z_BUFSIZE -# ifdef MAXSEG_64K -# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */ -# else -# define Z_BUFSIZE 16384 -# endif -#endif -#ifndef Z_PRINTF_BUFSIZE -# define Z_PRINTF_BUFSIZE 4096 -#endif - -#ifdef __MVS__ -# pragma map (fdopen , "\174\174FDOPEN") - FILE *fdopen(int, const char *); -#endif - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern void free OF((voidpf ptr)); -#endif - -#define ALLOC(size) malloc(size) -#define TRYFREE(p) {if (p) free(p);} - -static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ - -/* gzip flag byte */ -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */ -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */ -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */ -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */ -#define COMMENT 0x10 /* bit 4 set: file comment present */ -#define RESERVED 0xE0 /* bits 5..7: reserved */ - -typedef struct gz_stream { - z_stream stream; - int z_err; /* error code for last stream operation */ - int z_eof; /* set if end of input file */ - FILE *file; /* .gz file */ - Byte *inbuf; /* input buffer */ - Byte *outbuf; /* output buffer */ - uLong crc; /* crc32 of uncompressed data */ - char *msg; /* error message */ - char *path; /* path name for debugging only */ - int transparent; /* 1 if input file is not a .gz file */ - char mode; /* 'w' or 'r' */ - z_off_t start; /* start of compressed data in file (header skipped) */ - z_off_t in; /* bytes into deflate or inflate */ - z_off_t out; /* bytes out of deflate or inflate */ - int back; /* one character push-back */ - int last; /* true if push-back is last character */ -} gz_stream; - - -local gzFile gz_open OF((const char *path, const char *mode, int fd)); -local int do_flush OF((gzFile file, int flush)); -local int get_byte OF((gz_stream *s)); -local void check_header OF((gz_stream *s)); -local int destroy OF((gz_stream *s)); -local void putLong OF((FILE *file, uLong x)); -local uLong getLong OF((gz_stream *s)); - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb"). The file is given either by file descriptor - or path name (if fd == -1). - gz_open returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). -*/ -local gzFile gz_open (path, mode, fd) - const char *path; - const char *mode; - int fd; -{ - int err; - int level = Z_DEFAULT_COMPRESSION; /* compression level */ - int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ - char *p = (char*)mode; - gz_stream *s; - char fmode[80]; /* copy of mode, without the compression level */ - char *m = fmode; - - if (!path || !mode) return Z_NULL; - - s = (gz_stream *)ALLOC(sizeof(gz_stream)); - if (!s) return Z_NULL; - - s->stream.zalloc = (alloc_func)0; - s->stream.zfree = (free_func)0; - s->stream.opaque = (voidpf)0; - s->stream.next_in = s->inbuf = Z_NULL; - s->stream.next_out = s->outbuf = Z_NULL; - s->stream.avail_in = s->stream.avail_out = 0; - s->file = NULL; - s->z_err = Z_OK; - s->z_eof = 0; - s->in = 0; - s->out = 0; - s->back = EOF; - s->crc = crc32(0L, Z_NULL, 0); - s->msg = NULL; - s->transparent = 0; - - s->path = (char*)ALLOC(strlen(path)+1); - if (s->path == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - strcpy(s->path, path); /* do this early for debugging */ - - s->mode = '\0'; - do { - if (*p == 'r') s->mode = 'r'; - if (*p == 'w' || *p == 'a') s->mode = 'w'; - if (*p >= '0' && *p <= '9') { - level = *p - '0'; - } else if (*p == 'f') { - strategy = Z_FILTERED; - } else if (*p == 'h') { - strategy = Z_HUFFMAN_ONLY; - } else if (*p == 'R') { - strategy = Z_RLE; - } else { - *m++ = *p; /* copy the mode */ - } - } while (*p++ && m != fmode + sizeof(fmode)); - if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateInit2(&(s->stream), level, - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy); - /* windowBits is passed < 0 to suppress zlib header */ - - s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); -#endif - if (err != Z_OK || s->outbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } else { - s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); - - err = inflateInit2(&(s->stream), -MAX_WBITS); - /* windowBits is passed < 0 to tell that there is no zlib header. - * Note that in this case inflate *requires* an extra "dummy" byte - * after the compressed stream in order to complete decompression and - * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are - * present after the compressed stream. - */ - if (err != Z_OK || s->inbuf == Z_NULL) { - return destroy(s), (gzFile)Z_NULL; - } - } - s->stream.avail_out = Z_BUFSIZE; - - errno = 0; - s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode); - - if (s->file == NULL) { - return destroy(s), (gzFile)Z_NULL; - } - if (s->mode == 'w') { - /* Write a very simple .gz header: - */ - fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], - Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE); - s->start = 10L; - /* We use 10L instead of ftell(s->file) to because ftell causes an - * fflush on some systems. This version of the library doesn't use - * start anyway in write mode, so this initialization is not - * necessary. - */ - } else { - check_header(s); /* skip the .gz header */ - s->start = ftell(s->file) - s->stream.avail_in; - } - - return (gzFile)s; -} - -/* =========================================================================== - Opens a gzip (.gz) file for reading or writing. -*/ -gzFile ZEXPORT gzopen (path, mode) - const char *path; - const char *mode; -{ - return gz_open (path, mode, -1); -} - -/* =========================================================================== - Associate a gzFile with the file descriptor fd. fd is not dup'ed here - to mimic the behavio(u)r of fdopen. -*/ -gzFile ZEXPORT gzdopen (fd, mode) - int fd; - const char *mode; -{ - char name[46]; /* allow for up to 128-bit integers */ - - if (fd < 0) return (gzFile)Z_NULL; - sprintf(name, "<fd:%d>", fd); /* for debugging */ - - return gz_open (name, mode, fd); -} - -/* =========================================================================== - * Update the compression level and strategy - */ -int ZEXPORT gzsetparams (file, level, strategy) - gzFile file; - int level; - int strategy; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - /* Make room to allow flushing */ - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - } - s->stream.avail_out = Z_BUFSIZE; - } - - return deflateParams (&(s->stream), level, strategy); -} - -/* =========================================================================== - Read a byte from a gz_stream; update next_in and avail_in. Return EOF - for end of file. - IN assertion: the stream s has been sucessfully opened for reading. -*/ -local int get_byte(s) - gz_stream *s; -{ - if (s->z_eof) return EOF; - if (s->stream.avail_in == 0) { - errno = 0; - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) s->z_err = Z_ERRNO; - return EOF; - } - s->stream.next_in = s->inbuf; - } - s->stream.avail_in--; - return *(s->stream.next_in)++; -} - -/* =========================================================================== - Check the gzip header of a gz_stream opened for reading. Set the stream - mode to transparent if the gzip magic header is not present; set s->err - to Z_DATA_ERROR if the magic header is present but the rest of the header - is incorrect. - IN assertion: the stream s has already been created sucessfully; - s->stream.avail_in is zero for the first time, but may be non-zero - for concatenated .gz files. -*/ -local void check_header(s) - gz_stream *s; -{ - int method; /* method byte */ - int flags; /* flags byte */ - uInt len; - int c; - - /* Assure two bytes in the buffer so we can peek ahead -- handle case - where first byte of header is at the end of the buffer after the last - gzip segment */ - len = s->stream.avail_in; - if (len < 2) { - if (len) s->inbuf[0] = s->stream.next_in[0]; - errno = 0; - len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file); - if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO; - s->stream.avail_in += len; - s->stream.next_in = s->inbuf; - if (s->stream.avail_in < 2) { - s->transparent = s->stream.avail_in; - return; - } - } - - /* Peek ahead to check the gzip magic header */ - if (s->stream.next_in[0] != gz_magic[0] || - s->stream.next_in[1] != gz_magic[1]) { - s->transparent = 1; - return; - } - s->stream.avail_in -= 2; - s->stream.next_in += 2; - - /* Check the rest of the gzip header */ - method = get_byte(s); - flags = get_byte(s); - if (method != Z_DEFLATED || (flags & RESERVED) != 0) { - s->z_err = Z_DATA_ERROR; - return; - } - - /* Discard time, xflags and OS code: */ - for (len = 0; len < 6; len++) (void)get_byte(s); - - if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ - len = (uInt)get_byte(s); - len += ((uInt)get_byte(s))<<8; - /* len is garbage if EOF but the loop below will quit anyway */ - while (len-- != 0 && get_byte(s) != EOF) ; - } - if ((flags & ORIG_NAME) != 0) { /* skip the original file name */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & COMMENT) != 0) { /* skip the .gz file comment */ - while ((c = get_byte(s)) != 0 && c != EOF) ; - } - if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ - for (len = 0; len < 2; len++) (void)get_byte(s); - } - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK; -} - - /* =========================================================================== - * Cleanup then free the given gz_stream. Return a zlib error code. - Try freeing in the reverse order of allocations. - */ -local int destroy (s) - gz_stream *s; -{ - int err = Z_OK; - - if (!s) return Z_STREAM_ERROR; - - TRYFREE(s->msg); - - if (s->stream.state != NULL) { - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - err = Z_STREAM_ERROR; -#else - err = deflateEnd(&(s->stream)); -#endif - } else if (s->mode == 'r') { - err = inflateEnd(&(s->stream)); - } - } - if (s->file != NULL && fclose(s->file)) { -#ifdef ESPIPE - if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */ -#endif - err = Z_ERRNO; - } - if (s->z_err < 0) err = s->z_err; - - TRYFREE(s->inbuf); - TRYFREE(s->outbuf); - TRYFREE(s->path); - TRYFREE(s); - return err; -} - -/* =========================================================================== - Reads the given number of uncompressed bytes from the compressed file. - gzread returns the number of bytes actually read (0 for end of file). -*/ -int ZEXPORT gzread (file, buf, len) - gzFile file; - voidp buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - Bytef *start = (Bytef*)buf; /* starting point for crc computation */ - Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */ - - if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR; - - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1; - if (s->z_err == Z_STREAM_END) return 0; /* EOF */ - - next_out = (Byte*)buf; - s->stream.next_out = (Bytef*)buf; - s->stream.avail_out = len; - - if (s->stream.avail_out && s->back != EOF) { - *next_out++ = s->back; - s->stream.next_out++; - s->stream.avail_out--; - s->back = EOF; - s->out++; - start++; - if (s->last) { - s->z_err = Z_STREAM_END; - return 1; - } - } - - while (s->stream.avail_out != 0) { - - if (s->transparent) { - /* Copy first the lookahead bytes: */ - uInt n = s->stream.avail_in; - if (n > s->stream.avail_out) n = s->stream.avail_out; - if (n > 0) { - zmemcpy(s->stream.next_out, s->stream.next_in, n); - next_out += n; - s->stream.next_out = next_out; - s->stream.next_in += n; - s->stream.avail_out -= n; - s->stream.avail_in -= n; - } - if (s->stream.avail_out > 0) { - s->stream.avail_out -= - (uInt)fread(next_out, 1, s->stream.avail_out, s->file); - } - len -= s->stream.avail_out; - s->in += len; - s->out += len; - if (len == 0) s->z_eof = 1; - return (int)len; - } - if (s->stream.avail_in == 0 && !s->z_eof) { - - errno = 0; - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file); - if (s->stream.avail_in == 0) { - s->z_eof = 1; - if (ferror(s->file)) { - s->z_err = Z_ERRNO; - break; - } - } - s->stream.next_in = s->inbuf; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = inflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - - if (s->z_err == Z_STREAM_END) { - /* Check CRC and original size */ - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - start = s->stream.next_out; - - if (getLong(s) != s->crc) { - s->z_err = Z_DATA_ERROR; - } else { - (void)getLong(s); - /* The uncompressed length returned by above getlong() may be - * different from s->out in case of concatenated .gz files. - * Check for such files: - */ - check_header(s); - if (s->z_err == Z_OK) { - inflateReset(&(s->stream)); - s->crc = crc32(0L, Z_NULL, 0); - } - } - } - if (s->z_err != Z_OK || s->z_eof) break; - } - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start)); - - if (len == s->stream.avail_out && - (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO)) - return -1; - return (int)(len - s->stream.avail_out); -} - - -/* =========================================================================== - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ -int ZEXPORT gzgetc(file) - gzFile file; -{ - unsigned char c; - - return gzread(file, &c, 1) == 1 ? c : -1; -} - - -/* =========================================================================== - Push one byte back onto the stream. -*/ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF; - s->back = c; - s->out--; - s->last = (s->z_err == Z_STREAM_END); - if (s->last) s->z_err = Z_OK; - s->z_eof = 0; - return c; -} - - -/* =========================================================================== - Reads bytes from the compressed file until len-1 characters are - read, or a newline character is read and transferred to buf, or an - end-of-file condition is encountered. The string is then terminated - with a null character. - gzgets returns buf, or Z_NULL in case of error. - - The current implementation is not optimized at all. -*/ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - char *b = buf; - if (buf == Z_NULL || len <= 0) return Z_NULL; - - while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ; - *buf = '\0'; - return b == buf && len > 0 ? Z_NULL : b; -} - - -#ifndef NO_GZCOMPRESS -/* =========================================================================== - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of bytes actually written (0 in case of error). -*/ -int ZEXPORT gzwrite (file, buf, len) - gzFile file; - voidpc buf; - unsigned len; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.next_in = (Bytef*)buf; - s->stream.avail_in = len; - - while (s->stream.avail_in != 0) { - - if (s->stream.avail_out == 0) { - - s->stream.next_out = s->outbuf; - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) { - s->z_err = Z_ERRNO; - break; - } - s->stream.avail_out = Z_BUFSIZE; - } - s->in += s->stream.avail_in; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), Z_NO_FLUSH); - s->in -= s->stream.avail_in; - s->out -= s->stream.avail_out; - if (s->z_err != Z_OK) break; - } - s->crc = crc32(s->crc, (const Bytef *)buf, len); - - return (int)(len - s->stream.avail_in); -} - - -/* =========================================================================== - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). -*/ -#ifdef STDC -#include <stdarg.h> - -int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...) -{ - char buf[Z_PRINTF_BUFSIZE]; - va_list va; - int len; - - buf[sizeof(buf) - 1] = 0; - va_start(va, format); -#ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf(buf, format, va); - va_end(va); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = vsprintf(buf, format, va); - va_end(va); -# endif -#else -# ifdef HAS_vsnprintf_void - (void)vsnprintf(buf, sizeof(buf), format, va); - va_end(va); - len = strlen(buf); -# else - len = vsnprintf(buf, sizeof(buf), format, va); - va_end(va); -# endif -#endif - if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, (unsigned)len); -} -#else /* not ANSI C */ - -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; -{ - char buf[Z_PRINTF_BUFSIZE]; - int len; - - buf[sizeof(buf) - 1] = 0; -#ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < sizeof(buf); len++) - if (buf[len] == 0) break; -# else - len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#else -# ifdef HAS_snprintf_void - snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen(buf); -# else - len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif -#endif - if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0) - return 0; - return gzwrite(file, buf, len); -} -#endif - -/* =========================================================================== - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ -int ZEXPORT gzputc(file, c) - gzFile file; - int c; -{ - unsigned char cc = (unsigned char) c; /* required for big endian systems */ - - return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1; -} - - -/* =========================================================================== - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ -int ZEXPORT gzputs(file, s) - gzFile file; - const char *s; -{ - return gzwrite(file, (char*)s, (unsigned)strlen(s)); -} - - -/* =========================================================================== - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. -*/ -local int do_flush (file, flush) - gzFile file; - int flush; -{ - uInt len; - int done = 0; - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR; - - s->stream.avail_in = 0; /* should be zero already anyway */ - - for (;;) { - len = Z_BUFSIZE - s->stream.avail_out; - - if (len != 0) { - if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) { - s->z_err = Z_ERRNO; - return Z_ERRNO; - } - s->stream.next_out = s->outbuf; - s->stream.avail_out = Z_BUFSIZE; - } - if (done) break; - s->out += s->stream.avail_out; - s->z_err = deflate(&(s->stream), flush); - s->out -= s->stream.avail_out; - - /* Ignore the second of two consecutive flushes: */ - if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK; - - /* deflate has finished flushing only when it hasn't used up - * all the available space in the output buffer: - */ - done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END); - - if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break; - } - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} - -int ZEXPORT gzflush (file, flush) - gzFile file; - int flush; -{ - gz_stream *s = (gz_stream*)file; - int err = do_flush (file, flush); - - if (err) return err; - fflush(s->file); - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err; -} -#endif /* NO_GZCOMPRESS */ - -/* =========================================================================== - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error. - SEEK_END is not implemented, returns error. - In this version of the library, gzseek can be extremely slow. -*/ -z_off_t ZEXPORT gzseek (file, offset, whence) - gzFile file; - z_off_t offset; - int whence; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || whence == SEEK_END || - s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) { - return -1L; - } - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return -1L; -#else - if (whence == SEEK_SET) { - offset -= s->in; - } - if (offset < 0) return -1L; - - /* At this point, offset is the number of zero bytes to write. */ - if (s->inbuf == Z_NULL) { - s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */ - if (s->inbuf == Z_NULL) return -1L; - zmemzero(s->inbuf, Z_BUFSIZE); - } - while (offset > 0) { - uInt size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (uInt)offset; - - size = gzwrite(file, s->inbuf, size); - if (size == 0) return -1L; - - offset -= size; - } - return s->in; -#endif - } - /* Rest of function is for reading only */ - - /* compute absolute position */ - if (whence == SEEK_CUR) { - offset += s->out; - } - if (offset < 0) return -1L; - - if (s->transparent) { - /* map to fseek */ - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - if (fseek(s->file, offset, SEEK_SET) < 0) return -1L; - - s->in = s->out = offset; - return offset; - } - - /* For a negative seek, rewind and use positive seek */ - if (offset >= s->out) { - offset -= s->out; - } else if (gzrewind(file) < 0) { - return -1L; - } - /* offset is now the number of bytes to skip. */ - - if (offset != 0 && s->outbuf == Z_NULL) { - s->outbuf = (Byte*)ALLOC(Z_BUFSIZE); - if (s->outbuf == Z_NULL) return -1L; - } - if (offset && s->back != EOF) { - s->back = EOF; - s->out++; - offset--; - if (s->last) s->z_err = Z_STREAM_END; - } - while (offset > 0) { - int size = Z_BUFSIZE; - if (offset < Z_BUFSIZE) size = (int)offset; - - size = gzread(file, s->outbuf, (uInt)size); - if (size <= 0) return -1L; - offset -= size; - } - return s->out; -} - -/* =========================================================================== - Rewinds input file. -*/ -int ZEXPORT gzrewind (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return -1; - - s->z_err = Z_OK; - s->z_eof = 0; - s->back = EOF; - s->stream.avail_in = 0; - s->stream.next_in = s->inbuf; - s->crc = crc32(0L, Z_NULL, 0); - if (!s->transparent) (void)inflateReset(&s->stream); - s->in = 0; - s->out = 0; - return fseek(s->file, s->start, SEEK_SET); -} - -/* =========================================================================== - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. -*/ -z_off_t ZEXPORT gztell (file) - gzFile file; -{ - return gzseek(file, 0L, SEEK_CUR); -} - -/* =========================================================================== - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ -int ZEXPORT gzeof (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - /* With concatenated compressed files that can have embedded - * crc trailers, z_eof is no longer the only/best indicator of EOF - * on a gz_stream. Handle end-of-stream error explicitly here. - */ - if (s == NULL || s->mode != 'r') return 0; - if (s->z_eof) return 1; - return s->z_err == Z_STREAM_END; -} - -/* =========================================================================== - Returns 1 if reading and doing so transparently, otherwise zero. -*/ -int ZEXPORT gzdirect (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL || s->mode != 'r') return 0; - return s->transparent; -} - -/* =========================================================================== - Outputs a long in LSB order to the given file -*/ -local void putLong (file, x) - FILE *file; - uLong x; -{ - int n; - for (n = 0; n < 4; n++) { - fputc((int)(x & 0xff), file); - x >>= 8; - } -} - -/* =========================================================================== - Reads a long in LSB order from the given gz_stream. Sets z_err in case - of error. -*/ -local uLong getLong (s) - gz_stream *s; -{ - uLong x = (uLong)get_byte(s); - int c; - - x += ((uLong)get_byte(s))<<8; - x += ((uLong)get_byte(s))<<16; - c = get_byte(s); - if (c == EOF) s->z_err = Z_DATA_ERROR; - x += ((uLong)c)<<24; - return x; -} - -/* =========================================================================== - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. -*/ -int ZEXPORT gzclose (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return Z_STREAM_ERROR; - - if (s->mode == 'w') { -#ifdef NO_GZCOMPRESS - return Z_STREAM_ERROR; -#else - if (do_flush (file, Z_FINISH) != Z_OK) - return destroy((gz_stream*)file); - - putLong (s->file, s->crc); - putLong (s->file, (uLong)(s->in & 0xffffffff)); -#endif - } - return destroy((gz_stream*)file); -} - -#ifdef STDC -# define zstrerror(errnum) strerror(errnum) -#else -# define zstrerror(errnum) "" -#endif - -/* =========================================================================== - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ -const char * ZEXPORT gzerror (file, errnum) - gzFile file; - int *errnum; -{ - char *m; - gz_stream *s = (gz_stream*)file; - - if (s == NULL) { - *errnum = Z_STREAM_ERROR; - return (const char*)ERR_MSG(Z_STREAM_ERROR); - } - *errnum = s->z_err; - if (*errnum == Z_OK) return (const char*)""; - - m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg); - - if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err); - - TRYFREE(s->msg); - s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3); - if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR); - strcpy(s->msg, s->path); - strcat(s->msg, ": "); - strcat(s->msg, m); - return (const char*)s->msg; -} - -/* =========================================================================== - Clear the error and end-of-file flags, and do the same for the real file. -*/ -void ZEXPORT gzclearerr (file) - gzFile file; -{ - gz_stream *s = (gz_stream*)file; - - if (s == NULL) return; - if (s->z_err != Z_STREAM_END) s->z_err = Z_OK; - s->z_eof = 0; - clearerr(s->file); -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/infback.c b/components/dfs/filesystems/jffs2/cyg/compress/src/infback.c deleted file mode 100644 index 455dbc9ee8..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/infback.c +++ /dev/null @@ -1,623 +0,0 @@ -/* infback.c -- inflate using a call-back interface - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - This code is largely copied from inflate.c. Normally either infback.o or - inflate.o would be linked into an application--not both. The interface - with inffast.c is retained so that optimized assembler-coded versions of - inflate_fast() can be used with either inflate.c or infback.c. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); - -/* - strm provides memory allocation functions in zalloc and zfree, or - Z_NULL to use the library memory allocation functions. - - windowBits is in the range 8..15, and window is a user-supplied - window and output buffer that is 2**windowBits bytes. - */ -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; -int windowBits; -unsigned char FAR *window; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->write = 0; - state->whave = 0; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -/* Macros for inflateBack(): */ - -/* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Assure that some input is available. If input is requested, but denied, - then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflateBack() - with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflateBack() with - an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Assure that some output space is available, by writing out the window - if it's full. If the write fails, return from inflateBack() with a - Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) - -/* - strm provides the memory allocation functions and window buffer on input, - and provides information on the unused input on return. For Z_DATA_ERROR - returns, strm will also provide an error message. - - in() and out() are the call-back input and output functions. When - inflateBack() needs more input, it calls in(). When inflateBack() has - filled the window with output, or when it completes with data in the - window, it calls out() to write out the data. The application must not - change the provided input until in() is called again or inflateBack() - returns. The application must not change the window/output buffer until - inflateBack() returns. - - in() and out() are called with a descriptor parameter provided in the - inflateBack() call. This parameter can be a structure that provides the - information required to do the read or write, as well as accumulated - information on the input and output such as totals and check values. - - in() should return zero on failure. out() should return non-zero on - failure. If either in() or out() fails, than inflateBack() returns a - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it - was in() or out() that caused in the error. Otherwise, inflateBack() - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format - error, or Z_MEM_ERROR if it could not allocate memory for the state. - inflateBack() can also return Z_STREAM_ERROR if the input parameters - are not correct, i.e. strm is Z_NULL or the state was not initialized. - */ -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; -in_func in; -void FAR *in_desc; -out_func out; -void FAR *out_desc; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; - - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; - } - else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } - - /* get a literal, length, or end-of-block code */ - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.op && (this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - - /* process literal */ - if (this.op == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } - - /* process end of block */ - if (this.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - - /* invalid code */ - if (this.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - - /* get distance code */ - for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if ((this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - if (this.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)this.val; - - /* get distance extra bits, if any */ - state->extra = (unsigned)(this.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; - - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; - - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } - - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; -} - -int ZEXPORT inflateBackEnd(strm) -z_streamp strm; -{ - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/infblock.c b/components/dfs/filesystems/jffs2/cyg/compress/src/infblock.c deleted file mode 100644 index c2521d5a87..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/infblock.c +++ /dev/null @@ -1,403 +0,0 @@ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "infblock.h" -#include "inftrees.h" -//#include "infcodes.h" //no such file! -#include "infutil.h" - -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - -/* Table for deflate from PKZIP's appnote.txt. */ -local const uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_streamp z; -uLongf *c; -{ - if (c != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens); - if (s->mode == CODES) - inflate_codes_free(s->sub.decode.codes, z); - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0); - Tracev((stderr, "inflate: blocks reset\n")); -} - - -inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_streamp z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->hufts = - (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL) - { - ZFREE(z, s); - return Z_NULL; - } - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s->hufts); - ZFREE(z, s); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Tracev((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, Z_NULL); - return s; -} - - -int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Tracev((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Tracev((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td, z); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BAD; - z->msg = (char*)"invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if ((((~b) >> 16) & 0xffff) != (b & 0xffff)) - { - s->mode = BAD; - z->msg = (char*)"invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE); - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BAD; - z->msg = (char*)"too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, s->hufts, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - { - ZFREE(z, s->sub.trees.blens); - s->mode = BAD; - } - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->bits; - c = h->base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - ZFREE(z, s->sub.trees.blens); - s->mode = BAD; - z->msg = (char*)"invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, - s->hufts, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - { - ZFREE(z, s->sub.trees.blens); - s->mode = BAD; - } - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok\n")); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.codes = c; - } - ZFREE(z, s->sub.trees.blens); - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONE; - case DONE: - r = Z_STREAM_END; - LEAVE - case BAD: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -int inflate_blocks_free(s, z) -inflate_blocks_statef *s; -z_streamp z; -{ - inflate_blocks_reset(s, z, Z_NULL); - ZFREE(z, s->window); - ZFREE(z, s->hufts); - ZFREE(z, s); - Tracev((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - - -void inflate_set_dictionary(s, d, n) -inflate_blocks_statef *s; -const Bytef *d; -uInt n; -{ - zmemcpy(s->window, d, n); - s->read = s->write = s->window + n; -} - - -/* Returns true if inflate is currently at the end of a block generated - * by Z_SYNC_FLUSH or Z_FULL_FLUSH. - * IN assertion: s != Z_NULL - */ -int inflate_blocks_sync_point(s) -inflate_blocks_statef *s; -{ - return s->mode == LENS; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/infblock.h b/components/dfs/filesystems/jffs2/cyg/compress/src/infblock.h deleted file mode 100644 index 17ffbda2f8..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/infblock.h +++ /dev/null @@ -1,39 +0,0 @@ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; -typedef uLong (*check_func) OF((uLong check, const Bytef *buf, uInt len)); // add by prife -extern inflate_blocks_statef * inflate_blocks_new OF(( - z_streamp z, - check_func c, /* check function */ - uInt w)); /* window size */ - -extern int inflate_blocks OF(( - inflate_blocks_statef *, - z_streamp , - int)); /* initial return code */ - -extern void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_streamp , - uLongf *)); /* check value on output */ - -extern int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_streamp)); - -extern void inflate_set_dictionary OF(( - inflate_blocks_statef *s, - const Bytef *d, /* dictionary */ - uInt n)); /* dictionary length */ - -extern int inflate_blocks_sync_point OF(( - inflate_blocks_statef *s)); diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/inffast.c b/components/dfs/filesystems/jffs2/cyg/compress/src/inffast.c deleted file mode 100644 index bbee92ed1e..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/inffast.c +++ /dev/null @@ -1,318 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code this; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - write = state->write; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - this = lcode[hold & lmask]; - dolen: - op = (unsigned)(this.bits); - hold >>= op; - bits -= op; - op = (unsigned)(this.op); - if (op == 0) { /* literal */ - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - PUP(out) = (unsigned char)(this.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - this = dcode[hold & dmask]; - dodist: - op = (unsigned)(this.bits); - hold >>= op; - bits -= op; - op = (unsigned)(this.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(this.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - from = window - OFF; - if (write == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (write < op) { /* wrap around window */ - from += wsize + write - op; - op -= write; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (write < len) { /* some from start of window */ - op = write; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += write - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - this = dcode[this.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - this = lcode[this.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and write == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/inffast.h b/components/dfs/filesystems/jffs2/cyg/compress/src/inffast.h deleted file mode 100644 index 1e88d2d97b..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/inffixed.h b/components/dfs/filesystems/jffs2/cyg/compress/src/inffixed.h deleted file mode 100644 index 75ed4b5978..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/inflate.c b/components/dfs/filesystems/jffs2/cyg/compress/src/inflate.c deleted file mode 100644 index 792fdee8e9..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/inflate.c +++ /dev/null @@ -1,1368 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common write == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - strm->adler = 1; /* to support ill-conceived Java test suite */ - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->wsize = 0; - state->whave = 0; - state->write = 0; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - if (windowBits < 0) { - state->wrap = 0; - windowBits = -windowBits; - } - else { - state->wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) windowBits &= 15; -#endif - } - if (windowBits < 8 || windowBits > 15) { - ZFREE(strm, state); - strm->state = Z_NULL; - return Z_STREAM_ERROR; - } - state->wbits = (unsigned)windowBits; - state->window = Z_NULL; - return inflateReset(strm); -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include <stdio.h> - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->write = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->write = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->write; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->write, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->write = copy; - state->whave = state->wsize; - } - else { - state->write += dist; - if (state->write == state->wsize) state->write = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code this; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.val < 16) { - NEEDBITS(this.bits); - DROPBITS(this.bits); - state->lens[state->have++] = this.val; - } - else { - if (this.val == 16) { - NEEDBITS(this.bits + 2); - DROPBITS(this.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (this.val == 17) { - NEEDBITS(this.bits + 3); - DROPBITS(this.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(this.bits + 7); - DROPBITS(this.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* build code tables */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - break; - } - for (;;) { - this = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if (this.op && (this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - state->length = (unsigned)this.val; - if ((int)(this.op) == 0) { - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", this.val)); - state->mode = LIT; - break; - } - if (this.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - if (this.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(this.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->mode = DIST; - case DIST: - for (;;) { - this = state->distcode[BITS(state->distbits)]; - if ((unsigned)(this.bits) <= bits) break; - PULLBYTE(); - } - if ((this.op & 0xf0) == 0) { - last = this; - for (;;) { - this = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + this.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(this.bits); - if (this.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)this.val; - state->extra = (unsigned)(this.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - if (state->offset > state->whave + out - left) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->write) { - copy -= state->write; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->write - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long id; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - if (state->mode == DICT) { - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/inflate.h b/components/dfs/filesystems/jffs2/cyg/compress/src/inflate.h deleted file mode 100644 index 07bd3e78a7..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/inflate.h +++ /dev/null @@ -1,115 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2004 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN, /* i: waiting for length/lit code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to the BAD or MEM mode -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME - NAME -> COMMENT -> HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - Read deflate blocks: - TYPE -> STORED or TABLE or LEN or CHECK - STORED -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN - Read deflate codes: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 7K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned write; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ -}; diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/inftrees.c b/components/dfs/filesystems/jffs2/cyg/compress/src/inftrees.c deleted file mode 100644 index 8a9c13ff03..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/inftrees.c +++ /dev/null @@ -1,329 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.3 Copyright 1995-2005 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code this; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)1; - this.val = (unsigned short)0; - *(*table)++ = this; /* make a table to force an error */ - *(*table)++ = this; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min <= MAXBITS; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked when a LENS table is being made - against the space in *table, ENOUGH, minus the maximum space needed by - the worst case distance code, MAXD. This should never happen, but the - sufficiency of ENOUGH has not been proven exhaustively, hence the check. - This assumes that when type == LENS, bits == 9. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - this.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - this.op = (unsigned char)0; - this.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - this.op = (unsigned char)(extra[work[sym]]); - this.val = base[work[sym]]; - } - else { - this.op = (unsigned char)(32 + 64); /* end of block */ - this.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = this; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if (type == LENS && used >= ENOUGH - MAXD) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - this.op = (unsigned char)64; /* invalid code marker */ - this.bits = (unsigned char)(len - drop); - this.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - this.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = this; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/inftrees.h b/components/dfs/filesystems/jffs2/cyg/compress/src/inftrees.h deleted file mode 100644 index b1104c87e7..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/inftrees.h +++ /dev/null @@ -1,55 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of dynamic tree. The maximum found in a long but non- - exhaustive search was 1444 code structures (852 for length/literals - and 592 for distances, the latter actually the result of an - exhaustive search). The true maximum is not known, but the value - below is more than safe. */ -#define ENOUGH 2048 -#define MAXD 592 - -/* Type of code to build for inftable() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -extern int inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/infutil.c b/components/dfs/filesystems/jffs2/cyg/compress/src/infutil.c deleted file mode 100644 index 9a076221f2..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/infutil.c +++ /dev/null @@ -1,87 +0,0 @@ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "infblock.h" -#include "inftrees.h" -#include "infcodes.h" -#include "infutil.h" - -struct inflate_codes_state {int dummy;}; /* for buggy compilers */ - -/* And'ing with mask[n] masks the lower n bits */ -uInt inflate_mask[17] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - - -/* copy as much as possible from the sliding window to the output area */ -int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_streamp z; -int r; -{ - uInt n; - Bytef *p; - Bytef *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - zmemcpy(p, q, n); - p += n; - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - z->adler = s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - zmemcpy(p, q, n); - p += n; - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/infutil.h b/components/dfs/filesystems/jffs2/cyg/compress/src/infutil.h deleted file mode 100644 index 4401df82fc..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/infutil.h +++ /dev/null @@ -1,98 +0,0 @@ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -#ifndef _INFUTIL_H -#define _INFUTIL_H - -typedef enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONE, /* finished last block, done */ - BAD} /* got a data error--stuck here */ -inflate_block_mode; - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - inflate_block_mode mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - inflate_huft *hufts; /* single malloc for tree space */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}} -#define DUMPBITS(j) {b>>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=(uInt)WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* masks for lower bits (size given to avoid silly warnings with Visual C++) */ -extern uInt inflate_mask[17]; - -/* copy as much as possible from the sliding window to the output area */ -extern int inflate_flush OF(( - inflate_blocks_statef *, - z_streamp , - int)); - -struct internal_state {int dummy;}; /* for buggy compilers */ - -#endif diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/maketree.c b/components/dfs/filesystems/jffs2/cyg/compress/src/maketree.c deleted file mode 100644 index a16d4b1460..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/maketree.c +++ /dev/null @@ -1,85 +0,0 @@ -/* maketree.c -- make inffixed.h table for decoding fixed codes - * Copyright (C) 1995-2002 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* This program is included in the distribution for completeness. - You do not need to compile or run this program since inffixed.h - is already included in the distribution. To use this program - you need to compile zlib with BUILDFIXED defined and then compile - and link this program with the zlib library. Then the output of - this program can be piped to inffixed.h. */ - -#include <stdio.h> -#include <stdlib.h> -#include "zutil.h" -#include "inftrees.h" - -/* simplify the use of the inflate_huft type with some defines */ -#define exop word.what.Exop -#define bits word.what.Bits - -/* generate initialization table for an inflate_huft structure array */ -void maketree(uInt b, inflate_huft *t) -{ - int i, e; - - i = 0; - while (1) - { - e = t[i].exop; - if (e && (e & (16+64)) == 0) /* table pointer */ - { - fprintf(stderr, "maketree: cannot initialize sub-tables!\n"); - exit(1); - } - if (i % 4 == 0) - printf("\n "); - printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base); - if (++i == (1<<b)) - break; - putchar(','); - } - puts(""); -} - -/* create the fixed tables in C initialization syntax */ -void main(void) -{ - int r; - uInt bl, bd; - inflate_huft *tl, *td; - z_stream z; - - z.zalloc = zcalloc; - z.opaque = (voidpf)0; - z.zfree = zcfree; - r = inflate_trees_fixed(&bl, &bd, &tl, &td, &z); - if (r) - { - fprintf(stderr, "inflate_trees_fixed error %d\n", r); - return; - } - puts("/* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by the maketree.c program"); - puts(" */"); - puts(""); - puts("/* WARNING: this file should *not* be used by applications. It is"); - puts(" part of the implementation of the compression library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - printf("local uInt fixed_bl = %d;\n", bl); - printf("local uInt fixed_bd = %d;\n", bd); - printf("local inflate_huft fixed_tl[] = {"); - maketree(bl, tl); - puts(" };"); - printf("local inflate_huft fixed_td[] = {"); - maketree(bd, td); - puts(" };"); -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/minigzip.c b/components/dfs/filesystems/jffs2/cyg/compress/src/minigzip.c deleted file mode 100644 index 4524b96a1d..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/minigzip.c +++ /dev/null @@ -1,322 +0,0 @@ -/* minigzip.c -- simulate gzip using the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * minigzip is a minimal implementation of the gzip utility. This is - * only an example of using zlib and isn't meant to replace the - * full-featured gzip. No attempt is made to deal with file systems - * limiting names to 14 or 8+3 characters, etc... Error checking is - * very limited. So use minigzip only for testing; use gzip for the - * real thing. On MSDOS, use only on file names without extension - * or in pipe mode. - */ - -/* @(#) $Id$ */ - -#include <stdio.h> -#include "zlib.h" - -#ifdef STDC -# include <string.h> -# include <stdlib.h> -#endif - -#ifdef USE_MMAP -# include <sys/types.h> -# include <sys/mman.h> -# include <sys/stat.h> -#endif - -#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) -# include <fcntl.h> -# include <io.h> -# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) -#else -# define SET_BINARY_MODE(file) -#endif - -#ifdef VMS -# define unlink delete -# define GZ_SUFFIX "-gz" -#endif -#ifdef RISCOS -# define unlink remove -# define GZ_SUFFIX "-gz" -# define fileno(file) file->__file -#endif -#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include <unix.h> /* for fileno */ -#endif - -#ifndef WIN32 /* unlink already in stdio.h for WIN32 */ - extern int unlink OF((const char *)); -#endif - -#ifndef GZ_SUFFIX -# define GZ_SUFFIX ".gz" -#endif -#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) - -#define BUFLEN 16384 -#define MAX_NAME_LEN 1024 - -#ifdef MAXSEG_64K -# define local static - /* Needed for systems with limitation on stack size. */ -#else -# define local -#endif - -char *prog; - -void error OF((const char *msg)); -void gz_compress OF((FILE *in, gzFile out)); -#ifdef USE_MMAP -int gz_compress_mmap OF((FILE *in, gzFile out)); -#endif -void gz_uncompress OF((gzFile in, FILE *out)); -void file_compress OF((char *file, char *mode)); -void file_uncompress OF((char *file)); -int main OF((int argc, char *argv[])); - -/* =========================================================================== - * Display error message and exit - */ -void error(msg) - const char *msg; -{ - fprintf(stderr, "%s: %s\n", prog, msg); - exit(1); -} - -/* =========================================================================== - * Compress input to output then close both files. - */ - -void gz_compress(in, out) - FILE *in; - gzFile out; -{ - local char buf[BUFLEN]; - int len; - int err; - -#ifdef USE_MMAP - /* Try first compressing with mmap. If mmap fails (minigzip used in a - * pipe), use the normal fread loop. - */ - if (gz_compress_mmap(in, out) == Z_OK) return; -#endif - for (;;) { - len = (int)fread(buf, 1, sizeof(buf), in); - if (ferror(in)) { - perror("fread"); - exit(1); - } - if (len == 0) break; - - if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err)); - } - fclose(in); - if (gzclose(out) != Z_OK) error("failed gzclose"); -} - -#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <[email protected]> */ - -/* Try compressing the input file at once using mmap. Return Z_OK if - * if success, Z_ERRNO otherwise. - */ -int gz_compress_mmap(in, out) - FILE *in; - gzFile out; -{ - int len; - int err; - int ifd = fileno(in); - caddr_t buf; /* mmap'ed buffer for the entire input file */ - off_t buf_len; /* length of the input file */ - struct stat sb; - - /* Determine the size of the file, needed for mmap: */ - if (fstat(ifd, &sb) < 0) return Z_ERRNO; - buf_len = sb.st_size; - if (buf_len <= 0) return Z_ERRNO; - - /* Now do the actual mmap: */ - buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); - if (buf == (caddr_t)(-1)) return Z_ERRNO; - - /* Compress the whole file at once: */ - len = gzwrite(out, (char *)buf, (unsigned)buf_len); - - if (len != (int)buf_len) error(gzerror(out, &err)); - - munmap(buf, buf_len); - fclose(in); - if (gzclose(out) != Z_OK) error("failed gzclose"); - return Z_OK; -} -#endif /* USE_MMAP */ - -/* =========================================================================== - * Uncompress input to output then close both files. - */ -void gz_uncompress(in, out) - gzFile in; - FILE *out; -{ - local char buf[BUFLEN]; - int len; - int err; - - for (;;) { - len = gzread(in, buf, sizeof(buf)); - if (len < 0) error (gzerror(in, &err)); - if (len == 0) break; - - if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { - error("failed fwrite"); - } - } - if (fclose(out)) error("failed fclose"); - - if (gzclose(in) != Z_OK) error("failed gzclose"); -} - - -/* =========================================================================== - * Compress the given file: create a corresponding .gz file and remove the - * original. - */ -void file_compress(file, mode) - char *file; - char *mode; -{ - local char outfile[MAX_NAME_LEN]; - FILE *in; - gzFile out; - - strcpy(outfile, file); - strcat(outfile, GZ_SUFFIX); - - in = fopen(file, "rb"); - if (in == NULL) { - perror(file); - exit(1); - } - out = gzopen(outfile, mode); - if (out == NULL) { - fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); - exit(1); - } - gz_compress(in, out); - - unlink(file); -} - - -/* =========================================================================== - * Uncompress the given file and remove the original. - */ -void file_uncompress(file) - char *file; -{ - local char buf[MAX_NAME_LEN]; - char *infile, *outfile; - FILE *out; - gzFile in; - uInt len = (uInt)strlen(file); - - strcpy(buf, file); - - if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { - infile = file; - outfile = buf; - outfile[len-3] = '\0'; - } else { - outfile = file; - infile = buf; - strcat(infile, GZ_SUFFIX); - } - in = gzopen(infile, "rb"); - if (in == NULL) { - fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); - exit(1); - } - out = fopen(outfile, "wb"); - if (out == NULL) { - perror(file); - exit(1); - } - - gz_uncompress(in, out); - - unlink(infile); -} - - -/* =========================================================================== - * Usage: minigzip [-d] [-f] [-h] [-r] [-1 to -9] [files...] - * -d : decompress - * -f : compress with Z_FILTERED - * -h : compress with Z_HUFFMAN_ONLY - * -r : compress with Z_RLE - * -1 to -9 : compression level - */ - -int main(argc, argv) - int argc; - char *argv[]; -{ - int uncompr = 0; - gzFile file; - char outmode[20]; - - strcpy(outmode, "wb6 "); - - prog = argv[0]; - argc--, argv++; - - while (argc > 0) { - if (strcmp(*argv, "-d") == 0) - uncompr = 1; - else if (strcmp(*argv, "-f") == 0) - outmode[3] = 'f'; - else if (strcmp(*argv, "-h") == 0) - outmode[3] = 'h'; - else if (strcmp(*argv, "-r") == 0) - outmode[3] = 'R'; - else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' && - (*argv)[2] == 0) - outmode[2] = (*argv)[1]; - else - break; - argc--, argv++; - } - if (outmode[3] == ' ') - outmode[3] = 0; - if (argc == 0) { - SET_BINARY_MODE(stdin); - SET_BINARY_MODE(stdout); - if (uncompr) { - file = gzdopen(fileno(stdin), "rb"); - if (file == NULL) error("can't gzdopen stdin"); - gz_uncompress(file, stdout); - } else { - file = gzdopen(fileno(stdout), outmode); - if (file == NULL) error("can't gzdopen stdout"); - gz_compress(stdin, file); - } - } else { - do { - if (uncompr) { - file_uncompress(*argv); - } else { - file_compress(*argv, outmode); - } - } while (argv++, --argc); - } - return 0; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/trees.c b/components/dfs/filesystems/jffs2/cyg/compress/src/trees.c deleted file mode 100644 index 395e4e1681..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/trees.c +++ /dev/null @@ -1,1219 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2005 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include <ctype.h> -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local void set_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (value << s->bi_valid); - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (val << s->bi_valid);\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1<<extra_lbits[code]); n++) { - _length_code[length++] = (uch)code; - } - } - Assert (length == 256, "tr_static_init: length != 256"); - /* Note that the length 255 (match length 258) can be represented - * in two different ways: code 284 + 5 bits or code 285, so we - * overwrite length_code[255] to use the best encoding: - */ - _length_code[length-1] = (uch)code; - - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<<extra_dbits[code]); n++) { - _dist_code[dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: dist != 256"); - dist >>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include <stdio.h> -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, - "inconsistent bit counts"); - Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); - - for (n = 0; n <= max_code; n++) { - int len = tree[n].Len; - if (len == 0) continue; - /* Now reverse the bits */ - tree[n].Code = bi_reverse(next_code[len]++, len); - - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ", - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1)); - } -} - -/* =========================================================================== - * Construct one Huffman tree and assigns the code bit strings and lengths. - * Update the total bit length for the current block. - * IN assertion: the field freq is set for all tree elements. - * OUT assertions: the fields len and code are set to the optimal bit length - * and corresponding code. The length opt_len is updated; static_len is - * also updated if stree is not null. The field max_code is set. - */ -local void build_tree(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void _tr_stored_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void _tr_flush_block(s, buf, stored_len, eof) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int eof; /* true if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) - set_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, eof); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+eof, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+eof, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (eof) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*eof)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Set the data type to BINARY or TEXT, using a crude approximation: - * set it to Z_TEXT if all symbols are either printable characters (33 to 255) - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local void set_data_type(s) - deflate_state *s; -{ - int n; - - for (n = 0; n < 9; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - if (n == 9) - for (n = 14; n < 32; n++) - if (s->dyn_ltree[n].Freq != 0) - break; - s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/trees.h b/components/dfs/filesystems/jffs2/cyg/compress/src/trees.h deleted file mode 100644 index 72facf900f..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/uncompr.c b/components/dfs/filesystems/jffs2/cyg/compress/src/uncompr.c deleted file mode 100644 index 52040203bc..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/uncompr.c +++ /dev/null @@ -1,65 +0,0 @@ -/* uncompr.c -- decompress a memory buffer - * Copyright (C) 1995-2003 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#define ZLIB_INTERNAL -#ifdef __ECOS__ -#include <cyg/compress/zlib.h> -#else -#include "zlib.h" -#endif // __ECOS__ - -/* =========================================================================== - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted. -*/ -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - - err = inflateInit(&stream); - if (err != Z_OK) return err; - - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; - - err = inflateEnd(&stream); - return err; -} diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/zlib.3 b/components/dfs/filesystems/jffs2/cyg/compress/src/zlib.3 deleted file mode 100644 index 90b8162870..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/zlib.3 +++ /dev/null @@ -1,159 +0,0 @@ -.TH ZLIB 3 "18 July 2005" -.SH NAME -zlib \- compression/decompression library -.SH SYNOPSIS -[see -.I zlib.h -for full description] -.SH DESCRIPTION -The -.I zlib -library is a general purpose data compression library. -The code is thread safe. -It provides in-memory compression and decompression functions, -including integrity checks of the uncompressed data. -This version of the library supports only one compression method (deflation) -but other algorithms will be added later -and will have the same stream interface. -.LP -Compression can be done in a single step if the buffers are large enough -(for example if an input file is mmap'ed), -or can be done by repeated calls of the compression function. -In the latter case, -the application must provide more input and/or consume the output -(providing more output space) before each call. -.LP -The library also supports reading and writing files in -.IR gzip (1) -(.gz) format -with an interface similar to that of stdio. -.LP -The library does not install any signal handler. -The decoder checks the consistency of the compressed data, -so the library should never crash even in case of corrupted input. -.LP -All functions of the compression library are documented in the file -.IR zlib.h . -The distribution source includes examples of use of the library -in the files -.I example.c -and -.IR minigzip.c . -.LP -Changes to this version are documented in the file -.I ChangeLog -that accompanies the source, -and are concerned primarily with bug fixes and portability enhancements. -.LP -A Java implementation of -.I zlib -is available in the Java Development Kit 1.1: -.IP -http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html -.LP -A Perl interface to -.IR zlib , -written by Paul Marquess ([email protected]), -is available at CPAN (Comprehensive Perl Archive Network) sites, -including: -.IP -http://www.cpan.org/modules/by-module/Compress/ -.LP -A Python interface to -.IR zlib , -written by A.M. Kuchling ([email protected]), -is available in Python 1.5 and later versions: -.IP -http://www.python.org/doc/lib/module-zlib.html -.LP -A -.I zlib -binding for -.IR tcl (1), -written by Andreas Kupries ([email protected]), -is availlable at: -.IP -http://www.westend.com/~kupries/doc/trf/man/man.html -.LP -An experimental package to read and write files in .zip format, -written on top of -.I zlib -by Gilles Vollant ([email protected]), -is available at: -.IP -http://www.winimage.com/zLibDll/unzip.html -and also in the -.I contrib/minizip -directory of the main -.I zlib -web site. -.SH "SEE ALSO" -The -.I zlib -web site can be found at either of these locations: -.IP -http://www.zlib.org -.br -http://www.gzip.org/zlib/ -.LP -The data format used by the zlib library is described by RFC -(Request for Comments) 1950 to 1952 in the files: -.IP -http://www.ietf.org/rfc/rfc1950.txt (concerning zlib format) -.br -http://www.ietf.org/rfc/rfc1951.txt (concerning deflate format) -.br -http://www.ietf.org/rfc/rfc1952.txt (concerning gzip format) -.LP -These documents are also available in other formats from: -.IP -ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html -.LP -Mark Nelson ([email protected]) wrote an article about -.I zlib -for the Jan. 1997 issue of Dr. Dobb's Journal; -a copy of the article is available at: -.IP -http://dogma.net/markn/articles/zlibtool/zlibtool.htm -.SH "REPORTING PROBLEMS" -Before reporting a problem, -please check the -.I zlib -web site to verify that you have the latest version of -.IR zlib ; -otherwise, -obtain the latest version and see if the problem still exists. -Please read the -.I zlib -FAQ at: -.IP -http://www.gzip.org/zlib/zlib_faq.html -.LP -before asking for help. -Send questions and/or comments to [email protected], -or (for the Windows DLL version) to Gilles Vollant ([email protected]). -.SH AUTHORS -Version 1.2.3 -Copyright (C) 1995-2005 Jean-loup Gailly ([email protected]) -and Mark Adler ([email protected]). -.LP -This software is provided "as-is," -without any express or implied warranty. -In no event will the authors be held liable for any damages -arising from the use of this software. -See the distribution directory with respect to requirements -governing redistribution. -The deflate format used by -.I zlib -was defined by Phil Katz. -The deflate and -.I zlib -specifications were written by L. Peter Deutsch. -Thanks to all the people who reported problems and suggested various -improvements in -.IR zlib ; -who are too numerous to cite here. -.LP -UNIX manual page by R. P. C. Rodgers, -U.S. National Library of Medicine ([email protected]). -.\" end of man page diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/zutil.c b/components/dfs/filesystems/jffs2/cyg/compress/src/zutil.c deleted file mode 100644 index d55f5948a3..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/zutil.c +++ /dev/null @@ -1,318 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch (sizeof(uInt)) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch (sizeof(uLong)) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch (sizeof(voidpf)) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch (sizeof(z_off_t)) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#ifdef STDC -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int z_verbose = verbose; - -void z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ diff --git a/components/dfs/filesystems/jffs2/cyg/compress/src/zutil.h b/components/dfs/filesystems/jffs2/cyg/compress/src/zutil.h deleted file mode 100644 index 013754a1f7..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/src/zutil.h +++ /dev/null @@ -1,276 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#define ZLIB_INTERNAL -#ifdef __ECOS__ -#include <cyg/compress/zlib.h> -#include <cyg/crc/crc.h> -#undef crc32 -#define crc32 cyg_ether_crc32_accumulate -#else -#include "zlib.h" -#endif // __ECOS__ - -#ifdef STDC -# ifndef _WIN32_WCE -# include <stddef.h> -# endif -# include <string.h> -# include <stdlib.h> -#endif -#ifdef NO_ERRNO_H -# ifdef _WIN32_WCE - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. We rename it to - * avoid conflict with other libraries that use the same workaround. - */ -# define errno z_errno -# endif - extern int errno; -#else -# ifndef _WIN32_WCE -# include <errno.h> -# endif -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include <alloc.h> -# endif -# else /* MSC or DJGPP */ -# include <malloc.h> -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -# ifdef M_I86 - #include <malloc.h> -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include <unix.h> /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# define vsnprintf _vsnprintf -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -#endif -#ifdef VMS -# define NO_vsnprintf -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - extern void zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG -# include <stdio.h> - extern int z_verbose; - extern void z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); -void zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* ZUTIL_H */ diff --git a/components/dfs/filesystems/jffs2/cyg/compress/tests/zlib1.c b/components/dfs/filesystems/jffs2/cyg/compress/tests/zlib1.c deleted file mode 100644 index 22b2d397b5..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/tests/zlib1.c +++ /dev/null @@ -1,232 +0,0 @@ -//================================================================= -// -// zlib1.c -// -// zlib compression/decompression test 1 -// -//========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jskov -// Contributors: jskov -// Date: 2001-03-09 -// Description: Tests zlib compress/decompress functionality. -//####DESCRIPTIONEND#### - - -#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL - -#include <cyg/kernel/kapi.h> - -#include <cyg/infra/testcase.h> -#include <cyg/infra/diag.h> - -#ifdef CYGFUN_KERNEL_API_C - -#include <cyg/compress/zlib.h> -#include <stdlib.h> - -#define NTHREADS 1 -#define STACKSIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL > 8192 ? CYGNUM_HAL_STACK_SIZE_TYPICAL : 8192) - -static cyg_handle_t thread[NTHREADS]; - -static cyg_thread thread_obj[NTHREADS]; -static char stack[NTHREADS][STACKSIZE]; - -static char license_txt[] = -"Red Hat eCos Public License v1.1\n" -"\n" -"\n" -"1. DEFINITIONS\n" -"\n" -"1.1. \"Contributor\" means each entity that creates or\n" -"contributes to the creation of Modifications.\n" -"\n" -"1.2. \"Contributor Version\" means the combination of the\n" -"Original Code, prior Modifications used by a\n" -"Contributor, and the Modifications made by that\n" -"particular Contributor.\n" -"\n" -"1.3. \"Covered Code\" means the Original Code or\n" -"Modifications or the combination of the Original Code\n" -"and Modifications, in each case including portions\n" -"thereof.\n" -"\n" -"1.4. \"Electronic Distribution Mechanism\" means a\n" -"mechanism generally accepted in the software development\n" -"community for the electronic transfer of data.\n" -"\n" -"1.5. \"Executable\" means Covered Code in any form other\n" -"than Source Code.\n" -"1.6. \"Initial Developer\" means the individual or entity\n" -"identified as the Initial Developer in the Source Code\n" -"notice required by Exhibit A.\n" -"\n" -"1.7. \"Larger Work\" means a work which combines Covered\n" -"Code or portions thereof with code not governed by the\n" -"terms of this License.\n" -"\n" -"1.8. \"License\" means this document.\n" -"\n" -"1.9. \"Modifications\" means any addition to or deletion\n" -"from the substance or structure of either the Original\n" -"Code or any previous Modifications. When Covered Code is\n" -"released as a series of files, a Modification is:\n" -"\n" -" A. Any addition to or deletion from the\n" -" contents of a file containing Original Code or\n" -" previous Modifications.\n" -"\n" -" B. Any new file that contains any part of the\n" -" Original Code or previous Modifications.\n" -"\n" -"1.10. \"Original Code\" means Source Code of computer\n" -"software code which is described in the Source Code\n" -"notice required by Exhibit A as Original Code, and\n" -"which, at the time of its release under this License is\n" -"not already Covered Code governed by this License.\n" -"\n" -"1.11. \"Source Code\" means the preferred form of the\n" -"Covered Code for making modifications to it, including\n" -"all modules it contains, plus any associated interface\n" -"definition files, scripts used to control compilation\n" -"and installation of an Executable, or a list of source\n" -"code differential comparisons against either the\n" -"Original Code or another well known, available Covered\n" -"Code of the Contributor's choice. The Source Code can be\n" -"in a compressed or archival form, provided the\n" -"appropriate decompression or de-archiving software is\n" -"widely available for no charge.\n" -"\n" -"1.12. \"You\" means an individual or a legal entity\n" -"exercising rights under, and complying with all of the\n" -"terms of, this License or a future version of this\n" -"License issued under Section 6.1. For legal entities,\n" -"\"You\" includes any entity which controls, is controlled\n" -"by, or is under common control with You. For purposes of\n" -"this definition, \"control\" means (a) the power, direct\n" -"or indirect, to cause the direction or management of\n" -"such entity, whether by contract or otherwise, or (b)\n" -"ownership of fifty percent (50%) or more of the\n" -"outstanding shares or beneficial ownership of such\n" -"entity.\n" -"\n" -"1.13. \"Red Hat Branded Code\" is code that Red Hat\n" -"distributes and/or permits others to distribute under\n" -"different terms than the Red Hat eCos Public License.\n" -"Red Hat's Branded Code may contain part or all of the\n" -"Covered Code.\n"; - -static void entry0( cyg_addrword_t data ) -{ - int i; - unsigned long len; - int err; - int buf_size = sizeof(license_txt)+512; - unsigned char* packed = malloc(buf_size); - unsigned char* unpacked = malloc(buf_size); - - if (NULL == packed || NULL == unpacked) - CYG_TEST_NA("Not enough memory for buffers"); - - CYG_TEST_INFO("Compressing"); - - len = buf_size; - err = compress(packed, &len, license_txt, sizeof(license_txt)); - diag_printf("len = %d", len); - diag_dump_buf(packed, len); - - if (Z_OK != err) - CYG_TEST_NA("Not enough memory for compression"); - - - CYG_TEST_INFO("Decompressing"); - err = uncompress(unpacked, &buf_size, packed, len); - - switch (err) { - case Z_OK: - break; - case Z_MEM_ERROR: - CYG_TEST_NA("Not enough memory for decompression"); - break; - case Z_BUF_ERROR: - CYG_TEST_FAIL_FINISH("Decompressed data larger than original"); - break; - case Z_DATA_ERROR: - CYG_TEST_FAIL_FINISH("Decompression failed"); - break; - default: - CYG_TEST_FAIL_FINISH("Unknown decompression error"); - break; - } - - for (i = 0; i < sizeof(license_txt)-1; i++) { - if (license_txt[i] != unpacked[i]) - CYG_TEST_FAIL_FINISH("Verify failed"); - } - - CYG_TEST_PASS_FINISH("zlib1 OK"); -} - -void zlib1_main( void ) -{ - CYG_TEST_INIT(); - - cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "zlib1", - (void *)stack[0], STACKSIZE,&thread[0], &thread_obj[0]); - cyg_thread_resume(thread[0]); - - cyg_scheduler_start(); - - CYG_TEST_FAIL_FINISH("Not reached"); -} - -externC void -cyg_start( void ) -{ - zlib1_main(); -} - -#else /* def CYGFUN_KERNEL_API_C */ -externC void -cyg_start( void ) -{ - CYG_TEST_INIT(); - CYG_TEST_NA("Kernel C API layer disabled"); -} -#endif /* def CYGFUN_KERNEL_API_C */ - -// EOF zlib1.c diff --git a/components/dfs/filesystems/jffs2/cyg/compress/tests/zlib2.c b/components/dfs/filesystems/jffs2/cyg/compress/tests/zlib2.c deleted file mode 100644 index 11e36e1369..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/tests/zlib2.c +++ /dev/null @@ -1,307 +0,0 @@ -//================================================================= -// -// zlib2.c -// -// zlib decompression test 2 -// -//========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jskov -// Contributors: jskov -// Date: 2001-03-09 -// Description: Tests zlib compression of gz compressed image. -//####DESCRIPTIONEND#### - - -#include <cyg/hal/hal_arch.h> // CYGNUM_HAL_STACK_SIZE_TYPICAL - -#include <cyg/kernel/kapi.h> - -#include <cyg/infra/testcase.h> - -#ifdef CYGFUN_KERNEL_API_C - -#include <cyg/compress/zlib.h> -#include <stdlib.h> - -#define NTHREADS 1 -#define STACKSIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL > 8192 ? CYGNUM_HAL_STACK_SIZE_TYPICAL : 8192) - -static cyg_handle_t thread[NTHREADS]; - -static cyg_thread thread_obj[NTHREADS]; -static char stack[NTHREADS][STACKSIZE]; - - -unsigned char gzip_test[] = { -0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x8d, 0x56, 0xdb, 0x6e, 0xe3, 0x36, -0x10, 0xed, 0x33, 0xbf, 0x82, 0x08, 0x50, 0x74, 0x03, 0xb8, 0xee, 0xa6, 0xed, 0x6e, 0x2f, 0x6f, -0xd9, 0x24, 0x8b, 0x06, 0xd8, 0x4b, 0x91, 0x2c, 0xba, 0xe8, 0x23, 0x4d, 0x8d, 0x6c, 0x22, 0x12, -0xa9, 0x92, 0x94, 0x9d, 0xfc, 0x7d, 0xcf, 0x0c, 0x25, 0x59, 0x72, 0x1a, 0xa0, 0x7e, 0x32, 0x45, -0x72, 0xe6, 0xcc, 0xcc, 0x99, 0x33, 0xbc, 0xa3, 0x4a, 0xff, 0x61, 0xb2, 0xa6, 0xab, 0x90, 0xf4, -0x9f, 0xfd, 0xa6, 0x71, 0x56, 0x7f, 0x70, 0x96, 0x7c, 0x22, 0xbd, 0xbf, 0x58, 0x5f, 0x28, 0xfc, -0x2e, 0xd6, 0xfa, 0xfa, 0xe6, 0xfd, 0xed, 0xa7, 0xdb, 0x2f, 0xb7, 0x9f, 0x3f, 0xdd, 0xf3, 0x1a, -0x5f, 0xce, 0xae, 0x82, 0xcf, 0xd1, 0x6d, 0xfa, 0x1c, 0xe2, 0x99, 0x6e, 0xc9, 0xf8, 0xa4, 0xc9, -0xd8, 0x9d, 0x26, 0x9f, 0x5d, 0x7e, 0xd2, 0x79, 0x07, 0xab, 0x36, 0x92, 0xc9, 0x94, 0x74, 0x88, -0xca, 0x8e, 0xc7, 0xb1, 0xcc, 0x01, 0xdb, 0x54, 0x76, 0x5d, 0xf0, 0x3a, 0xd4, 0xfa, 0x63, 0xa8, -0x5c, 0xed, 0xac, 0xac, 0xd3, 0x9a, 0x7d, 0xfc, 0xb8, 0xf4, 0xa1, 0xff, 0xa2, 0x98, 0xb0, 0x39, -0xfa, 0x12, 0x03, 0xa1, 0xdd, 0x38, 0x3f, 0xd9, 0xc0, 0x27, 0xf5, 0x39, 0xba, 0x2d, 0x3e, 0x35, -0xfa, 0x2a, 0x54, 0xb4, 0xd2, 0x5d, 0x74, 0xb8, 0xba, 0x30, 0xae, 0xfb, 0x84, 0x98, 0x37, 0x4f, -0xda, 0xa8, 0x99, 0xf9, 0x95, 0x36, 0xbe, 0x12, 0xa3, 0xcb, 0xc3, 0xad, 0xa9, 0x88, 0x0f, 0x73, -0x38, 0xaa, 0x33, 0x31, 0x3b, 0xdb, 0x37, 0x26, 0xea, 0xd9, 0x55, 0x41, 0xfb, 0x93, 0xa0, 0xdd, -0x53, 0x84, 0x6d, 0x76, 0x3d, 0x87, 0xb9, 0xc0, 0xc4, 0xb9, 0x58, 0xba, 0x00, 0xc0, 0xff, 0x0e, -0x66, 0x79, 0x51, 0x31, 0xc0, 0xc5, 0xcd, 0x95, 0x76, 0xbe, 0xe4, 0xdc, 0x1a, 0x94, 0xcb, 0x79, -0xdb, 0xf4, 0x95, 0xf3, 0x5b, 0xdd, 0x85, 0x28, 0x07, 0x14, 0x8c, 0x44, 0x0a, 0xb5, 0x20, 0xfc, -0x19, 0x08, 0x6f, 0x1a, 0xb2, 0x39, 0x06, 0x8f, 0x22, 0x5f, 0xbb, 0x54, 0x02, 0x60, 0x7f, 0x1f, -0xc9, 0xee, 0x8c, 0x77, 0xa9, 0x1d, 0x61, 0x1b, 0xd5, 0x8e, 0x9f, 0xf4, 0x96, 0x3c, 0x45, 0xd3, -0x34, 0xc8, 0x98, 0xb5, 0xd4, 0x65, 0x44, 0x08, 0xbf, 0x8c, 0x2f, 0x85, 0x3a, 0x1f, 0x4c, 0x24, -0x5d, 0xd1, 0x9e, 0x9a, 0xd0, 0xb5, 0xa8, 0x3d, 0x0a, 0xdd, 0xb6, 0xbd, 0x67, 0x0a, 0xd4, 0x43, -0x64, 0x74, 0xf4, 0x9a, 0x23, 0xac, 0xd7, 0x14, 0x39, 0xc2, 0xca, 0x64, 0x23, 0xc8, 0xde, 0x30, -0xb2, 0x47, 0xb2, 0x7d, 0x36, 0x9b, 0x66, 0xca, 0xdc, 0x3c, 0x9b, 0xec, 0xd0, 0x78, 0xb1, 0xd8, -0xea, 0xc0, 0x51, 0x21, 0x34, 0xe3, 0xf5, 0x7d, 0xe8, 0xa3, 0x25, 0x39, 0xb2, 0x86, 0xa1, 0xb7, -0x30, 0x74, 0x0b, 0xd7, 0x0e, 0x29, 0xbb, 0x2e, 0x90, 0x28, 0xce, 0x2b, 0xe1, 0x7c, 0xe5, 0xf6, -0xae, 0xea, 0xb1, 0x0f, 0x6c, 0x85, 0xa9, 0xca, 0x55, 0xfc, 0xa7, 0x76, 0xf0, 0x65, 0xca, 0xb1, -0x67, 0x36, 0xc6, 0x80, 0x67, 0xfe, 0x94, 0x0f, 0xe0, 0x02, 0xe9, 0x48, 0xff, 0xf4, 0x2e, 0x16, -0x46, 0xdd, 0x3c, 0xee, 0xdc, 0xc6, 0x65, 0x7d, 0x29, 0x61, 0xfd, 0x02, 0x34, 0x1f, 0x4c, 0xdc, -0xe2, 0xfa, 0xd7, 0x10, 0x1f, 0xa6, 0xd4, 0xea, 0x03, 0x56, 0xfa, 0xb0, 0x73, 0x5c, 0x38, 0x29, -0x3a, 0x4d, 0xd1, 0xaa, 0x81, 0x22, 0x53, 0x09, 0xf5, 0x50, 0x42, 0x7d, 0x70, 0x99, 0x8f, 0x63, -0x17, 0x8e, 0xf5, 0x96, 0x8f, 0xfb, 0xe2, 0x95, 0x69, 0x9f, 0x29, 0xb6, 0xa9, 0xd0, 0xc6, 0xa5, -0xb1, 0x81, 0x05, 0xc5, 0xaf, 0x8c, 0xa2, 0xac, 0x8f, 0x99, 0xc0, 0x99, 0x2a, 0xd8, 0x9e, 0xeb, -0x25, 0x87, 0x7e, 0xc3, 0xa1, 0x05, 0xb5, 0x26, 0xb0, 0x48, 0xba, 0xa9, 0x2a, 0x27, 0x2c, 0x41, -0xdb, 0x02, 0x59, 0x85, 0x72, 0xf2, 0x52, 0xd5, 0x31, 0xb4, 0x85, 0x06, 0xfd, 0x26, 0x65, 0xe3, -0xad, 0x00, 0x07, 0xab, 0x7a, 0x9b, 0x7b, 0x90, 0x02, 0x68, 0xc8, 0x31, 0xfc, 0x05, 0x97, 0xa7, -0x08, 0xd9, 0x74, 0x17, 0x69, 0xef, 0x42, 0x9f, 0x4e, 0xda, 0x5f, 0x7f, 0xdd, 0x91, 0x3f, 0x21, -0x40, 0x52, 0x11, 0x8e, 0x4d, 0x2a, 0x55, 0x32, 0x3a, 0x51, 0x74, 0x24, 0x21, 0xd7, 0xae, 0x21, -0xf4, 0x82, 0x59, 0x18, 0xc1, 0x85, 0xdf, 0x95, 0xd2, 0xfc, 0xbb, 0x5c, 0xeb, 0xcb, 0x97, 0xc3, -0xd0, 0x63, 0x18, 0xe5, 0x30, 0xcb, 0x14, 0xb2, 0x22, 0x86, 0x8d, 0x98, 0x96, 0x4f, 0xc6, 0x79, -0x6e, 0xac, 0x67, 0x9d, 0x2c, 0x77, 0x5e, 0x88, 0x62, 0x70, 0xff, 0xae, 0xb8, 0xf7, 0x74, 0x28, -0xe6, 0x8a, 0x30, 0x16, 0x9b, 0x25, 0xc1, 0x2c, 0x2b, 0xa3, 0x7e, 0xc9, 0x95, 0x53, 0x37, 0x2f, -0x7b, 0x80, 0x14, 0xbf, 0x46, 0xed, 0x16, 0x17, 0xc6, 0xda, 0xcd, 0xc8, 0xca, 0xd6, 0x41, 0xb5, -0x0e, 0xea, 0x1b, 0xd5, 0xd4, 0xb5, 0xc2, 0xa6, 0xc2, 0x43, 0x26, 0x04, 0x25, 0x0b, 0x41, 0x38, -0x76, 0xf7, 0xff, 0x25, 0x3b, 0xd7, 0xe3, 0x44, 0x76, 0x21, 0x55, 0x4a, 0x0c, 0xe3, 0x6f, 0x16, -0x63, 0xd9, 0xb5, 0x82, 0xc2, 0x21, 0xb5, 0x43, 0x21, 0x75, 0xef, 0x2b, 0x21, 0xc7, 0x91, 0xb1, -0x5c, 0x66, 0xa6, 0xb7, 0x69, 0x30, 0x1a, 0xaa, 0xa7, 0x25, 0x05, 0x96, 0x9c, 0x3f, 0xa1, 0xf9, -0x05, 0x8f, 0xa4, 0x19, 0xe2, 0x79, 0xd7, 0x23, 0x7b, 0x90, 0x1c, 0xb6, 0x53, 0xf4, 0xa3, 0x64, -0x7a, 0x61, 0x9b, 0xa5, 0xaa, 0x35, 0x0f, 0x5c, 0xe3, 0x76, 0x21, 0xce, 0x20, 0x8b, 0xcb, 0xab, -0xa3, 0xb6, 0x2a, 0x08, 0x21, 0x1f, 0xe9, 0xc1, 0x39, 0xec, 0x4c, 0x85, 0xc4, 0xa8, 0x69, 0xfa, -0xa1, 0x5f, 0x52, 0x0a, 0xd6, 0x99, 0xa2, 0x93, 0x48, 0x78, 0x6d, 0x2c, 0xa9, 0x8a, 0x6a, 0xe7, -0x0b, 0xff, 0x06, 0xbe, 0x72, 0xb6, 0xbb, 0x3c, 0x8c, 0x23, 0xb8, 0x91, 0x01, 0x19, 0x1a, 0xa9, -0x93, 0x6b, 0xc4, 0xbd, 0x48, 0x3e, 0x8c, 0x67, 0x38, 0x9d, 0x06, 0x03, 0x64, 0xef, 0x28, 0x96, -0x2b, 0xe9, 0x24, 0xdd, 0x40, 0xcc, 0x79, 0x2f, 0x49, 0x02, 0x94, 0x14, 0x16, 0x51, 0x20, 0x6a, -0x96, 0x36, 0x53, 0x8c, 0x9a, 0xe8, 0x12, 0x87, 0x64, 0xb6, 0x0c, 0x38, 0xcf, 0x9a, 0x53, 0x3d, -0x23, 0x9c, 0xf1, 0xa2, 0xb2, 0xfa, 0x40, 0x08, 0xf7, 0xc1, 0x87, 0x83, 0x47, 0x25, 0xf7, 0x06, -0xb8, 0xe0, 0xf4, 0x44, 0xac, 0xca, 0xac, 0x9a, 0x0d, 0xc4, 0xef, 0x92, 0xb6, 0xbb, 0x80, 0xe2, -0xac, 0xf5, 0x97, 0x25, 0x8f, 0x30, 0xa8, 0xbc, 0xde, 0x90, 0x62, 0x39, 0x17, 0x4c, 0x91, 0x12, -0x87, 0xcf, 0x1e, 0xa3, 0xdd, 0xb9, 0x3d, 0x20, 0x70, 0x8d, 0x78, 0x70, 0x07, 0x08, 0x35, 0xc9, -0x48, 0x56, 0xa6, 0xc3, 0x12, 0xa3, 0x1c, 0x39, 0x05, 0x4d, 0xc7, 0x7b, 0x92, 0x0f, 0x6e, 0xe4, -0xef, 0xcb, 0x5d, 0x2e, 0xde, 0xc4, 0x6d, 0x10, 0xe9, 0x80, 0xfb, 0x3c, 0xb4, 0x26, 0xd8, 0x5c, -0x64, 0x8f, 0x44, 0xef, 0x58, 0x94, 0x0b, 0x6b, 0xf8, 0x91, 0xf1, 0x77, 0xe8, 0x8f, 0x72, 0x77, -0x32, 0x22, 0x90, 0x5a, 0xda, 0xe2, 0xef, 0x30, 0x2a, 0xe8, 0x91, 0xa2, 0x75, 0x89, 0x3d, 0x21, -0x63, 0x3b, 0xae, 0x1e, 0x73, 0xb8, 0x3c, 0x1e, 0x18, 0x57, 0xf3, 0xc4, 0x7b, 0xa2, 0xd5, 0x4c, -0x94, 0x81, 0x6a, 0xa3, 0x3a, 0xaf, 0x96, 0x64, 0x17, 0xfb, 0x75, 0x2f, 0x62, 0xb9, 0x2f, 0xaf, -0x9b, 0x51, 0xc2, 0xd5, 0xb1, 0x21, 0x52, 0x8f, 0x2c, 0x94, 0x56, 0xb9, 0xc7, 0x1c, 0xe5, 0x43, -0x6f, 0xf9, 0x01, 0xf6, 0x1e, 0xd7, 0x67, 0xe0, 0x20, 0x86, 0x2b, 0x55, 0x62, 0x29, 0x64, 0xa5, -0xc2, 0xc6, 0xe1, 0x39, 0x36, 0x8e, 0x1b, 0xe1, 0x18, 0xbf, 0x1c, 0xd2, 0xb8, 0x68, 0x50, 0xc8, -0xcd, 0x93, 0x10, 0xc9, 0x0d, 0xf1, 0x70, 0x28, 0x2d, 0xfc, 0x8c, 0x94, 0x94, 0x78, 0x60, 0xba, -0x38, 0xed, 0xfa, 0xd8, 0x85, 0x24, 0xda, 0xab, 0xca, 0x28, 0x99, 0xb8, 0xbd, 0xd2, 0x67, 0xc3, -0x9d, 0x31, 0xa3, 0xaf, 0xcc, 0x79, 0xe9, 0xc1, 0x70, 0xe0, 0x3c, 0x55, 0x50, 0x0f, 0x9b, 0x15, -0xfb, 0xf2, 0xe5, 0xff, 0x4a, 0xb8, 0x6f, 0xd0, 0x05, 0x72, 0xae, 0x7c, 0x1c, 0x4a, 0xdb, 0x1a, -0x6f, 0xb6, 0xc4, 0x53, 0x8a, 0x7d, 0xa5, 0x7e, 0x7a, 0x5d, 0xae, 0x10, 0x0f, 0x09, 0x41, 0xa1, -0x05, 0xe2, 0xd1, 0xd8, 0xcc, 0x37, 0x84, 0xb5, 0x07, 0x97, 0x4a, 0x63, 0xbc, 0xda, 0x9c, 0x2b, -0x50, 0x17, 0xa9, 0xdd, 0xb9, 0xae, 0x8c, 0x8a, 0x1a, 0xb9, 0xc0, 0x40, 0xb7, 0x6c, 0xf3, 0xd5, -0x9b, 0xd7, 0xdf, 0x9e, 0x8b, 0x9f, 0x10, 0x47, 0x1e, 0xab, 0xd0, 0x67, 0x1e, 0x66, 0xf2, 0x8e, -0x4a, 0x60, 0x8a, 0xbc, 0x5e, 0xc1, 0x59, 0x8f, 0x20, 0x2d, 0xb7, 0xd2, 0xc2, 0x20, 0x63, 0x52, -0x05, 0x53, 0x21, 0x14, 0xbf, 0x03, 0xef, 0x86, 0x37, 0xf5, 0x3b, 0x3c, 0x76, 0xaa, 0xe9, 0x3d, -0x28, 0x19, 0xaf, 0x06, 0xfd, 0x1f, 0x8e, 0xa8, 0x6a, 0x7c, 0x85, 0x49, 0xb5, 0xaa, 0x1f, 0x38, -0xbd, 0x20, 0x0b, 0xab, 0xa4, 0x84, 0x22, 0x02, 0x74, 0x3c, 0x54, 0xca, 0xa3, 0xa6, 0xd6, 0xd6, -0x85, 0x59, 0xf2, 0x16, 0xe2, 0xec, 0xdd, 0xbd, 0xfc, 0x9a, 0x5f, 0xab, 0x61, 0x13, 0xdd, 0x39, -0x07, 0x86, 0x24, 0x3f, 0x8d, 0x2a, 0x36, 0x4c, 0xa2, 0x38, 0xe7, 0xee, 0x5c, 0x26, 0xd7, 0xea, -0x9b, 0x7f, 0x01, 0x21, 0xe0, 0xda, 0x98, 0x30, 0x0c, 0x00, 0x00}; - -unsigned char gzip_test_ref[] = -"Red Hat eCos Public License v1.1\n" -"\n" -"\n" -"\n" -"1. DEFINITIONS\n" -"\n" -"1.1. \"Contributor\" means each entity that creates or\n" -"contributes to the creation of Modifications.\n" -"\n" -"1.2. \"Contributor Version\" means the combination of the\n" -"Original Code, prior Modifications used by a\n" -"Contributor, and the Modifications made by that\n" -"particular Contributor.\n" -"\n" -"1.3. \"Covered Code\" means the Original Code or\n" -"Modifications or the combination of the Original Code\n" -"and Modifications, in each case including portions\n" -"thereof.\n" -"\n" -"1.4. \"Electronic Distribution Mechanism\" means a\n" -"mechanism generally accepted in the software development\n" -"community for the electronic transfer of data.\n" -"\n" -"1.5. \"Executable\" means Covered Code in any form other\n" -"than Source Code.\n" -"1.6. \"Initial Developer\" means the individual or entity\n" -"identified as the Initial Developer in the Source Code\n" -"notice required by Exhibit A.\n" -"\n" -"1.7. \"Larger Work\" means a work which combines Covered\n" -"Code or portions thereof with code not governed by the\n" -"terms of this License.\n" -"\n" -"1.8. \"License\" means this document.\n" -"\n" -"1.9. \"Modifications\" means any addition to or deletion\n" -"from the substance or structure of either the Original\n" -"Code or any previous Modifications. When Covered Code is\n" -"released as a series of files, a Modification is:\n" -"\n" -" A. Any addition to or deletion from the\n" -" contents of a file containing Original Code or\n" -" previous Modifications.\n" -"\n" -" B. Any new file that contains any part of the\n" -" Original Code or previous Modifications.\n" -"\n" -"1.10. \"Original Code\" means Source Code of computer\n" -"software code which is described in the Source Code\n" -"notice required by Exhibit A as Original Code, and\n" -"which, at the time of its release under this License is\n" -"not already Covered Code governed by this License.\n" -"\n" -"1.11. \"Source Code\" means the preferred form of the\n" -"Covered Code for making modifications to it, including\n" -"all modules it contains, plus any associated interface\n" -"definition files, scripts used to control compilation\n" -"and installation of an Executable, or a list of source\n" -"code differential comparisons against either the\n" -"Original Code or another well known, available Covered\n" -"Code of the Contributor's choice. The Source Code can be\n" -"in a compressed or archival form, provided the\n" -"appropriate decompression or de-archiving software is\n" -"widely available for no charge.\n" -"\n" -"1.12. \"You\" means an individual or a legal entity\n" -"exercising rights under, and complying with all of the\n" -"terms of, this License or a future version of this\n" -"License issued under Section 6.1. For legal entities,\n" -"\"You\" includes any entity which controls, is controlled\n" -"by, or is under common control with You. For purposes of\n" -"this definition, \"control\" means (a) the power, direct\n" -"or indirect, to cause the direction or management of\n" -"such entity, whether by contract or otherwise, or (b)\n" -"ownership of fifty percent (50%) or more of the\n" -"outstanding shares or beneficial ownership of such\n" -"entity.\n" -"\n" -"1.13. \"Red Hat Branded Code\" is code that Red Hat\n" -"distributes and/or permits others to distribute under\n" -"different terms than the Red Hat eCos Public License.\n" -"Red Hat's Branded Code may contain part or all of the\n" -"Covered Code.\n"; - -static void entry0( cyg_addrword_t data ) -{ - int i; - unsigned long len; - int err; - int buf_size = sizeof(gzip_test_ref)+512; - unsigned char* unpacked = malloc(buf_size); - - if (NULL == unpacked) - CYG_TEST_NA("Not enough memory for buffers"); - - CYG_TEST_INFO("Decompressing"); - len = buf_size; - err = uncompress(unpacked, &len, gzip_test, sizeof(gzip_test)); - - switch (err) { - case Z_OK: - break; - case Z_MEM_ERROR: - CYG_TEST_NA("Not enough memory for decompression"); - break; - case Z_BUF_ERROR: - CYG_TEST_FAIL_FINISH("Decompressed data larger than original"); - break; - case Z_DATA_ERROR: - CYG_TEST_FAIL_FINISH("Decompression failed"); - break; - default: - CYG_TEST_FAIL_FINISH("Unknown decompression error"); - break; - } - - for (i = 0; i < sizeof(gzip_test_ref)-1; i++) { - if (gzip_test_ref[i] != unpacked[i]) - CYG_TEST_FAIL_FINISH("Verify failed"); - } - - CYG_TEST_PASS_FINISH("zlib2 OK"); -} - -void zlib2_main( void ) -{ - CYG_TEST_INIT(); - - cyg_thread_create(4, entry0 , (cyg_addrword_t)0, "zlib1", - (void *)stack[0], STACKSIZE,&thread[0], &thread_obj[0]); - cyg_thread_resume(thread[0]); - - cyg_scheduler_start(); - - CYG_TEST_FAIL_FINISH("Not reached"); -} - -externC void -cyg_start( void ) -{ - zlib2_main(); -} - -#else /* def CYGFUN_KERNEL_API_C */ -externC void -cyg_start( void ) -{ - CYG_TEST_INIT(); - CYG_TEST_NA("Kernel C API layer disabled"); -} -#endif /* def CYGFUN_KERNEL_API_C */ - -// EOF zlib1.c diff --git a/components/dfs/filesystems/jffs2/cyg/compress/zconf.h b/components/dfs/filesystems/jffs2/cyg/compress/zconf.h deleted file mode 100644 index dc360d8ff6..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/zconf.h +++ /dev/null @@ -1,358 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2005 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -// #ifdef __ECOS__ -#undef __ECOS__ -#define __ECOS__ -#include <rtthread.h> - -#ifndef RT_USING_LIBC -#define malloc rt_malloc -#define free rt_free -#define printf rt_kprintf -#endif - -//#define Z_PREFIX //by prife -//#include <pkgconf/compress_zlib.h> //prife no such file. - -#if CYGINT_COMPRESS_ZLIB_LOCAL_ALLOC != 0 -#define MY_ZCALLOC -#endif -#ifdef CYGSEM_COMPRESS_ZLIB_DEFLATE_MAKES_GZIP -#undef MAX_WBITS -#define MAX_WBITS 15+16 /* 32K LZ77 window */ -#else -#define NO_GZIP -#define NO_GZCOMPRESS -#endif -// #endif - -/* - * If you *really* need a unique prefix for all types and library functions, - * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it. - */ -#ifdef Z_PREFIX -# define deflateInit_ z_deflateInit_ -# define deflate z_deflate -# define deflateEnd z_deflateEnd -# define inflateInit_ z_inflateInit_ -# define inflate z_inflate -# define inflateEnd z_inflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateSetDictionary z_deflateSetDictionary -# define deflateCopy z_deflateCopy -# define deflateReset z_deflateReset -# define deflateParams z_deflateParams -# define deflateBound z_deflateBound -# define deflatePrime z_deflatePrime -# define inflateInit2_ z_inflateInit2_ -# define inflateSetDictionary z_inflateSetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateCopy z_inflateCopy -# define inflateReset z_inflateReset -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# define uncompress z_uncompress -# define adler32 z_adler32 -# define crc32 z_crc32 -# define get_crc_table z_get_crc_table -# define zError z_zError - -# define alloc_func z_alloc_func -# define free_func z_free_func -# define in_func z_in_func -# define out_func z_out_func -# define Byte z_Byte -# define uInt z_uInt -# define uLong z_uLong -# define Bytef z_Bytef -# define charf z_charf -# define intf z_intf -# define uIntf z_uIntf -# define uLongf z_uLongf -# define voidpf z_voidpf -# define voidp z_voidp -#endif - -#if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS -#endif -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 -#endif -#if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS -#endif -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif -#endif -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif -#endif - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - */ -#ifdef SYS16BIT -# define MAXSEG_64K -#endif -#ifdef MSDOS -# define UNALIGNED_OK -#endif - -#ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC -#endif -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC -#endif -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC -#endif -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC -#endif - -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC -#endif - -#ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif -#endif - -/* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -/* The following definitions for FAR are needed only for MSDOS mixed - * model programming (small or medium model with some far allocations). - * This was tested only with MSC; for other MSDOS compilers you may have - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model, - * just define FAR to be empty. - */ -#ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif -#endif - -#if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include <windows.h> - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif -#endif - -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif -#endif - -#ifndef ZEXTERN -# define ZEXTERN extern -#endif -#ifndef ZEXPORT -# define ZEXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA -#endif - -#ifndef FAR -# define FAR -#endif - -#if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ -#endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -#ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR -#else - typedef Byte FAR Bytef; -#endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */ -# include <sys/types.h> /* for off_t */ -# include <unistd.h> /* for SEEK_* and off_t */ -# ifdef VMS -# include <unixio.h> /* for off_t */ -# endif -# define z_off_t off_t -#endif -#ifndef SEEK_SET -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif -#ifndef z_off_t -# define z_off_t long -#endif - -#if defined(__OS400__) -# define NO_vsnprintf -#endif - -#if defined(__MVS__) -# define NO_vsnprintf -# ifdef FAR -# undef FAR -# endif -#endif - -/* MVS linker does not support external names larger than 8 bytes */ -#if defined(__MVS__) -# pragma map(deflateInit_,"DEIN") -# pragma map(deflateInit2_,"DEIN2") -# pragma map(deflateEnd,"DEEND") -# pragma map(deflateBound,"DEBND") -# pragma map(inflateInit_,"ININ") -# pragma map(inflateInit2_,"ININ2") -# pragma map(inflateEnd,"INEND") -# pragma map(inflateSync,"INSY") -# pragma map(inflateSetDictionary,"INSEDI") -# pragma map(compressBound,"CMBND") -# pragma map(inflate_table,"INTABL") -# pragma map(inflate_fast,"INFA") -# pragma map(inflate_copyright,"INCOPY") -#endif - -#endif /* ZCONF_H */ diff --git a/components/dfs/filesystems/jffs2/cyg/compress/zlib.h b/components/dfs/filesystems/jffs2/cyg/compress/zlib.h deleted file mode 100644 index 081e7c912f..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/compress/zlib.h +++ /dev/null @@ -1,1358 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.3, July 18th, 2005 - - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.3" -#define ZLIB_VERNUM 0x1230 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms will be added later and will have the same - stream interface. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never - crash even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */ -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative - * values are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. - If zalloc and zfree are set to Z_NULL, deflateInit updates them to - use default allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at - all (the input data is simply copied a block at a time). - Z_DEFAULT_COMPRESSION requests a default compromise between speed and - compression (currently equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if level is not a valid compression level, - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). - msg is set to null if there is no error message. deflateInit does not - perform any compression: this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce some - output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). - Some output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating avail_in or avail_out accordingly; avail_out - should never be zero before the call. The application can consume the - compressed output when it wants, for example when the output buffer is full - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK - and with zero avail_out, it must be called again after making room in the - output buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumualte before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In particular - avail_in is zero after the call if enough output space has been provided - before the call.) Flushing may degrade compression for some compression - algorithms and so it should be used only when necessary. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there - was enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the - stream are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least - the value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect - the compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, - msg may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact - value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller. msg is set to null if there is no error - message. inflateInit does not perform any decompression apart from reading - the zlib header if present: this will be done by inflate(). (So next_in and - avail_in may be modified, but next_out and avail_out are unchanged.) -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there - is no more input data or no more space in the output buffer (see below - about the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). If inflate returns Z_OK and with zero avail_out, it - must be called again after making room in the output buffer because there - might be more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() stop - if and when it gets to the next deflate block boundary. When decoding the - zlib or gzip format, this will cause inflate() to return immediately after - the header and before the first block. When doing a raw inflate, inflate() - will go ahead and process the first block, and will return when it gets to - the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 - if inflate() is currently decoding the last block in the deflate stream, - plus 128 if inflate() returned immediately after decoding an end-of-block - code or decoding the complete header up to just before the first byte of the - deflate stream. The end-of-block will not be indicated until all of the - uncompressed data from that block has been written to strm->next_out. The - number of unused bits may in general be greater than seven, except when - bit 7 of data_type is set, in which case the number of unused bits will be - less than eight. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster approach - may be used for the single inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() will decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically. Any information - contained in the gzip header is not retained, so applications that need that - information should instead use raw inflate, see inflateInit2() below, or - inflateBack() and perform their own processing of the gzip header and - trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may then - call inflateSync() to look for a good compression block if a partial recovery - of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by - the caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), - no header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but - is slow and reduces compression ratio; memLevel=9 uses maximum memory - for optimal speed. The default value is 8. See zconf.h for total memory - usage as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy - parameter only affects the compression ratio but not the correctness of the - compressed output even if it is not set appropriately. Z_FIXED prevents the - use of dynamic Huffman codes, allowing for a simpler decoder for special - applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid - method). msg is set to null if there is no error message. deflateInit2 does - not perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any - call of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size in - deflate or deflate2. Thus the strings most likely to be useful should be - put at the end of the dictionary, not at the front. In addition, the - current implementation of deflate will use at most the window size minus - 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and - can consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. - The stream will keep the same compression level and any other attributes - that may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different - strategy. If the compression level is changed, the input available so far - is compressed with the old level (and may be flushed); the new level will - take effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to - be compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR - if strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() - or deflateInit2(). This would be used to allocate an output buffer - for deflation in a single pass, and so would be called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the - bits leftover from a previous deflate stream when appending to it. As such, - this function can only be used for raw deflate, and must be used before the - first deflate() call after a deflateInit2() or deflateReset(). bits must be - less than or equal to 16, and that many of the least significant bits of - value will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is - a crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg - is set to null if there is no error message. inflateInit2 does not perform - any decompression apart from reading the zlib header if present: this will - be done by inflate(). (So next_in and avail_in may be modified, but next_out - and avail_out are unchanged.) -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (such as NULL dictionary) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been found, - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success - case, the application may save the current current value of total_in which - indicates where valid compressed data was found. In the error case, the - application may repeatedly call inflateSync, providing more input each time, - until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. - The stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being NULL). -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK can be used to - force inflate() to return immediately after header processing is complete - and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When - any of extra, name, or comment are not Z_NULL and the respective field is - not present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not - be allocated, or Z_VERSION_ERROR if the version of the library does not - match the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free - the allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects - only the raw deflate stream to decompress. This is different from the - normal behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format - error in the deflate stream (in which case strm->msg is set to indicate the - nature of the error), or Z_STREAM_ERROR if the stream was not properly - initialized. In the case of Z_BUF_ERROR, an input or output error can be - distinguished using strm->next_in which will be Z_NULL only if in() returned - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to - out() returning non-zero. (in() will always be called before out(), so - strm->next_in is assured to be defined if out() returns non-zero.) Note - that inflateBack() cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the - basic stream-oriented functions. To simplify the interface, some - default options are assumed (compression level and memory usage, - standard memory allocation functions). The source code of these - utility functions can easily be modified if you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be at least the value returned - by compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - This function can be used to compress a whole file at once if the - input file is mmap'ed. - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before - a compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total - size of the destination buffer, which must be large enough to hold the - entire uncompressed data. (The size of the uncompressed data must have - been saved previously by the compressor and transmitted to the decompressor - by some mechanism outside the scope of this compression library.) - Upon exit, destLen is the actual size of the compressed buffer. - This function can be used to decompress a whole file at once if the - input file is mmap'ed. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - -typedef voidp gzFile; - -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); -/* - Opens a gzip (.gz) file for reading or writing. The mode parameter - is as in fopen ("rb" or "wb") but can also include a compression level - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for - Huffman only compression as in "wb1h", or 'R' for run-length encoding - as in "wb1R". (See the description of deflateInit2 for more information - about the strategy parameter.) - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened or if there was - insufficient memory to allocate the (de)compression state; errno - can be checked to distinguish the two cases (if errno is zero, the - zlib error is Z_MEM_ERROR). */ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen() associates a gzFile with the file descriptor fd. File - descriptors are obtained from calls like open, dup, creat, pipe or - fileno (in the file has been previously opened with fopen). - The mode parameter is as in gzopen. - The next call of gzclose on the returned gzFile will also close the - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode). - gzdopen returns NULL if there was insufficient memory to allocate - the (de)compression state. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. - If the input file was not in gzip format, gzread copies the given number - of bytes into the buffer. - gzread returns the number of uncompressed bytes actually read (0 for - end of file, -1 for error). */ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes actually written - (0 in case of error). -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the args to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written (0 in case of error). The number of - uncompressed bytes written is limited to 4095. The caller should assure that - this limit is not exceeded. If it is exceeded, then gzprintf() will return - return an error (0) with nothing written. In this case, there may also be a - buffer overflow with unpredictable consequences, which is possible only if - zlib was compiled with the insecure functions sprintf() or vsprintf() - because the secure snprintf() or vsnprintf() functions were not available. -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or - a newline character is read and transferred to buf, or an end-of-file - condition is encountered. The string is then terminated with a null - character. - gzgets returns buf, or Z_NULL in case of error. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. - gzputc returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte - or -1 in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read again later. - Only one character of push-back is allowed. gzungetc() returns the - character pushed, or -1 on failure. gzungetc() will fail if a - character has been pushed but not read yet, or if c is -1. The pushed - character will be discarded if the stream is repositioned with gzseek() - or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter - flush is as in the deflate() function. The return value is the zlib - error number (see function gzerror below). gzflush returns Z_OK if - the flush parameter is Z_FINISH and all output could be flushed. - gzflush should be called only when strictly necessary because it can - degrade compression. -*/ - -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); -/* - Sets the starting position for the next gzread or gzwrite on the - given compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); -/* - Returns the starting position for the next gzread or gzwrite on the - given compressed file. This position represents a number of bytes in the - uncompressed data stream. - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns 1 when EOF has previously been detected reading the given - input stream, otherwise zero. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns 1 if file is being read directly without decompression, otherwise - zero. -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file - and deallocates all the (de)compression state. The return value is the zlib - error number (see function gzerror below). -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the - given compressed file. errnum is set to zlib error number. If an - error occurred in the file system and not in the compression library, - errnum is set to Z_ERRNO and the application may consult errno - to get the exact error code. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the - compression library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is NULL, this function returns - the required initial value for the checksum. - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -#ifndef __ECOS__ -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); -/* - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is NULL, this function returns the required initial - value for the for the crc. Pre- and post-conditioning (one's complement) is - performed within this function so it shouldn't be done by the application. - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ -#endif // __ECOS__ - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_stream FAR *strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - -/* - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; /* hack for buggy compilers */ -#endif - -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/components/dfs/filesystems/jffs2/cyg/crc/crc.h b/components/dfs/filesystems/jffs2/cyg/crc/crc.h deleted file mode 100644 index 7b7db10e9e..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/crc/crc.h +++ /dev/null @@ -1,105 +0,0 @@ -//========================================================================== -// -// crc.h -// -// Interface for the CRC algorithms. -// -//========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 2002, 2009 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): Andrew Lunn -// Contributors: Andrew Lunn -// Date: 2002-08-06 -// Purpose: -// Description: -// -// This code is part of eCos (tm). -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#ifndef _SERVICES_CRC_CRC_H_ -#define _SERVICES_CRC_CRC_H_ - -#include <cyg/infra/cyg_type.h> - -#ifndef __externC -# ifdef __cplusplus -# define __externC extern "C" -# else -# define __externC extern -# endif -#endif - -// Compute a CRC, using the POSIX 1003 definition - -__externC cyg_uint32 -cyg_posix_crc32(unsigned char *s, int len); - -// Gary S. Brown's 32 bit CRC - -__externC cyg_uint32 -cyg_crc32(unsigned char *s, int len); - -// Gary S. Brown's 32 bit CRC, but accumulate the result from a -// previous CRC calculation - -__externC cyg_uint32 -cyg_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len); - -// Ethernet FCS Algorithm - -__externC cyg_uint32 -cyg_ether_crc32(unsigned char *s, int len); - -// Ethernet FCS algorithm, but accumulate the result from a previous -// CRC calculation. - -__externC cyg_uint32 -cyg_ether_crc32_accumulate(cyg_uint32 crc, unsigned char *s, int len); - -// 16 bit CRC with polynomial x^16+x^12+x^5+1 - -__externC cyg_uint16 -cyg_crc16(unsigned char *s, int len); - -__externC cyg_uint16 -cyg_crc16_accumulate(cyg_uint16 crc, unsigned char *s, int len); - -#endif // _SERVICES_CRC_CRC_H_ - - - diff --git a/components/dfs/filesystems/jffs2/cyg/crc/crc16.c b/components/dfs/filesystems/jffs2/cyg/crc/crc16.c deleted file mode 100644 index 7d6fa38105..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/crc/crc16.c +++ /dev/null @@ -1,104 +0,0 @@ -//========================================================================== -// -// crc16.c -// -// 16 bit CRC with polynomial x^16+x^12+x^5+1 -// -//========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas,asl -// Date: 2001-01-31 -// Purpose: -// Description: -// -// This code is part of eCos (tm). -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include <cyg/crc/crc.h> - -// Table of CRC constants - implements x^16+x^12+x^5+1 -static const cyg_uint16 crc16_tab[] = { - 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, - 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, - 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, - 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, - 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, - 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, - 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, - 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, - 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, - 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, - 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, - 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, - 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, - 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, - 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, - 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, - 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, - 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, - 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, - 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, - 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, - 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, - 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, - 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, - 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, - 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, - 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, - 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, - 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, - 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, - 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, - 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, -}; - -cyg_uint16 -cyg_crc16(unsigned char *buf, int len) -{ - int i; - cyg_uint16 cksum; - - cksum = 0; - for (i = 0; i < len; i++) { - cksum = crc16_tab[((cksum>>8) ^ *buf++) & 0xFF] ^ (cksum << 8); - } - return cksum; -} - diff --git a/components/dfs/filesystems/jffs2/cyg/crc/crc32.c b/components/dfs/filesystems/jffs2/cyg/crc/crc32.c deleted file mode 100644 index 7e4ea269f2..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/crc/crc32.c +++ /dev/null @@ -1,166 +0,0 @@ -//========================================================================== -// -// crc32.c -// -// Gary S. Brown's 32 bit CRC -// -//========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas,asl -// Date: 2001-01-31 -// Purpose: -// Description: -// -// This code is part of eCos (tm). -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include <cyg/crc/crc.h> - - /* ====================================================================== */ - /* COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or */ - /* code or tables extracted from it, as desired without restriction. */ - /* */ - /* First, the polynomial itself and its table of feedback terms. The */ - /* polynomial is */ - /* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ - /* */ - /* ====================================================================== */ - -static const cyg_uint32 crc32_tab[] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL - }; - -/* This is the standard Gary S. Brown's 32 bit CRC algorithm, but - accumulate the CRC into the result of a previous CRC. */ -cyg_uint32 -cyg_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len) -{ - int i; - - for (i = 0; i < len; i++) { - crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); - } - return crc32val; -} - -/* This is the standard Gary S. Brown's 32 bit CRC algorithm */ -cyg_uint32 -cyg_crc32(unsigned char *s, int len) -{ - return (cyg_crc32_accumulate(0,s,len)); -} - -/* Return a 32-bit CRC of the contents of the buffer accumulating the - result from a previous CRC calculation. This uses the Ethernet FCS - algorithm.*/ -cyg_uint32 -cyg_ether_crc32_accumulate(cyg_uint32 crc32val, unsigned char *s, int len) -{ - int i; - - if (s == 0) return 0L; - - crc32val = crc32val ^ 0xffffffff; - for (i = 0; i < len; i++) { - crc32val = crc32_tab[(crc32val ^ s[i]) & 0xff] ^ (crc32val >> 8); - } - return crc32val ^ 0xffffffff; -} - -/* Return a 32-bit CRC of the contents of the buffer, using the - Ethernet FCS algorithm. */ -cyg_uint32 -cyg_ether_crc32(unsigned char *s, int len) -{ - return cyg_ether_crc32_accumulate(0,s,len); -} - - diff --git a/components/dfs/filesystems/jffs2/cyg/crc/posix_crc.c b/components/dfs/filesystems/jffs2/cyg/crc/posix_crc.c deleted file mode 100644 index 0da50e9a40..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/crc/posix_crc.c +++ /dev/null @@ -1,116 +0,0 @@ -//========================================================================== -// -// posix_crc.c -// -// POSIX CRC calculation -// -//========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): gthomas -// Contributors: gthomas,asl -// Date: 2001-01-31 -// Purpose: -// Description: -// -// This code is part of eCos (tm). -// -//####DESCRIPTIONEND#### -// -//========================================================================== - -#include <cyg/crc/crc.h> - -// Compute a CRC, using the POSIX 1003 definition - -// Same basic algorithm as CRC-16, but the bits are defined in the -// opposite order. This computation matches the output of the -// Linux 'cksum' program. - -static const cyg_uint32 posix_crc32_tab[] = { - 0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005, - 0x2608EDB8, 0x22C9F00F, 0x2F8AD6D6, 0x2B4BCB61, 0x350C9B64, 0x31CD86D3, 0x3C8EA00A, 0x384FBDBD, - 0x4C11DB70, 0x48D0C6C7, 0x4593E01E, 0x4152FDA9, 0x5F15ADAC, 0x5BD4B01B, 0x569796C2, 0x52568B75, - 0x6A1936C8, 0x6ED82B7F, 0x639B0DA6, 0x675A1011, 0x791D4014, 0x7DDC5DA3, 0x709F7B7A, 0x745E66CD, - 0x9823B6E0, 0x9CE2AB57, 0x91A18D8E, 0x95609039, 0x8B27C03C, 0x8FE6DD8B, 0x82A5FB52, 0x8664E6E5, - 0xBE2B5B58, 0xBAEA46EF, 0xB7A96036, 0xB3687D81, 0xAD2F2D84, 0xA9EE3033, 0xA4AD16EA, 0xA06C0B5D, - 0xD4326D90, 0xD0F37027, 0xDDB056FE, 0xD9714B49, 0xC7361B4C, 0xC3F706FB, 0xCEB42022, 0xCA753D95, - 0xF23A8028, 0xF6FB9D9F, 0xFBB8BB46, 0xFF79A6F1, 0xE13EF6F4, 0xE5FFEB43, 0xE8BCCD9A, 0xEC7DD02D, - 0x34867077, 0x30476DC0, 0x3D044B19, 0x39C556AE, 0x278206AB, 0x23431B1C, 0x2E003DC5, 0x2AC12072, - 0x128E9DCF, 0x164F8078, 0x1B0CA6A1, 0x1FCDBB16, 0x018AEB13, 0x054BF6A4, 0x0808D07D, 0x0CC9CDCA, - 0x7897AB07, 0x7C56B6B0, 0x71159069, 0x75D48DDE, 0x6B93DDDB, 0x6F52C06C, 0x6211E6B5, 0x66D0FB02, - 0x5E9F46BF, 0x5A5E5B08, 0x571D7DD1, 0x53DC6066, 0x4D9B3063, 0x495A2DD4, 0x44190B0D, 0x40D816BA, - 0xACA5C697, 0xA864DB20, 0xA527FDF9, 0xA1E6E04E, 0xBFA1B04B, 0xBB60ADFC, 0xB6238B25, 0xB2E29692, - 0x8AAD2B2F, 0x8E6C3698, 0x832F1041, 0x87EE0DF6, 0x99A95DF3, 0x9D684044, 0x902B669D, 0x94EA7B2A, - 0xE0B41DE7, 0xE4750050, 0xE9362689, 0xEDF73B3E, 0xF3B06B3B, 0xF771768C, 0xFA325055, 0xFEF34DE2, - 0xC6BCF05F, 0xC27DEDE8, 0xCF3ECB31, 0xCBFFD686, 0xD5B88683, 0xD1799B34, 0xDC3ABDED, 0xD8FBA05A, - 0x690CE0EE, 0x6DCDFD59, 0x608EDB80, 0x644FC637, 0x7A089632, 0x7EC98B85, 0x738AAD5C, 0x774BB0EB, - 0x4F040D56, 0x4BC510E1, 0x46863638, 0x42472B8F, 0x5C007B8A, 0x58C1663D, 0x558240E4, 0x51435D53, - 0x251D3B9E, 0x21DC2629, 0x2C9F00F0, 0x285E1D47, 0x36194D42, 0x32D850F5, 0x3F9B762C, 0x3B5A6B9B, - 0x0315D626, 0x07D4CB91, 0x0A97ED48, 0x0E56F0FF, 0x1011A0FA, 0x14D0BD4D, 0x19939B94, 0x1D528623, - 0xF12F560E, 0xF5EE4BB9, 0xF8AD6D60, 0xFC6C70D7, 0xE22B20D2, 0xE6EA3D65, 0xEBA91BBC, 0xEF68060B, - 0xD727BBB6, 0xD3E6A601, 0xDEA580D8, 0xDA649D6F, 0xC423CD6A, 0xC0E2D0DD, 0xCDA1F604, 0xC960EBB3, - 0xBD3E8D7E, 0xB9FF90C9, 0xB4BCB610, 0xB07DABA7, 0xAE3AFBA2, 0xAAFBE615, 0xA7B8C0CC, 0xA379DD7B, - 0x9B3660C6, 0x9FF77D71, 0x92B45BA8, 0x9675461F, 0x8832161A, 0x8CF30BAD, 0x81B02D74, 0x857130C3, - 0x5D8A9099, 0x594B8D2E, 0x5408ABF7, 0x50C9B640, 0x4E8EE645, 0x4A4FFBF2, 0x470CDD2B, 0x43CDC09C, - 0x7B827D21, 0x7F436096, 0x7200464F, 0x76C15BF8, 0x68860BFD, 0x6C47164A, 0x61043093, 0x65C52D24, - 0x119B4BE9, 0x155A565E, 0x18197087, 0x1CD86D30, 0x029F3D35, 0x065E2082, 0x0B1D065B, 0x0FDC1BEC, - 0x3793A651, 0x3352BBE6, 0x3E119D3F, 0x3AD08088, 0x2497D08D, 0x2056CD3A, 0x2D15EBE3, 0x29D4F654, - 0xC5A92679, 0xC1683BCE, 0xCC2B1D17, 0xC8EA00A0, 0xD6AD50A5, 0xD26C4D12, 0xDF2F6BCB, 0xDBEE767C, - 0xE3A1CBC1, 0xE760D676, 0xEA23F0AF, 0xEEE2ED18, 0xF0A5BD1D, 0xF464A0AA, 0xF9278673, 0xFDE69BC4, - 0x89B8FD09, 0x8D79E0BE, 0x803AC667, 0x84FBDBD0, 0x9ABC8BD5, 0x9E7D9662, 0x933EB0BB, 0x97FFAD0C, - 0xAFB010B1, 0xAB710D06, 0xA6322BDF, 0xA2F33668, 0xBCB4666D, 0xB8757BDA, 0xB5365D03, 0xB1F740B4 - }; - -cyg_uint32 -cyg_posix_crc32(unsigned char *s, int len) -{ - int i; - cyg_uint32 crc32val; - unsigned long length; - - crc32val = 0; - for (i = 0; i < len; i++) { - crc32val = (crc32val << 8) ^ posix_crc32_tab[((crc32val >> 24) ^ *s++) & 0xFF]; - } - length = len; - while (length > 0) { - crc32val = (crc32val << 8) ^ posix_crc32_tab[((crc32val >> 24) ^ length) & 0xFF]; - length >>= 8; - } - crc32val = ~crc32val; - return crc32val; -} - diff --git a/components/dfs/filesystems/jffs2/cyg/fileio/fileio.h b/components/dfs/filesystems/jffs2/cyg/fileio/fileio.h deleted file mode 100644 index d364ae3b45..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/fileio/fileio.h +++ /dev/null @@ -1,489 +0,0 @@ -#ifndef CYGONCE_FILEIO_H -#define CYGONCE_FILEIO_H -//============================================================================= -// -// fileio.h -// -// Fileio header -// -//============================================================================= -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//============================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): nickg -// Contributors: nickg -// Date: 2000-05-25 -// Purpose: Fileio header -// Description: This header contains the external definitions of the general file -// IO subsystem for POSIX and EL/IX compatability. -// -// Usage: -// #include <fileio.h> -// ... -// -// -//####DESCRIPTIONEND#### -// -//============================================================================= - -//#include <pkgconf/hal.h> -//#include <pkgconf/io_fileio.h> - -//#include <cyg/infra/cyg_type.h> -//#include <cyg/hal/hal_tables.h> -#ifdef CYGFUN_IO_FILEIO_SELECT -#include <cyg/kernel/kapi.h> -#endif - -#include <stddef.h> // NULL, size_t -#include <limits.h> -#if defined(__GNUC__) && !defined(__CC_ARM) -#include <sys/types.h> -#include <fcntl.h> -#else -#include <port/sys/types.h> -#include <port/fcntl.h> -#endif -//#include "os_sys_stat.h"//#include <sys/stat.h> - -//============================================================================= -// forward definitions - -struct cyg_mtab_entry; -typedef struct cyg_mtab_entry cyg_mtab_entry; - -struct cyg_fstab_entry; -typedef struct cyg_fstab_entry cyg_fstab_entry; - -struct CYG_FILEOPS_TAG; -typedef struct CYG_FILEOPS_TAG cyg_fileops; - -struct CYG_FILE_TAG; -typedef struct CYG_FILE_TAG cyg_file; - -struct CYG_IOVEC_TAG; -typedef struct CYG_IOVEC_TAG cyg_iovec; - -struct CYG_UIO_TAG; -typedef struct CYG_UIO_TAG cyg_uio; - -struct CYG_SELINFO_TAG; -typedef struct CYG_SELINFO_TAG cyg_selinfo; - -//============================================================================= -// Directory pointer - -typedef CYG_ADDRWORD cyg_dir; - -#define CYG_DIR_NULL 0 - -//============================================================================= -// Filesystem table entry - -typedef int cyg_fsop_mount ( cyg_fstab_entry *fste, cyg_mtab_entry *mte ); -typedef int cyg_fsop_umount ( cyg_mtab_entry *mte ); -typedef int cyg_fsop_open ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, - int mode, cyg_file *fte ); -typedef int cyg_fsop_unlink ( cyg_mtab_entry *mte, cyg_dir dir, const char *name ); -typedef int cyg_fsop_mkdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name ); -typedef int cyg_fsop_rmdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name ); -typedef int cyg_fsop_rename ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1, - cyg_dir dir2, const char *name2 ); -typedef int cyg_fsop_link ( cyg_mtab_entry *mte, cyg_dir dir1, const char *name1, - cyg_dir dir2, const char *name2, int type ); -typedef int cyg_fsop_opendir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, - cyg_file *fte ); -typedef int cyg_fsop_chdir ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, - cyg_dir *dir_out ); -typedef int cyg_fsop_stat ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, - struct stat *buf); -typedef int cyg_fsop_getinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, - int key, void *buf, int len ); -typedef int cyg_fsop_setinfo ( cyg_mtab_entry *mte, cyg_dir dir, const char *name, - int key, void *buf, int len ); - - -struct cyg_fstab_entry -{ - const char *name; // filesystem name - CYG_ADDRWORD data; // private data value -//#ifdef CYGOPT_FS_JFFS2_GCTHREAD -// struct rt_mutex syncmode; // synchronization mode -//#endif - cyg_uint32 syncmode; // synchronization mode - cyg_fsop_mount *mount; - cyg_fsop_umount *umount; - cyg_fsop_open *open; - cyg_fsop_unlink *unlink; - cyg_fsop_mkdir *mkdir; - cyg_fsop_rmdir *rmdir; - cyg_fsop_rename *rename; - cyg_fsop_link *link; - cyg_fsop_opendir *opendir; - cyg_fsop_chdir *chdir; - cyg_fsop_stat *stat; - cyg_fsop_getinfo *getinfo; - cyg_fsop_setinfo *setinfo; -} ;// CYG_HAL_TABLE_TYPE; //prife - -//----------------------------------------------------------------------------- -// Keys for getinfo() and setinfo() - -#define FS_INFO_CONF 1 /* pathconf() */ -#define FS_INFO_ACCESS 2 /* access() */ -#define FS_INFO_GETCWD 3 /* getcwd() */ -#define FS_INFO_SYNC 4 /* cyg_fs_fssync() */ -#define FS_INFO_ATTRIB 5 /* cyg_fs_(get|set)_attrib() */ -#ifdef CYGSEM_FILEIO_INFO_DISK_USAGE -#define FS_INFO_DISK_USAGE 6 /* get_disk_usage() */ -#endif -#define FS_INFO_CHMOD 7 /* chmod() */ - -//----------------------------------------------------------------------------- -// Types for link() - -#define CYG_FSLINK_HARD 1 /* form a hard link */ -#define CYG_FSLINK_SOFT 2 /* form a soft link */ - -//----------------------------------------------------------------------------- -// getinfo() and setinfo() buffers structures. - -struct cyg_getcwd_info -{ - char *buf; /* buffer for cwd string */ - size_t size; /* size of buffer */ -}; - -struct cyg_fs_disk_usage{ - cyg_uint64 total_blocks; - cyg_uint64 free_blocks; - cyg_uint32 block_size; -}; - -typedef cyg_uint32 cyg_fs_attrib_t; - -//----------------------------------------------------------------------------- -// Macro to define an initialized fstab entry - -#define FSTAB_ENTRY( _l, _name, _data, _syncmode, _mount, _umount, \ - _open, _unlink, _mkdir, _rmdir, _rename, _link, \ - _opendir, _chdir, _stat, _getinfo, _setinfo) \ -struct cyg_fstab_entry _l /*CYG_HAL_TABLE_ENTRY(fstab) prife*/ = \ -{ \ - _name, \ - _data, \ - _syncmode, \ - _mount, \ - _umount, \ - _open, \ - _unlink, \ - _mkdir, \ - _rmdir, \ - _rename, \ - _link, \ - _opendir, \ - _chdir, \ - _stat, \ - _getinfo, \ - _setinfo \ -}; - -//============================================================================= -// Mount table entry - -struct cyg_mtab_entry -{ - const char *name; // name of mount point - const char *fsname; // name of implementing filesystem - const char *devname; // name of hardware device - CYG_ADDRWORD data; // private data value - - // The following are filled in after a successful mount operation - cyg_bool valid; // Valid entry? - cyg_fstab_entry *fs; // pointer to fstab entry - cyg_dir root; // root directory pointer -} ; // CYG_HAL_TABLE_TYPE; // prife - - -// This macro defines an initialized mtab entry - -#define MTAB_ENTRY( _l, _name, _fsname, _devname, _data ) \ -struct cyg_mtab_entry _l /*CYG_HAL_TABLE_ENTRY(mtab) prife */ = \ -{ \ - _name, \ - _fsname, \ - _devname, \ - _data, \ - false, \ - NULL, \ - CYG_DIR_NULL \ -}; - -//============================================================================= -// IO vector descriptors - -struct CYG_IOVEC_TAG -{ - void *iov_base; /* Base address. */ - ssize_t iov_len; /* Length. */ -}; - -enum cyg_uio_rw { UIO_READ, UIO_WRITE }; - -/* Segment flag values. */ -enum cyg_uio_seg -{ - UIO_USERSPACE, /* from user data space */ - UIO_SYSSPACE /* from system space */ -}; - -struct CYG_UIO_TAG -{ - struct CYG_IOVEC_TAG *uio_iov; /* pointer to array of iovecs */ - int uio_iovcnt; /* number of iovecs in array */ - off_t uio_offset; /* offset into file this uio corresponds to */ - ssize_t uio_resid; /* residual i/o count */ - enum cyg_uio_seg uio_segflg; /* see above */ - enum cyg_uio_rw uio_rw; /* see above */ -}; - -// Limits -#define UIO_SMALLIOV 8 /* 8 on stack, else malloc */ - -//============================================================================= -// Description of open file - -typedef int cyg_fileop_readwrite (struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio); -typedef cyg_fileop_readwrite cyg_fileop_read; -typedef cyg_fileop_readwrite cyg_fileop_write; -typedef int cyg_fileop_lseek (struct CYG_FILE_TAG *fp, off_t *pos, int whence ); -typedef int cyg_fileop_ioctl (struct CYG_FILE_TAG *fp, CYG_ADDRWORD com, - CYG_ADDRWORD data); -typedef cyg_bool cyg_fileop_select (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info); -typedef int cyg_fileop_fsync (struct CYG_FILE_TAG *fp, int mode ); -typedef int cyg_fileop_close (struct CYG_FILE_TAG *fp); -typedef int cyg_fileop_fstat (struct CYG_FILE_TAG *fp, struct stat *buf ); -typedef int cyg_fileop_getinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len ); -typedef int cyg_fileop_setinfo (struct CYG_FILE_TAG *fp, int key, void *buf, int len ); - -struct CYG_FILEOPS_TAG -{ - cyg_fileop_read *fo_read; - cyg_fileop_write *fo_write; - cyg_fileop_lseek *fo_lseek; - cyg_fileop_ioctl *fo_ioctl; - cyg_fileop_select *fo_select; - cyg_fileop_fsync *fo_fsync; - cyg_fileop_close *fo_close; - cyg_fileop_fstat *fo_fstat; - cyg_fileop_getinfo *fo_getinfo; - cyg_fileop_setinfo *fo_setinfo; -}; - -struct CYG_FILE_TAG -{ - cyg_uint32 f_flag; /* file state */ - cyg_uint16 f_ucount; /* use count */ - cyg_uint16 f_type; /* descriptor type */ - cyg_uint32 f_syncmode; /* synchronization protocol */ - struct CYG_FILEOPS_TAG *f_ops; /* file operations */ - off_t f_offset; /* current offset */ - CYG_ADDRWORD f_data; /* file or socket */ - CYG_ADDRWORD f_xops; /* extra type specific ops */ - cyg_mtab_entry *f_mte; /* mount table entry */ -}; - -//----------------------------------------------------------------------------- -// File flags - -// Allocation here is that bits 0..15 are copies of bits from the open -// flags, bits 16..23 are extra bits that are visible to filesystems but -// are not derived from the open call, and bits 24..31 are reserved for -// the fileio infrastructure. -#define CYG_FREAD O_RDONLY -#define CYG_FWRITE O_WRONLY -#define CYG_FNONBLOCK O_NONBLOCK -#define CYG_FAPPEND O_APPEND -#define CYG_FASYNC 0x00010000 -#define CYG_FDIR 0x00020000 - -#define CYG_FLOCKED 0x01000000 // Set if file is locked -#define CYG_FLOCK 0x02000000 // Lock during file ops -#define CYG_FALLOC 0x80000000 // File is "busy", i.e. allocated - -// Mask for open mode bits stored in file object -#define CYG_FILE_MODE_MASK (CYG_FREAD|CYG_FWRITE|CYG_FNONBLOCK|CYG_FAPPEND) - -//----------------------------------------------------------------------------- -// Type of file - -#define CYG_FILE_TYPE_FILE 1 /* file */ -#define CYG_FILE_TYPE_SOCKET 2 /* communications endpoint */ -#define CYG_FILE_TYPE_DEVICE 3 /* device */ - -//----------------------------------------------------------------------------- -// Keys for getinfo() and setinfo() - -#define FILE_INFO_CONF 1 /* fpathconf() */ - -//----------------------------------------------------------------------------- -// Modes for fsync() - -#define CYG_FSYNC 1 -#define CYG_FDATASYNC 2 - -//----------------------------------------------------------------------------- -// Get/set info buffer structures - -// This is used for pathconf() and fpathconf() -struct cyg_pathconf_info -{ - int name; // POSIX defined variable name - long value; // Returned variable value -}; - -//============================================================================= -// Synchronization modes -// These values are filled into the syncmode fields of the above structures -// and define the synchronization protocol used when accessing the object in -// question. - -#define CYG_SYNCMODE_NONE (0) // no locking required - -#define CYG_SYNCMODE_FILE_FILESYSTEM 0x0002 // lock fs during file ops -#define CYG_SYNCMODE_FILE_MOUNTPOINT 0x0004 // lock mte during file ops -#define CYG_SYNCMODE_IO_FILE 0x0010 // lock file during io ops -#define CYG_SYNCMODE_IO_FILESYSTEM 0x0020 // lock fs during io ops -#define CYG_SYNCMODE_IO_MOUNTPOINT 0x0040 // lock mte during io ops -#define CYG_SYNCMODE_SOCK_FILE 0x0100 // lock socket during socket ops -#define CYG_SYNCMODE_SOCK_NETSTACK 0x0800 // lock netstack during socket ops - -#define CYG_SYNCMODE_IO_SHIFT (4) // shift for IO to file bits -#define CYG_SYNCMODE_SOCK_SHIFT (8) // shift for sock to file bits - -//============================================================================= -// Mount and umount functions - -__externC int mount( const char *devname, - const char *dir, - const char *fsname); - -__externC int umount( const char *name); - -//============================================================================= -// Get/Set info functions - -__externC int cyg_fs_getinfo( const char *path, int key, void *buf, int len ); -__externC int cyg_fs_setinfo( const char *path, int key, void *buf, int len ); -__externC int cyg_fs_fgetinfo( int fd, int key, void *buf, int len ); -__externC int cyg_fs_fsetinfo( int fd, int key, void *buf, int len ); - -#ifdef CYGFUN_IO_FILEIO_SELECT -//============================================================================= -// Select support - -//----------------------------------------------------------------------------- -// Data structure for embedding in client data structures. A pointer to this -// must be passed to cyg_selrecord() and cyg_selwakeup(). - -struct CYG_SELINFO_TAG -{ - CYG_ADDRWORD si_info; // info passed through from fo_select() - cyg_flag_value_t si_waitFlag; // select wait flags -}; - -//----------------------------------------------------------------------------- -// Select support functions. - -// cyg_selinit() is used to initialize a selinfo structure. -__externC void cyg_selinit( struct CYG_SELINFO_TAG *sip ); - -// cyg_selrecord() is called when a client device needs to register -// the current thread for selection. -__externC void cyg_selrecord( CYG_ADDRWORD info, struct CYG_SELINFO_TAG *sip ); - -// cyg_selwakeup() is called when the client device matches the select -// criterion, and needs to wake up a selector. -__externC void cyg_selwakeup( struct CYG_SELINFO_TAG *sip ); -#endif -//============================================================================= -// Timestamp support - -// Provides the current time as a time_t timestamp for use in filesystem -// data strucures. - -__externC time_t jffs2_get_timestamp(void); - -//============================================================================= -// Miscellaneous functions. - -// Provide a function to synchronize an individual file system. (ie write -// file and directory information to disk) -__externC int cyg_fs_fssync(const char *path); - -// Functions to set and get attributes of a file, eg FAT attributes -// like hidden and system. -__externC int cyg_fs_set_attrib( const char *fname, - const cyg_fs_attrib_t new_attrib ); -__externC int cyg_fs_get_attrib( const char *fname, - cyg_fs_attrib_t * const file_attrib ); - -// Functions to lock and unlock a filesystem. These are normally used -// internally by the fileio layer, but the file system might need to -// use them when it needs to lock itself, eg when performing garbage -// collect. -__externC void cyg_fs_lock( cyg_mtab_entry *mte, cyg_uint32 syncmode ); - -__externC void cyg_fs_unlock( cyg_mtab_entry *mte, cyg_uint32 syncmode ); - -// To be able to lock the filesystem you need the mte. This function -// allows the table of mounted filesystems to be searched to find an -// mte which uses the give filesystem root. - -__externC cyg_mtab_entry * cyg_fs_root_lookup( cyg_dir *root ); - -//============================================================================= -// Default functions. -// Cast to the appropriate type, these functions can be put into any of -// the operation table slots to provide the defined error code. - -__externC int cyg_fileio_enosys(void); -__externC int cyg_fileio_erofs(void); -__externC int cyg_fileio_enoerr(void); -__externC int cyg_fileio_enotdir(void); -__externC cyg_fileop_select cyg_fileio_seltrue; - -//----------------------------------------------------------------------------- -#endif // ifndef CYGONCE_FILEIO_H -// End of fileio.h diff --git a/components/dfs/filesystems/jffs2/cyg/hal/basetype.h b/components/dfs/filesystems/jffs2/cyg/hal/basetype.h deleted file mode 100644 index 6f3455c0df..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/hal/basetype.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef CYGONCE_HAL_BASETYPE_H -#define CYGONCE_HAL_BASETYPE_H - -//============================================================================= -// -// basetype.h -// -// Standard types for this architecture. -// -//============================================================================= -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//============================================================================= -//#####DESCRIPTIONBEGIN#### -// -// Author(s): nickg, gthomas -// Contributors: nickg, gthomas -// Date: 1998-09-11 -// Purpose: Define architecture base types. -// Usage: Included by "cyg_type.h", do not use directly - -// -//####DESCRIPTIONEND#### -// - -//----------------------------------------------------------------------------- -// Characterize the architecture - -#ifdef __ARMEB__ -# define CYG_BYTEORDER CYG_MSBFIRST // Big endian -#else -# define CYG_BYTEORDER CYG_LSBFIRST // Little endian -#endif - -#if defined(__ARMEL__) && defined(__VFP_FP__) -# define CYG_DOUBLE_BYTEORDER CYG_LSBFIRST -#else -# define CYG_DOUBLE_BYTEORDER CYG_MSBFIRST // Big? endian -#endif - -//----------------------------------------------------------------------------- -// ARM does not usually use labels with underscores. - -#define CYG_LABEL_NAME(_name_) _name_ -#define CYG_LABEL_DEFN(_name_) _name_ - -//----------------------------------------------------------------------------- -// Override the alignment definitions from cyg_type.h. ARM only allows 4 -// byte alignment whereas the default is 8 byte. - -#define CYGARC_ALIGNMENT 4 -#define CYGARC_P2ALIGNMENT 2 - -//----------------------------------------------------------------------------- -// Define the standard variable sizes - -// The ARM architecture uses the default definitions of the base types, -// so we do not need to define any here. - -//----------------------------------------------------------------------------- -#endif // CYGONCE_HAL_BASETYPE_H -// End of basetype.h diff --git a/components/dfs/filesystems/jffs2/cyg/hal/drv_api.h b/components/dfs/filesystems/jffs2/cyg/hal/drv_api.h deleted file mode 100644 index de4346673c..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/hal/drv_api.h +++ /dev/null @@ -1,250 +0,0 @@ -#ifndef CYGONCE_HAL_DRV_API_H -#define CYGONCE_HAL_DRV_API_H - -/*========================================================================== -// -// drv_api.h -// -// Native API for Kernel -// -//========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): nickg -// Date: 1999-02-24 -// Purpose: Driver API -// Description: This file defines the API used by device drivers to access -// system services. When the kernel is present it maps directly -// to the Kernel C API. When the kernel is absent, it is provided -// by a set of HAL functions. -// -// Usage: #include <cyg/kernel/kapi.h> -// -//####DESCRIPTIONEND#### -// -//========================================================================*/ - -//#include <pkgconf/hal.h> //mod by prife -#include <cyg/infra/cyg_type.h> - -#ifdef CYGPKG_KERNEL - -/*------------------------------------------------------------------------*/ -/* Kernel co-resident version of API */ - -#include <pkgconf/kernel.h> - -#ifndef CYGFUN_KERNEL_API_C -#error Driver API requres Kernel API to be present -#endif - -#include <cyg/kernel/kapi.h> - -#define cyg_drv_isr_lock cyg_interrupt_disable -#define cyg_drv_isr_unlock cyg_interrupt_enable - -#define cyg_drv_dsr_lock cyg_scheduler_lock -#define cyg_drv_dsr_unlock cyg_scheduler_unlock - -#define cyg_drv_mutex_t cyg_mutex_t -#define cyg_drv_mutex_init cyg_mutex_init -#define cyg_drv_mutex_destroy cyg_mutex_destroy -#define cyg_drv_mutex_lock cyg_mutex_lock -#define cyg_drv_mutex_trylock cyg_mutex_trylock -#define cyg_drv_mutex_unlock cyg_mutex_unlock -#define cyg_drv_mutex_release cyg_mutex_release - -#define cyg_drv_cond_t cyg_cond_t -#define cyg_drv_cond_init cyg_cond_init -#define cyg_drv_cond_destroy cyg_cond_destroy -#define cyg_drv_cond_wait cyg_cond_wait -#define cyg_drv_cond_signal cyg_cond_signal -#define cyg_drv_cond_broadcast cyg_cond_broadcast - -#define cyg_drv_interrupt_create cyg_interrupt_create -#define cyg_drv_interrupt_delete cyg_interrupt_delete -#define cyg_drv_interrupt_attach cyg_interrupt_attach -#define cyg_drv_interrupt_detach cyg_interrupt_detach -#define cyg_drv_interrupt_mask cyg_interrupt_mask -#define cyg_drv_interrupt_unmask cyg_interrupt_unmask -#define cyg_drv_interrupt_mask_intunsafe cyg_interrupt_mask_intunsafe -#define cyg_drv_interrupt_unmask_intunsafe cyg_interrupt_unmask_intunsafe -#define cyg_drv_interrupt_acknowledge cyg_interrupt_acknowledge -#define cyg_drv_interrupt_configure cyg_interrupt_configure -#define cyg_drv_interrupt_level cyg_interrupt_level -#define cyg_drv_interrupt_set_cpu cyg_interrupt_set_cpu -#define cyg_drv_interrupt_get_cpu cyg_interrupt_get_cpu - -#define cyg_drv_spinlock_t cyg_spinlock_t -#define cyg_drv_spinlock_init cyg_spinlock_init -#define cyg_drv_spinlock_spin cyg_spinlock_spin -#define cyg_drv_spinlock_clear cyg_spinlock_clear -#define cyg_drv_spinlock_try cyg_spinlock_try -#define cyg_drv_spinlock_test cyg_spinlock_test -#define cyg_drv_spinlock_spin_intsave cyg_spinlock_spin_intsave -#define cyg_drv_spinlock_clear_intsave cyg_spinlock_clear_intsave - -#else /* CYGPKG_KERNEL */ - -/*------------------------------------------------------------------------*/ -/* Non-kernel version of API */ - -typedef CYG_ADDRWORD cyg_addrword_t; /* May hold pointer or word */ -typedef cyg_addrword_t cyg_handle_t; /* Object handle */ -typedef cyg_uint32 cyg_priority_t; /* type for priorities */ -typedef cyg_uint32 cyg_vector_t; /* Interrupt vector id */ -typedef cyg_uint32 cyg_cpu_t; /* CPU id */ -typedef int cyg_bool_t; -typedef cyg_int32 cyg_code_t; /* type for various codes */ - -typedef cyg_uint32 cyg_ISR_t( cyg_vector_t vector, cyg_addrword_t data); -typedef void cyg_DSR_t(cyg_vector_t vector, - cyg_ucount32 count, - cyg_addrword_t data); - - -externC void cyg_drv_isr_lock(void); -externC void cyg_drv_isr_unlock(void); - -externC void cyg_drv_dsr_lock(void); -externC void cyg_drv_dsr_unlock(void); - -typedef struct -{ - cyg_atomic lock; -} cyg_drv_mutex_t; - -externC void cyg_drv_mutex_init( cyg_drv_mutex_t *mutex ); -externC void cyg_drv_mutex_destroy( cyg_drv_mutex_t *mutex ); -externC cyg_bool_t cyg_drv_mutex_lock( cyg_drv_mutex_t *mutex ); -externC cyg_bool_t cyg_drv_mutex_trylock( cyg_drv_mutex_t *mutex ); -externC void cyg_drv_mutex_unlock( cyg_drv_mutex_t *mutex ); -externC void cyg_drv_mutex_release( cyg_drv_mutex_t *mutex ); - -typedef struct -{ - cyg_atomic wait; - cyg_drv_mutex_t *mutex; -} cyg_drv_cond_t; - -externC void cyg_drv_cond_init( cyg_drv_cond_t *cond, cyg_drv_mutex_t *mutex ); -externC void cyg_drv_cond_destroy( cyg_drv_cond_t *cond ); -externC cyg_bool_t cyg_drv_cond_wait( cyg_drv_cond_t *cond ); -externC void cyg_drv_cond_signal( cyg_drv_cond_t *cond ); -externC void cyg_drv_cond_broadcast( cyg_drv_cond_t *cond ); - -typedef struct cyg_interrupt -{ - cyg_vector_t vector; - cyg_priority_t priority; - cyg_ISR_t *isr; - cyg_DSR_t *dsr; - CYG_ADDRWORD data; - - struct cyg_interrupt* volatile next_dsr; - volatile cyg_int32 dsr_count; - -#ifdef CYGIMP_HAL_COMMON_INTERRUPTS_CHAIN - struct cyg_interrupt *next; -#endif - -} cyg_interrupt; - -externC void cyg_drv_interrupt_create( - cyg_vector_t vector, - cyg_priority_t priority, - cyg_addrword_t data, - cyg_ISR_t *isr, - cyg_DSR_t *dsr, - cyg_handle_t *handle, - cyg_interrupt *intr - ); -externC void cyg_drv_interrupt_delete( cyg_handle_t interrupt ); -externC void cyg_drv_interrupt_attach( cyg_handle_t interrupt ); -externC void cyg_drv_interrupt_detach( cyg_handle_t interrupt ); - -externC void cyg_drv_interrupt_mask( cyg_vector_t vector ); -externC void cyg_drv_interrupt_mask_intunsafe( cyg_vector_t vector ); -externC void cyg_drv_interrupt_unmask( cyg_vector_t vector ); -externC void cyg_drv_interrupt_unmask_intunsafe( cyg_vector_t vector ); -externC void cyg_drv_interrupt_acknowledge( cyg_vector_t vector ); -externC void cyg_drv_interrupt_configure( - cyg_vector_t vector, - cyg_bool_t level, - cyg_bool_t up - ); -externC void cyg_drv_interrupt_level( cyg_vector_t vector, cyg_priority_t level ); -externC void cyg_drv_interrupt_set_cpu( cyg_vector_t vector, cyg_cpu_t cpu ); -externC cyg_cpu_t cyg_drv_interrupt_get_cpu( cyg_vector_t vector ); - - -enum cyg_ISR_results -{ - CYG_ISR_HANDLED = 1, /* Interrupt was handled */ - CYG_ISR_CALL_DSR = 2 /* Schedule DSR */ -}; - - -typedef struct -{ - cyg_atomic lock; -} cyg_drv_spinlock_t; - -void cyg_drv_spinlock_init( - cyg_drv_spinlock_t *lock, /* spinlock to initialize */ - cyg_bool_t locked /* init locked or unlocked */ -); - -void cyg_drv_spinlock_destroy( cyg_drv_spinlock_t *lock ); - -void cyg_drv_spinlock_spin( cyg_drv_spinlock_t *lock ); - -void cyg_drv_spinlock_clear( cyg_drv_spinlock_t *lock ); - -cyg_bool_t cyg_drv_spinlock_try( cyg_drv_spinlock_t *lock ); - -cyg_bool_t cyg_drv_spinlock_test( cyg_drv_spinlock_t *lock ); - -void cyg_drv_spinlock_spin_intsave( cyg_drv_spinlock_t *lock, - cyg_addrword_t *istate ); - -void cyg_drv_spinlock_clear_intsave( cyg_drv_spinlock_t *lock, - cyg_addrword_t istate ); - -#endif /* CYGPKG_KERNEL */ - -/*------------------------------------------------------------------------*/ -/* EOF drv_api.h */ -#endif // CYGONCE_HAL_DRV_API_H diff --git a/components/dfs/filesystems/jffs2/cyg/infra/cyg_type.h b/components/dfs/filesystems/jffs2/cyg/infra/cyg_type.h deleted file mode 100644 index 01b60c5099..0000000000 --- a/components/dfs/filesystems/jffs2/cyg/infra/cyg_type.h +++ /dev/null @@ -1,544 +0,0 @@ -#ifndef CYGONCE_INFRA_CYG_TYPE_H -#define CYGONCE_INFRA_CYG_TYPE_H - -//========================================================================== -// -// cyg_type.h -// -// Standard types, and some useful coding macros. -// -//========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2009 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): nickg from an original by hmt -// Contributors: nickg -// Date: 1997-09-08 -// Purpose: share unambiguously sized types. -// Description: we typedef [cyg_][u]int8,16,32 &c for general use. -// Usage: #include "cyg/infra/cyg_type.h" -// ... -// cyg_int32 my_32bit_integer; -// -//####DESCRIPTIONEND#### -// - -#include <stddef.h> // Definition of NULL from the compiler - -// ------------------------------------------------------------------------- -// Some useful macros. These are defined here by default. - -// __externC is used in mixed C/C++ headers to force C linkage on an external -// definition. It avoids having to put all sorts of ifdefs in. - -#ifdef __cplusplus -# define __externC extern "C" -#else -# define __externC extern -#endif -// Also define externC for now - but it is deprecated -#define externC __externC - -// Compiler version. -#ifdef __GNUC__ -# if defined(__GNU_PATCHLEVEL__) -# define __GNUC_VERSION__ (__GNUC__ * 10000 \ - + __GNUC_MINOR__ * 100 \ - + __GNUC_PATCHLEVEL__) -# else -# define __GNUC_VERSION__ (__GNUC__ * 10000 \ - + __GNUC_MINOR__ * 100) -# endif -#endif - -// ------------------------------------------------------------------------- -// The header <basetype.h> defines the base types used here. It is -// supplied either by the target architecture HAL, or by the host -// porting kit. They are all defined as macros, and only those that -// make choices other than the defaults given below need be defined. - -#define CYG_LSBFIRST 1234 -#define CYG_MSBFIRST 4321 - -#include <cyg/hal/basetype.h> - -#if (CYG_BYTEORDER != CYG_LSBFIRST) && (CYG_BYTEORDER != CYG_MSBFIRST) -# error You must define CYG_BYTEORDER to equal CYG_LSBFIRST or CYG_MSBFIRST -#endif - -#ifndef CYG_DOUBLE_BYTEORDER -#define CYG_DOUBLE_BYTEORDER CYG_BYTEORDER -#endif - -#ifndef cyg_halint8 -# define cyg_halint8 char -#endif -#ifndef cyg_halint16 -# define cyg_halint16 short -#endif -#ifndef cyg_halint32 -# define cyg_halint32 int -#endif -#ifndef cyg_halint64 -# define cyg_halint64 long long -#endif - -#ifndef cyg_halcount8 -# define cyg_halcount8 int -#endif -#ifndef cyg_halcount16 -# define cyg_halcount16 int -#endif -#ifndef cyg_halcount32 -# define cyg_halcount32 int -#endif -#ifndef cyg_halcount64 -# define cyg_halcount64 long long -#endif - -#ifndef cyg_haladdress -# define cyg_haladdress cyg_uint32 -#endif -#ifndef cyg_haladdrword -# define cyg_haladdrword cyg_uint32 -#endif - -#ifndef cyg_halbool -# define cyg_halbool int -#endif - -#ifndef cyg_halatomic -# define cyg_halatomic cyg_halint8 -#endif - -// ------------------------------------------------------------------------- -// Provide a default architecture alignment -// This may be overridden in basetype.h if necessary. -// These should be straightforward numbers to allow use in assembly. - -#ifndef CYGARC_ALIGNMENT -# define CYGARC_ALIGNMENT 8 -#endif -// And corresponding power of two alignment -#ifndef CYGARC_P2ALIGNMENT -# define CYGARC_P2ALIGNMENT 3 -#endif -#if (CYGARC_ALIGNMENT) != (1 << CYGARC_P2ALIGNMENT) -# error "Inconsistent CYGARC_ALIGNMENT and CYGARC_P2ALIGNMENT values" -#endif - -// ------------------------------------------------------------------------- -// The obvious few that compilers may define for you. -// But in case they don't: - -#ifndef NULL -# define NULL 0 -#endif - -#ifndef __cplusplus - -typedef cyg_halbool bool; - -# ifndef false -# define false 0 -# endif - -# ifndef true -# define true (!false) -# endif - -#endif - -// ------------------------------------------------------------------------- -// Allow creation of procedure-like macros that are a single statement, -// and must be followed by a semi-colon - -#define CYG_MACRO_START do { -#define CYG_MACRO_END } while (0) - -#define CYG_EMPTY_STATEMENT CYG_MACRO_START CYG_MACRO_END - -#define CYG_UNUSED_PARAM( _type_, _name_ ) CYG_MACRO_START \ - _type_ __tmp1 = (_name_); \ - _type_ __tmp2 = __tmp1; \ - __tmp1 = __tmp2; \ -CYG_MACRO_END - - -//---------------------------------------------------------------------------- -// The unused attribute stops the compiler warning about the variable -// not being used. -// The used attribute prevents the compiler from optimizing it away. - -#define CYG_REFERENCE_OBJECT(__object__) \ - CYG_MACRO_START \ - static const void* __cygvar_discard_me__ \ - __attribute__ ((unused, used)) = (const void*)&(__object__); \ - CYG_MACRO_END - -// ------------------------------------------------------------------------- -// Define basic types for using integers in memory and structures; -// depends on compiler defaults and CPU type. - -typedef unsigned cyg_halint8 cyg_uint8 ; -typedef signed cyg_halint8 cyg_int8 ; - -typedef unsigned cyg_halint16 cyg_uint16 ; -typedef signed cyg_halint16 cyg_int16 ; - -typedef unsigned cyg_halint32 cyg_uint32 ; -typedef signed cyg_halint32 cyg_int32 ; - -typedef unsigned cyg_halint64 cyg_uint64 ; -typedef signed cyg_halint64 cyg_int64 ; - -typedef cyg_halbool cyg_bool ; - -// ------------------------------------------------------------------------- -// Define types for using integers in registers for looping and the like; -// depends on CPU type, choose what it is most comfortable with, with at -// least the range required. - -typedef unsigned cyg_halcount8 cyg_ucount8 ; -typedef signed cyg_halcount8 cyg_count8 ; - -typedef unsigned cyg_halcount16 cyg_ucount16 ; -typedef signed cyg_halcount16 cyg_count16 ; - -typedef unsigned cyg_halcount32 cyg_ucount32 ; -typedef signed cyg_halcount32 cyg_count32 ; - -typedef unsigned cyg_halcount64 cyg_ucount64 ; -typedef signed cyg_halcount64 cyg_count64 ; - -// ------------------------------------------------------------------------- -// Define a type to be used for atomic accesses. This type is guaranteed -// to be read or written in a single uninterruptible operation. This type -// is at least a single byte. - -typedef volatile unsigned cyg_halatomic cyg_atomic; -typedef volatile unsigned cyg_halatomic CYG_ATOMIC; - -// ------------------------------------------------------------------------- -// Define types for access plain, on-the-metal memory or devices. - -typedef cyg_uint32 CYG_WORD; -typedef cyg_uint8 CYG_BYTE; -typedef cyg_uint16 CYG_WORD16; -typedef cyg_uint32 CYG_WORD32; -typedef cyg_uint64 CYG_WORD64; - -typedef cyg_haladdress CYG_ADDRESS; -typedef cyg_haladdrword CYG_ADDRWORD; - -// ------------------------------------------------------------------------- -// Number of elements in a (statically allocated) array. - -#define CYG_NELEM(a) (sizeof(a) / sizeof((a)[0])) - -// ------------------------------------------------------------------------- -// Constructor ordering macros. These are added as annotations to all -// static objects to order the constuctors appropriately. - -#if defined(__cplusplus) && defined(__GNUC__) && \ - !defined(CYGBLD_ATTRIB_INIT_PRI) -# define CYGBLD_ATTRIB_INIT_PRI( _pri_ ) __attribute__((init_priority(_pri_))) -#elif !defined(CYGBLD_ATTRIB_INIT_PRI) -// FIXME: should maybe just bomb out if this is attempted anywhere else? -// Not sure -# define CYGBLD_ATTRIB_INIT_PRI( _pri_ ) -#endif - -// The following will be removed eventually as it doesn't allow the use of -// e.g. pri+5 format -#define CYG_INIT_PRIORITY( _pri_ ) CYGBLD_ATTRIB_INIT_PRI( CYG_INIT_##_pri_ ) - -#define CYGBLD_ATTRIB_INIT_BEFORE( _pri_ ) CYGBLD_ATTRIB_INIT_PRI(_pri_-100) -#define CYGBLD_ATTRIB_INIT_AFTER( _pri_ ) CYGBLD_ATTRIB_INIT_PRI(_pri_+100) - -#if defined(__GNUC__) && !defined(__cplusplus) && (__GNUC_VERSION__ >= 40300) -// Equivalents of the above for C functions, available from gcc 4.3 onwards. -# define CYGBLD_ATTRIB_C_INIT_PRI( _pri_) __attribute__((constructor (_pri_))) -# define CYGBLD_ATTRIB_C_INIT_BEFORE( _pri_ ) __attribute__((constructor (_pri_-100))) -# define CYGBLD_ATTRIB_C_INIT_AFTER( _pri_ ) __attribute__((constructor (_pri_+100))) -#endif - -// Start with initializing everything inside the cpu and the main memory. -#define CYG_INIT_HAL 10000 -#define CYG_INIT_SCHEDULER 11000 -#define CYG_INIT_IDLE_THREAD 11100 -#define CYG_INIT_INTERRUPTS 12000 -#define CYG_INIT_CLOCK 14000 -#define CYG_INIT_THREADS 16000 -#define CYG_INIT_KERNEL 19000 -#define CYG_INIT_MEMALLOC 20000 -// Now move on to I/O subsystems and device drivers. These can make use of -// kernel and HAL functionality, and can dynamically allocate memory if -// absolutely needed. For now they can also assume that diag_printf() -// functionality is available, but that may change in future. -// -// Primary buses are ones very closely tied to the processor, e.g. PCI. -#define CYG_INIT_BUS_PRIMARY 30000 -// Not yet: on some targets cyg_pci_init() has to be called very early -// on for HAL diagnostics to work. -// #define CYG_INIT_BUS_PCI CYG_INIT_BUS_PRIMARY -// -// Secondary buses may hang off primary buses, e.g. USB host. -#define CYG_INIT_BUS_SECONDARY 31000 -// Tertiary buses are everything else. -#define CYG_INIT_BUS_TERTIARY 32000 -#define CYG_INIT_BUS_I2C CYG_INIT_BUS_TERTIARY -#define CYG_INIT_BUS_SPI CYG_INIT_BUS_TERTIARY -// -// In future HAL diag initialization may happen at this point. -// -// Watchdogs and wallclocks often hang off a tertiary bus but -// have no dependencies -#define CYG_INIT_DEV_WATCHDOG 35000 -#define CYG_INIT_DEV_WALLCLOCK 36000 -// A primary block configuration can be initialized with no need -// for per-unit configuration information. -#define CYG_INIT_DEV_BLOCK_PRIMARY 37000 -#define CYG_INIT_DEV_FLASH CYG_INIT_DEV_BLOCK_PRIMARY -// Per-unit configuration data extracted from primary storage. -// NOTE: for future use, not implemented yet. -#define CYG_INIT_CONFIG 38000 -// Secondary block devices may use per-unit configuration data -// for e.g. interpreting partition layout. Few devices are expected -// to fall into this category. Note that these devices, as well as -// some char devices, may not actually be usable until interrupts -// are enabled. -#define CYG_INIT_DEV_BLOCK_SECONDARY 40000 -// Char devices are everything else: serial, ethernet, CAN, ... -#define CYG_INIT_DEV_CHAR 41000 -// For backwards compatibility. Subject to change in future so -// a CYG_INIT_DEV_ priority should be used instead. -#define CYG_INIT_DRIVERS 48000 -// CYG_INIT_IO and CYG_INIT_IO_FS are poorly defined at present, -// and may get reorganized in future. -#define CYG_INIT_IO 49000 -#define CYG_INIT_IO_FS 50000 -// The I/O subsystems and device drivers have been initialized. -#define CYG_INIT_LIBC 56000 -#define CYG_INIT_COMPAT 58000 -#define CYG_INIT_APPLICATION 60000 -#define CYG_INIT_PREDEFAULT 65534 -#define CYG_INIT_DEFAULT 65535 - -// ------------------------------------------------------------------------- -// Label name macros. Some toolsets generate labels with initial -// underscores and others don't. CYG_LABEL_NAME should be used on -// labels in C/C++ code that are defined in assembly code or linker -// scripts. CYG_LABEL_DEFN is for use in assembly code and linker -// scripts where we need to manufacture labels that can be used from -// C/C++. -// These are default implementations that should work for most targets. -// They may be overridden in basetype.h if necessary. - -#ifndef CYG_LABEL_NAME - -#define CYG_LABEL_NAME(_name_) _name_ - -#endif - -#ifndef CYG_LABEL_DEFN - -#define CYG_LABEL_DEFN(_label) _label - -#endif - -// ------------------------------------------------------------------------- -// COMPILER-SPECIFIC STUFF - -#ifdef __GNUC__ -// Force a 'C' routine to be called like a 'C++' contructor -# if !defined(CYGBLD_ATTRIB_CONSTRUCTOR) -# define CYGBLD_ATTRIB_CONSTRUCTOR __attribute__((constructor)) -# endif - -// Define a compiler-specific rune for saying a function doesn't return -# if !defined(CYGBLD_ATTRIB_NORET) -# define CYGBLD_ATTRIB_NORET __attribute__((noreturn)) -# endif - -// How to define weak symbols - this is only relevant for ELF and a.out, -// but that won't be a problem for eCos -# if !defined(CYGBLD_ATTRIB_WEAK) -# define CYGBLD_ATTRIB_WEAK __attribute__ ((weak)) -# endif - -// How to define alias to symbols. Just pass in the symbol itself, not -// the string name of the symbol -# if !defined(CYGBLD_ATTRIB_ALIAS) -# define CYGBLD_ATTRIB_ALIAS(__symbol__) \ - __attribute__ ((alias (#__symbol__))) -# endif - -// This effectively does the reverse of the previous macro. It defines -// a name that the attributed variable or function will actually have -// in assembler. -# if !defined(CYGBLD_ATTRIB_ASM_ALIAS) -# define __Str(x) #x -# define __Xstr(x) __Str(x) -# define CYGBLD_ATTRIB_ASM_ALIAS(__symbol__) \ - __asm__ ( __Xstr( CYG_LABEL_DEFN( __symbol__ ) ) ) -# endif - -// Shows that a function returns the same value when given the same args, but -// note this can't be used if there are pointer args -# if !defined(CYGBLD_ATTRIB_CONST) -# define CYGBLD_ATTRIB_CONST __attribute__((const)) -#endif - -// Assign a defined variable to a specific section -# if !defined(CYGBLD_ATTRIB_SECTION) -# define CYGBLD_ATTRIB_SECTION(__sect__) __attribute__((section (__sect__))) -# endif - -// Give a type or object explicit minimum alignment -# if !defined(CYGBLD_ATTRIB_ALIGN) -# define CYGBLD_ATTRIB_ALIGN(__align__) __attribute__((aligned(__align__))) -# endif - -# if !defined(CYGBLD_ATTRIB_ALIGN_MAX) -# define CYGBLD_ATTRIB_ALIGN_MAX __attribute__((aligned)) -# endif - -# if !defined(CYGBLD_ATTRIB_ALIGNOFTYPE) -# define CYGBLD_ATTRIB_ALIGNOFTYPE( _type_ ) \ - __attribute__((aligned(__alignof__( _type_ )))) -# endif - -// Teach compiler how to check format of printf-like functions -# define CYGBLD_ATTRIB_PRINTF_FORMAT(__format__, __args__) \ - __attribute__((format (printf, __format__, __args__))) - -// Teach compiler how to check format of scanf-like functions -# define CYGBLD_ATTRIB_SCANF_FORMAT(__format__, __args__) \ - __attribute__((format (scanf, __format__, __args__))) - -// Teach compiler how to check format of strftime-like functions -# define CYGBLD_ATTRIB_STRFTIME_FORMAT(__format__, __args__) \ - __attribute__((format (strftime, __format__, __args__))) - -// Tell the compiler not to throw away a variable or function. Only known -// available on 3.3.2 or above. Old version's didn't throw them away, -// but using the unused attribute should stop warnings. -# if !defined(CYGBLD_ATTRIB_USED) -# if __GNUC_VERSION__ >= 30302 -# define CYGBLD_ATTRIB_USED __attribute__((used)) -# else -# define CYGBLD_ATTRIB_USED __attribute__((unused)) -# endif -# endif -#else // non-GNU - -# define CYGBLD_ATTRIB_CONSTRUCTOR - -# define CYGBLD_ATTRIB_NORET - // This intentionally gives an error only if we actually try to - // use it. #error would give an error if we simply can't. -// FIXME: Had to disarm the bomb - the CYGBLD_ATTRIB_WEAK macro is now -// (indirectly) used in host tools. -# define CYGBLD_ATTRIB_WEAK /* !!!-- Attribute weak not defined --!!! */ - -# define CYGBLD_ATTRIB_ALIAS(__x__) !!!-- Attribute alias not defined --!!! - -# define CYGBLD_ATTRIB_ASM_ALIAS(__symbol__) !!!-- Asm alias not defined --!!! - -# define CYGBLD_ATTRIB_CONST - -# define CYGBLD_ATTRIB_ALIGN(__align__) !!!-- Alignment alias not defined --!!! - -# define CYGBLD_ATTRIB_ALIGN_MAX !!!-- Alignment alias not defined --!!! - -# define CYGBLD_ATTRIB_ALIGNOFTYPE( _type_ ) !!!-- Alignment alias not defined --!!! - -# define CYGBLD_ATTRIB_PRINTF_FORMAT(__format__, __args__) - -# define CYGBLD_ATTRIB_SCANF_FORMAT(__format__, __args__) - -# define CYGBLD_ATTRIB_STRFTIME_FORMAT(__format__, __args__) - - -#endif - -// How to define weak aliases. Currently this is simply a mixture of the -// above - -# define CYGBLD_ATTRIB_WEAK_ALIAS(__symbol__) \ - CYGBLD_ATTRIB_WEAK CYGBLD_ATTRIB_ALIAS(__symbol__) - -#ifdef __cplusplus -# define __THROW throw() -#else -# define __THROW -#endif - -// ------------------------------------------------------------------------- -// Variable annotations -// These annotations may be added to various static variables in the -// HAL and kernel to indicate which component they belong to. These -// are used by some targets to optimize memory placement of these -// variables. - -#ifndef CYGBLD_ANNOTATE_VARIABLE_HAL -#define CYGBLD_ANNOTATE_VARIABLE_HAL -#endif -#ifndef CYGBLD_ANNOTATE_VARIABLE_SCHED -#define CYGBLD_ANNOTATE_VARIABLE_SCHED -#endif -#ifndef CYGBLD_ANNOTATE_VARIABLE_CLOCK -#define CYGBLD_ANNOTATE_VARIABLE_CLOCK -#endif -#ifndef CYGBLD_ANNOTATE_VARIABLE_INTR -#define CYGBLD_ANNOTATE_VARIABLE_INTR -#endif - -// ------------------------------------------------------------------------- -// Various "flavours" of memory regions that can be described by the -// Memory Layout Tool (MLT). - -#define CYGMEM_REGION_ATTR_R 0x01 // Region can be read -#define CYGMEM_REGION_ATTR_W 0x02 // Region can be written - -#if defined (__GNUC__) -#elif defined (MSVC) -#define __inline__ __inline -#define inline __inline -#else -#endif -// ------------------------------------------------------------------------- -#endif // CYGONCE_INFRA_CYG_TYPE_H multiple inclusion protection -// EOF cyg_type.h diff --git a/components/dfs/filesystems/jffs2/dfs_jffs2.c b/components/dfs/filesystems/jffs2/dfs_jffs2.c deleted file mode 100644 index c082c21d73..0000000000 --- a/components/dfs/filesystems/jffs2/dfs_jffs2.c +++ /dev/null @@ -1,687 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-1-7 prife the first version - */ - -#include <rtthread.h> -#include <rtdevice.h> - -#include "cyg/infra/cyg_type.h" -#include "cyg/fileio/fileio.h" -#include "port/codes.h" -#include "port/fcntl.h" -#undef mode_t - -#include <dfs_fs.h> -#include <dfs_file.h> - -#include "dfs_jffs2.h" -#include "jffs2_config.h" -#include "porting.h" -#include <string.h> - -#if DEVICE_PART_MAX > 1 - #error "support only one jffs2 partition on a flash device!" -#endif - -/* make sure the following struct var had been initilased to 0! */ -struct device_part -{ - struct cyg_mtab_entry * mte; - struct rt_mtd_nor_device *dev; -}; -static struct device_part device_partition[DEVICE_PART_MAX] = {0}; -static struct rt_mutex jffs2_lock; - -#define jffs2_mount jffs2_fste.mount -#define jffs2_umount jffs2_fste.umount -#define jffs2_open jffs2_fste.open -#define jffs2_file_unlink jffs2_fste.unlink -#define jffs2_mkdir jffs2_fste.mkdir -#define jffs2_rmdir jffs2_fste.rmdir -#define jffs2_rename jffs2_fste.rename -#define jffs2_link jffs2_fste.link -#define jffs2_opendir jffs2_fste.opendir -#define jffs2_chdir jffs2_fste.chdir -#define jffs2_ops_stat jffs2_fste.stat -#define jffs2_getinfo jffs2_fste.getinfo -#define jffs2_setinfo jffs2_fste.setinfo - -#define jffs2_file_read jffs2_fileops.fo_read -#define jffs2_file_write jffs2_fileops.fo_write -#define jffs2_file_lseek jffs2_fileops.fo_lseek -#define jffs2_file_ioctl jffs2_fileops.fo_ioctl -#define jffs2_file_select jffs2_fileops.fo_select -#define jffs2_file_fsync jffs2_fileops.fo_fsync -#define jffs2_file_colse jffs2_fileops.fo_close -#define jffs2_file_fstat jffs2_fileops.fo_fstat -#define jffs2_file_getinfo jffs2_fileops.fo_getinfo -#define jffs2_file_setinfo jffs2_fileops.fo_setinfo - -#define jffs2_dir_read jffs2_dirops.fo_read -//#define jffs2_dir_write jffs2_dirops.fo_write -#define jffs2_dir_lseek jffs2_dirops.fo_lseek -//#define jffs2_dir_ioctl jffs2_dirops.fo_ioctl -#define jffs2_dir_select jffs2_dirops.fo_select -//#define jffs2_dir_fsync jffs2_dirops.fo_fsync -#define jffs2_dir_colse jffs2_dirops.fo_close -//#define jffs2_dir_fstat jffs2_dirops.fo_fstat -//#define jffs2_dir_getinfo jffs2_dirops.fo_getinfo -//#define jffs2_dir_setinfo jffs2_dirops.fo_setinfo - -/* - * RT-Thread Device Interface for jffs2 - */ - -/* these code is in src/flashio.c */ -static int jffs2_result_to_dfs(int result) -{ - if (result < 0) return result; - if (result > 0) return -result; - - return 0; -} - -/* - * RT-Thread DFS Interface for jffs2 - */ -static int dfs_jffs2_mount(struct dfs_filesystem* fs, - unsigned long rwflag, - const void* data) -{ - unsigned index; - struct cyg_mtab_entry * mte; - int result; - - /* find a empty entry in partition table */ - for (index = 0; index < DEVICE_PART_MAX; index ++) - { - if (device_partition[index].dev == RT_NULL) - break; - } - if (index == DEVICE_PART_MAX) - return -ENOSPC; - - mte = rt_malloc(sizeof(struct cyg_mtab_entry)); - if (mte == RT_NULL) - return -ENOMEM; - - mte->name = fs->path; - mte->fsname = "jffs2"; - mte->devname = NULL; - /* note that, i use mte->data to store rtt's device - * while, in jffs2_mount, mte->data will be copy into - * s_dev in struct super_block, and mte->data will be - * filled with jffs2_sb(see the source of jffs2_mount. - */ - mte->data = (CYG_ADDRWORD)fs->dev_id; - - device_partition[index].dev = RT_MTD_NOR_DEVICE(fs->dev_id); - /* after jffs2_mount, mte->data will not be dev_id any more */ - result = jffs2_mount(NULL, mte); - if (result != 0) - { - device_partition[index].dev = NULL; - return jffs2_result_to_dfs(result); - } - - /* save this pointer */ - device_partition[index].mte = mte; - return 0; -} - -static int _find_fs(struct cyg_mtab_entry ** mte, rt_device_t dev_id) -{ - unsigned index; - - /* find device index */ - for (index = 0; index < DEVICE_PART_MAX; index++) - { - if (device_partition[index].dev == RT_MTD_NOR_DEVICE(dev_id)) - { - *mte = device_partition[index].mte; - return 0; - } - } - - rt_kprintf("error, could not found the fs!"); - return -1; -} - -static int dfs_jffs2_unmount(struct dfs_filesystem* fs) -{ - int result; - unsigned index; - - /* find device index, then umount it */ - for (index = 0; index < DEVICE_PART_MAX; index++) - { - if (device_partition[index].dev == RT_MTD_NOR_DEVICE(fs->dev_id)) - { - result = jffs2_umount(device_partition[index].mte); - if (result) return jffs2_result_to_dfs(result); - - rt_free(device_partition[index].mte); - device_partition[index].dev = NULL; - device_partition[index].mte = NULL; - return RT_EOK; - } - } - - return -ENOENT; -} - -static int dfs_jffs2_mkfs(rt_device_t dev_id) -{ - /* just erase all blocks on this nand partition */ - return -ENOSYS; -} - -static int dfs_jffs2_statfs(struct dfs_filesystem* fs, - struct statfs *buf) -{ - /* since the limit of unsigned long, so the max size of flash device is 4G */ - struct cyg_mtab_entry * mte; - struct jffs2_fs_info info; - int result; - - result = _find_fs(&mte, fs->dev_id); - if (result) - return -ENOENT; - - RT_ASSERT(mte->data != 0); - - jffs2_get_info_from_sb((void *)mte->data, &info); - buf->f_bsize = info.sector_size; - buf->f_blocks = info.nr_blocks; - buf->f_bfree = info.free_size / info.sector_size; - - return 0; -} - -static const char jffs2_root_path[] = "."; - -static int dfs_jffs2_open(struct dfs_fd* file) -{ - int result; - int oflag, mode; - const char * name; - cyg_file * jffs2_file; - struct dfs_filesystem *fs; - struct cyg_mtab_entry * mte; - - oflag = file->flags; - fs = (struct dfs_filesystem *)file->data; - RT_ASSERT(fs != RT_NULL); - - jffs2_file = rt_malloc(sizeof(cyg_file)); - if (jffs2_file == RT_NULL) - return -ENOMEM; - - /* just escape '/' provided by dfs code */ - name = file->path; - if ((name[0] == '/') && (name[1] == 0)) - name = jffs2_root_path; - else /* name[0] still will be '/' */ - name ++; - - result = _find_fs(&mte, fs->dev_id); - if (result) - { - rt_free(jffs2_file); - return -ENOENT; - } - - /* set mount table */ - jffs2_file->f_mte = mte; - - if (oflag & O_DIRECTORY) /* operations about dir */ - { - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - if (oflag & O_CREAT) /* create a dir*/ - { - /* fixme, should test file->path can end with '/' */ - result = jffs2_mkdir(mte, mte->root, name); - if (result) - { - rt_mutex_release(&jffs2_lock); - rt_free(jffs2_file); - return jffs2_result_to_dfs(result); - } - } - - /* open dir */ - result = jffs2_opendir(mte, mte->root, name, jffs2_file); - rt_mutex_release(&jffs2_lock); - if (result) - { - rt_free(jffs2_file); - return jffs2_result_to_dfs(result); - } -#ifdef CONFIG_JFFS2_NO_RELATIVEDIR - jffs2_file->f_offset = 2; -#endif - /* save this pointer, it will be used by dfs_jffs2_getdents*/ - file->data = jffs2_file; - return 0; - } - /* regular file operations */ - mode = JFFS2_O_RDONLY; - if (oflag & O_WRONLY) mode |= JFFS2_O_WRONLY; - if (oflag & O_RDWR) mode |= JFFS2_O_RDWR; - /* Opens the file, if it is existing. If not, a new file is created. */ - if (oflag & O_CREAT) mode |= JFFS2_O_CREAT; - /* Creates a new file. If the file is existing, it is truncated and overwritten. */ - if (oflag & O_TRUNC) mode |= JFFS2_O_TRUNC; - /* Creates a new file. The function fails if the file is already existing. */ - if (oflag & O_EXCL) mode |= JFFS2_O_EXCL; - - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_open(mte, 0, name, mode, jffs2_file); - if (result != 0) - { - rt_mutex_release(&jffs2_lock); - rt_free(jffs2_file); - return jffs2_result_to_dfs(result); - } - - /* save this pointer, it will be used when calling read(), write(), - flush(), lessk(), and will be rt_free when calling close()*/ - file->data = jffs2_file; - file->pos = jffs2_file->f_offset; - file->size = 0; - jffs2_file_lseek(jffs2_file, (off_t *)(&(file->size)), SEEK_END); - jffs2_file->f_offset = (off_t)file->pos; - rt_mutex_release(&jffs2_lock); - - if (oflag & O_APPEND) - { - file->pos = file->size; - jffs2_file->f_offset = file->size; - } - - return 0; -} - -static int dfs_jffs2_close(struct dfs_fd* file) -{ - int result; - cyg_file * jffs2_file; - - RT_ASSERT(file->data != NULL); - jffs2_file = (cyg_file *)(file->data); - - if (file->flags & O_DIRECTORY) /* operations about dir */ - { - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_dir_colse(jffs2_file); - rt_mutex_release(&jffs2_lock); - if (result) - return jffs2_result_to_dfs(result); - - rt_free(jffs2_file); - return 0; - } - /* regular file operations */ - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_file_colse(jffs2_file); - rt_mutex_release(&jffs2_lock); - if (result) - return jffs2_result_to_dfs(result); - - /* release memory */ - rt_free(jffs2_file); - return 0; -} - -static int dfs_jffs2_ioctl(struct dfs_fd* file, int cmd, void* args) -{ - return -ENOSYS; -} - -static int dfs_jffs2_read(struct dfs_fd* file, void* buf, size_t len) -{ - cyg_file * jffs2_file; - struct CYG_UIO_TAG uio_s; - struct CYG_IOVEC_TAG iovec; - int char_read; - int result; - - RT_ASSERT(file->data != NULL); - jffs2_file = (cyg_file *)(file->data); - uio_s.uio_iov = &iovec; - uio_s.uio_iov->iov_base = buf; - uio_s.uio_iov->iov_len = len; - uio_s.uio_iovcnt = 1; //must be 1 - //uio_s.uio_offset //not used... - uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2; - - char_read = jffs2_file->f_offset; /* the current offset */ - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_file_read(jffs2_file, &uio_s); - rt_mutex_release(&jffs2_lock); - if (result) - return jffs2_result_to_dfs(result); - - /* update position */ - file->pos = jffs2_file->f_offset; - char_read = jffs2_file->f_offset - char_read; - return char_read; -} - -static int dfs_jffs2_write(struct dfs_fd* file, - const void* buf, - size_t len) -{ - cyg_file * jffs2_file; - struct CYG_UIO_TAG uio_s; - struct CYG_IOVEC_TAG iovec; - int char_write; - int result; - - RT_ASSERT(file->data != NULL); - jffs2_file = (cyg_file *)(file->data); - uio_s.uio_iov = &iovec; - uio_s.uio_iov->iov_base = (void *)buf; - uio_s.uio_iov->iov_len = len; - uio_s.uio_iovcnt = 1; //must be 1 - //uio_s.uio_offset //not used... - uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2; - - char_write = jffs2_file->f_offset; - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_file_write(jffs2_file, &uio_s); - rt_mutex_release(&jffs2_lock); - if (result) - return jffs2_result_to_dfs(result); - - /* update position */ - file->pos = jffs2_file->f_offset; - char_write = jffs2_file->f_offset - char_write; - return char_write; -} - -static int dfs_jffs2_flush(struct dfs_fd* file) -{ - /* infact, jffs2 not support, jffs2_fo_sync just return ok */ - return -ENOSYS; -} - -/* fixme warning: the offset is rt_off_t, so maybe the size of a file is must <= 2G*/ -static int dfs_jffs2_lseek(struct dfs_fd* file, - rt_off_t offset) -{ - cyg_file * jffs2_file; - int result; - - RT_ASSERT(file->data != NULL); - jffs2_file = (cyg_file *)(file->data); - - /* set offset as current offset */ - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_file_lseek(jffs2_file, &offset, SEEK_SET); - rt_mutex_release(&jffs2_lock); - if (result) - return jffs2_result_to_dfs(result); - /* update file position */ - file->pos = offset; - return offset; -} - -/* return the size of struct dirent*/ -static int dfs_jffs2_getdents(struct dfs_fd* file, - struct dirent* dirp, - rt_uint32_t count) -{ - cyg_file * jffs2_file; - struct CYG_UIO_TAG uio_s; - struct CYG_IOVEC_TAG iovec; - struct jffs2_dirent jffs2_d; - struct dirent * d; - rt_uint32_t index; -#if !defined (CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE) - struct jffs2_stat s; - cyg_mtab_entry * mte; - char * fullname; -#endif - int result; - - RT_ASSERT(file->data != RT_NULL); - jffs2_file = (cyg_file*)(file->data); - mte = jffs2_file->f_mte; - - //set jffs2_d - memset(&jffs2_d, 0, sizeof(struct jffs2_dirent)); - //set CYG_UIO_TAG uio_s - uio_s.uio_iov = &iovec; - uio_s.uio_iov->iov_base = &jffs2_d; - uio_s.uio_iov->iov_len = sizeof(struct jffs2_dirent);; - uio_s.uio_iovcnt = 1; //must be 1 - uio_s.uio_offset = 0;//not used... - uio_s.uio_resid = uio_s.uio_iov->iov_len; //seem no use in jffs2; - - /* make integer count, usually count is 1 */ - count = (count / sizeof(struct dirent)) * sizeof(struct dirent); - if (count == 0) return -EINVAL; - - index = 0; - /* usually, the while loop should only be looped only once! */ - while (1) - { - d = dirp + index; - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_dir_read(jffs2_file, &uio_s); - rt_mutex_release(&jffs2_lock); - /* if met a error or all entry are read over, break while*/ - if (result || jffs2_d.d_name[0] == 0) - break; - -#if defined (CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE) - switch(jffs2_d.d_type & JFFS2_S_IFMT) - { - case JFFS2_S_IFREG: d->d_type = DT_REG; break; - case JFFS2_S_IFDIR: d->d_type = DT_DIR; break; - default: d->d_type = DT_UNKNOWN; break; - } -#else - fullname = rt_malloc(FILE_PATH_MAX); - if(fullname == RT_NULL) - return -ENOMEM; - - /* make a right entry */ - if ((file->path[0] == '/') ) - { - if (file->path[1] == 0) - strcpy(fullname, jffs2_d.d_name); - else - rt_sprintf(fullname, "%s/%s", file->path+1, jffs2_d.d_name); - } - else - rt_sprintf(fullname, "%s/%s", file->path, jffs2_d.d_name); - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_porting_stat(mte, mte->root, fullname, (void *)&s); - rt_mutex_release(&jffs2_lock); - if (result) - return jffs2_result_to_dfs(result); - - rt_free(fullname); - /* convert to dfs stat structure */ - switch(s.st_mode & JFFS2_S_IFMT) - { - case JFFS2_S_IFREG: d->d_type = DT_REG; break; - case JFFS2_S_IFDIR: d->d_type = DT_DIR; break; - default: d->d_type = DT_UNKNOWN; break; - } -#endif - /* write the rest fields of struct dirent* dirp */ - d->d_namlen = rt_strlen(jffs2_d.d_name); - d->d_reclen = (rt_uint16_t)sizeof(struct dirent); - rt_strncpy(d->d_name, jffs2_d.d_name, d->d_namlen + 1); - - index ++; - if (index * sizeof(struct dirent) >= count) - break; - } - if (result) - return jffs2_result_to_dfs(result); - return index * sizeof(struct dirent); -} - -static int dfs_jffs2_unlink(struct dfs_filesystem* fs, const char* path) -{ - int result; - struct jffs2_stat s; - cyg_mtab_entry * mte; - - result = _find_fs(&mte, fs->dev_id); - if (result) - return -ENOENT; - - /* deal path */ - if (path[0] == '/') - path++; - - /* judge file type, dir is to be delete by rmdir, others by unlink */ - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_porting_stat(mte, mte->root, path, (void *)&s); - if (result) - { - rt_mutex_release(&jffs2_lock); - return jffs2_result_to_dfs(result); - } - - switch(s.st_mode & JFFS2_S_IFMT) - { - case JFFS2_S_IFREG: - result = jffs2_file_unlink(mte, mte->root, path); - break; - case JFFS2_S_IFDIR: - result = jffs2_rmdir(mte, mte->root, path); - break; - default: - /* unknown file type */ - rt_mutex_release(&jffs2_lock); - return -1; - } - rt_mutex_release(&jffs2_lock); - if (result) - return jffs2_result_to_dfs(result); - return 0; -} - -static int dfs_jffs2_rename(struct dfs_filesystem* fs, - const char* oldpath, - const char* newpath) -{ - int result; - cyg_mtab_entry * mte; - - result = _find_fs(&mte, fs->dev_id); - if (result) - return -ENOENT; - - if (*oldpath == '/') - oldpath += 1; - if (*newpath == '/') - newpath += 1; - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_rename(mte, mte->root, oldpath, mte->root, newpath); - rt_mutex_release(&jffs2_lock); - if (result) - return jffs2_result_to_dfs(result); - return 0; -} - -static int dfs_jffs2_stat(struct dfs_filesystem* fs, const char *path, struct stat *st) -{ - int result; - struct jffs2_stat s; - cyg_mtab_entry * mte; - - /* deal the path for jffs2 */ - RT_ASSERT(!((path[0] == '/') && (path[1] == 0))); - - if (path[0] == '/') - path++; - - result = _find_fs(&mte, fs->dev_id); - if (result) - return -ENOENT; - - rt_mutex_take(&jffs2_lock, RT_WAITING_FOREVER); - result = jffs2_porting_stat(mte, mte->root, path, (void *)&s); - rt_mutex_release(&jffs2_lock); - - if (result) - return jffs2_result_to_dfs(result); - /* convert to dfs stat structure */ - switch(s.st_mode & JFFS2_S_IFMT) - { - case JFFS2_S_IFREG: - st->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH | - S_IWUSR | S_IWGRP | S_IWOTH; - break; - - case JFFS2_S_IFDIR: - st->st_mode = S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH; - break; - - default: - st->st_mode = DT_UNKNOWN; //fixme - break; - } - - st->st_dev = 0; - st->st_size = s.st_size; - st->st_mtime = s.st_mtime; - - return 0; -} - -static const struct dfs_file_ops _jffs2_fops = -{ - dfs_jffs2_open, - dfs_jffs2_close, - dfs_jffs2_ioctl, - dfs_jffs2_read, - dfs_jffs2_write, - dfs_jffs2_flush, - dfs_jffs2_lseek, - dfs_jffs2_getdents, -}; - -static const struct dfs_filesystem_ops _jffs2_ops = -{ - "jffs2", - DFS_FS_FLAG_DEFAULT, - &_jffs2_fops, - - dfs_jffs2_mount, - dfs_jffs2_unmount, - dfs_jffs2_mkfs, - dfs_jffs2_statfs, - - dfs_jffs2_unlink, - dfs_jffs2_stat, - dfs_jffs2_rename, -}; - -int dfs_jffs2_init(void) -{ - /* register fatfs file system */ - dfs_register(&_jffs2_ops); - - /* initialize mutex */ - if (rt_mutex_init(&jffs2_lock, "jffs2lock", RT_IPC_FLAG_FIFO) != RT_EOK) - { - rt_kprintf("init jffs2 lock mutex failed\n"); - } - rt_kprintf("init jffs2 lock mutex okay\n"); - return 0; -} -INIT_COMPONENT_EXPORT(dfs_jffs2_init); diff --git a/components/dfs/filesystems/jffs2/dfs_jffs2.h b/components/dfs/filesystems/jffs2/dfs_jffs2.h deleted file mode 100644 index 1be403a19c..0000000000 --- a/components/dfs/filesystems/jffs2/dfs_jffs2.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef __DFS_JFFS2_H__ -#define __DFS_JFFS2_H__ - -int dfs_jffs2_init(void); - -#endif diff --git a/components/dfs/filesystems/jffs2/include/linux/jffs2.h b/components/dfs/filesystems/jffs2/include/linux/jffs2.h deleted file mode 100644 index ab034effe6..0000000000 --- a/components/dfs/filesystems/jffs2/include/linux/jffs2.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in the - * jffs2 directory. - * - * $Id: jffs2.h,v 1.36 2005/07/26 13:19:36 havasi Exp $ - * - */ - -#ifndef __LINUX_JFFS2_H__ -#define __LINUX_JFFS2_H__ - -/* You must include something which defines the C99 uintXX_t types. - We don't do it from here because this file is used in too many - different environments. */ - -#define JFFS2_SUPER_MAGIC 0x72b6 - -/* Values we may expect to find in the 'magic' field */ -#define JFFS2_OLD_MAGIC_BITMASK 0x1984 -#define JFFS2_MAGIC_BITMASK 0x1985 -#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */ -#define JFFS2_EMPTY_BITMASK 0xffff -#define JFFS2_DIRTY_BITMASK 0x0000 - -/* We only allow a single char for length, and 0xFF is empty flash so - we don't want it confused with a real length. Hence max 254. -*/ -#define JFFS2_MAX_NAME_LEN 254 - -/* How small can we sensibly write nodes? */ -#define JFFS2_MIN_DATA_LEN 128 - -#define JFFS2_COMPR_NONE 0x00 -#define JFFS2_COMPR_ZERO 0x01 -#define JFFS2_COMPR_RTIME 0x02 -#define JFFS2_COMPR_RUBINMIPS 0x03 -#define JFFS2_COMPR_COPY 0x04 -#define JFFS2_COMPR_DYNRUBIN 0x05 -#define JFFS2_COMPR_ZLIB 0x06 -/* Compatibility flags. */ -#define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */ -#define JFFS2_NODE_ACCURATE 0x2000 -/* INCOMPAT: Fail to mount the filesystem */ -#define JFFS2_FEATURE_INCOMPAT 0xc000 -/* ROCOMPAT: Mount read-only */ -#define JFFS2_FEATURE_ROCOMPAT 0x8000 -/* RWCOMPAT_COPY: Mount read/write, and copy the node when it's GC'd */ -#define JFFS2_FEATURE_RWCOMPAT_COPY 0x4000 -/* RWCOMPAT_DELETE: Mount read/write, and delete the node when it's GC'd */ -#define JFFS2_FEATURE_RWCOMPAT_DELETE 0x0000 - -#define JFFS2_NODETYPE_DIRENT (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 1) -#define JFFS2_NODETYPE_INODE (JFFS2_FEATURE_INCOMPAT | JFFS2_NODE_ACCURATE | 2) -#define JFFS2_NODETYPE_CLEANMARKER (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) -#define JFFS2_NODETYPE_PADDING (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 4) - -// Maybe later... -//#define JFFS2_NODETYPE_CHECKPOINT (JFFS2_FEATURE_RWCOMPAT_DELETE | JFFS2_NODE_ACCURATE | 3) -//#define JFFS2_NODETYPE_OPTIONS (JFFS2_FEATURE_RWCOMPAT_COPY | JFFS2_NODE_ACCURATE | 4) - - -#define JFFS2_INO_FLAG_PREREAD 1 /* Do read_inode() for this one at - mount time, don't wait for it to - happen later */ -#define JFFS2_INO_FLAG_USERCOMPR 2 /* User has requested a specific - compression type */ - - -/* These can go once we've made sure we've caught all uses without - byteswapping */ -#include <stdint.h> - -#if defined(__GNUC__) || (__CC_ARM) -typedef struct { - uint32_t v32; -} __attribute__((packed)) jint32_t; - -typedef struct { - uint32_t m; -} __attribute__((packed)) jmode_t; - -typedef struct { - uint16_t v16; -} __attribute__((packed)) jint16_t; - -struct jffs2_unknown_node -{ - /* All start like this */ - jint16_t magic; - jint16_t nodetype; - jint32_t totlen; /* So we can skip over nodes we don't grok */ - jint32_t hdr_crc; -} __attribute__((packed)); - -struct jffs2_raw_dirent -{ - jint16_t magic; - jint16_t nodetype; /* == JFFS2_NODETYPE_DIRENT */ - jint32_t totlen; - jint32_t hdr_crc; - jint32_t pino; - jint32_t version; - jint32_t ino; /* == zero for unlink */ - jint32_t mctime; - uint8_t nsize; - uint8_t type; - uint8_t unused[2]; - jint32_t node_crc; - jint32_t name_crc; - uint8_t name[0]; -} __attribute__((packed)); - -/* The JFFS2 raw inode structure: Used for storage on physical media. */ -/* The uid, gid, atime, mtime and ctime members could be longer, but - are left like this for space efficiency. If and when people decide - they really need them extended, it's simple enough to add support for - a new type of raw node. -*/ -struct jffs2_raw_inode -{ - jint16_t magic; /* A constant magic number. */ - jint16_t nodetype; /* == JFFS2_NODETYPE_INODE */ - jint32_t totlen; /* Total length of this node (inc data, etc.) */ - jint32_t hdr_crc; - jint32_t ino; /* Inode number. */ - jint32_t version; /* Version number. */ - jmode_t mode; /* The file's type or mode. */ - jint16_t uid; /* The file's owner. */ - jint16_t gid; /* The file's group. */ - jint32_t isize; /* Total resultant size of this inode (used for truncations) */ - jint32_t atime; /* Last access time. */ - jint32_t mtime; /* Last modification time. */ - jint32_t ctime; /* Change time. */ - jint32_t offset; /* Where to begin to write. */ - jint32_t csize; /* (Compressed) data size */ - jint32_t dsize; /* Size of the node's data. (after decompression) */ - uint8_t compr; /* Compression algorithm used */ - uint8_t usercompr; /* Compression algorithm requested by the user */ - jint16_t flags; /* See JFFS2_INO_FLAG_* */ - jint32_t data_crc; /* CRC for the (compressed) data. */ - jint32_t node_crc; /* CRC for the raw inode (excluding data) */ - uint8_t data[0]; -} __attribute__((packed)); - -#elif defined (MSVC) -typedef uint32_t jint32_t; -//typedef uint32_t jmode_t; -typedef struct { - uint32_t m; -} jmode_t; -typedef uint16_t jint16_t; - -#pragma pack(1) -struct jffs2_unknown_node -{ - /* All start like this */ - jint16_t magic; - jint16_t nodetype; - jint32_t totlen; /* So we can skip over nodes we don't grok */ - jint32_t hdr_crc; -}; - -struct jffs2_raw_dirent -{ - jint16_t magic; - jint16_t nodetype; /* == JFFS2_NODETYPE_DIRENT */ - jint32_t totlen; - jint32_t hdr_crc; - jint32_t pino; - jint32_t version; - jint32_t ino; /* == zero for unlink */ - jint32_t mctime; - uint8_t nsize; - uint8_t type; - uint8_t unused[2]; - jint32_t node_crc; - jint32_t name_crc; - uint8_t name[0]; -}; - -/* The JFFS2 raw inode structure: Used for storage on physical media. */ -/* The uid, gid, atime, mtime and ctime members could be longer, but - are left like this for space efficiency. If and when people decide - they really need them extended, it's simple enough to add support for - a new type of raw node. -*/ -struct jffs2_raw_inode -{ - jint16_t magic; /* A constant magic number. */ - jint16_t nodetype; /* == JFFS2_NODETYPE_INODE */ - jint32_t totlen; /* Total length of this node (inc data, etc.) */ - jint32_t hdr_crc; - jint32_t ino; /* Inode number. */ - jint32_t version; /* Version number. */ - jmode_t mode; /* The file's type or mode. */ - jint16_t uid; /* The file's owner. */ - jint16_t gid; /* The file's group. */ - jint32_t isize; /* Total resultant size of this inode (used for truncations) */ - jint32_t atime; /* Last access time. */ - jint32_t mtime; /* Last modification time. */ - jint32_t ctime; /* Change time. */ - jint32_t offset; /* Where to begin to write. */ - jint32_t csize; /* (Compressed) data size */ - jint32_t dsize; /* Size of the node's data. (after decompression) */ - uint8_t compr; /* Compression algorithm used */ - uint8_t usercompr; /* Compression algorithm requested by the user */ - jint16_t flags; /* See JFFS2_INO_FLAG_* */ - jint32_t data_crc; /* CRC for the (compressed) data. */ - jint32_t node_crc; /* CRC for the raw inode (excluding data) */ - uint8_t data[0]; -}; -#pragma pack() -#else -#endif - - -union jffs2_node_union { - struct jffs2_raw_inode i; - struct jffs2_raw_dirent d; - struct jffs2_unknown_node u; -}; - -#endif /* __LINUX_JFFS2_H__ */ diff --git a/components/dfs/filesystems/jffs2/include/linux/jffs2_fs_i.h b/components/dfs/filesystems/jffs2/include/linux/jffs2_fs_i.h deleted file mode 100644 index 7f30282653..0000000000 --- a/components/dfs/filesystems/jffs2/include/linux/jffs2_fs_i.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $Id: jffs2_fs_i.h,v 1.18 2005/07/17 11:13:48 dedekind Exp $ */ - -#ifndef _JFFS2_FS_I -#define _JFFS2_FS_I - -#include <linux/version.h> -#include <linux/rbtree.h> -#include <asm/semaphore.h> - -struct jffs2_inode_info { - /* We need an internal semaphore similar to inode->i_sem. - Unfortunately, we can't used the existing one, because - either the GC would deadlock, or we'd have to release it - before letting GC proceed. Or we'd have to put ugliness - into the GC code so it didn't attempt to obtain the i_sem - for the inode(s) which are already locked */ - struct semaphore sem; - - /* The highest (datanode) version number used for this ino */ - uint32_t highest_version; - - /* List of data fragments which make up the file */ - struct rb_root fragtree; - - /* There may be one datanode which isn't referenced by any of the - above fragments, if it contains a metadata update but no actual - data - or if this is a directory inode */ - /* This also holds the _only_ dnode for symlinks/device nodes, - etc. */ - struct jffs2_full_dnode *metadata; - - /* Directory entries */ - struct jffs2_full_dirent *dents; - - /* The target path if this is the inode of a symlink */ - unsigned char *target; - - /* Some stuff we just have to keep in-core at all times, for each inode. */ - struct jffs2_inode_cache *inocache; - - uint16_t flags; - uint8_t usercompr; -#if !defined (__ECOS) && !defined(RT_THREAD) -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2) - struct inode vfs_inode; -#endif -#endif -}; - -#endif /* _JFFS2_FS_I */ diff --git a/components/dfs/filesystems/jffs2/include/linux/jffs2_fs_sb.h b/components/dfs/filesystems/jffs2/include/linux/jffs2_fs_sb.h deleted file mode 100644 index 066e9400bc..0000000000 --- a/components/dfs/filesystems/jffs2/include/linux/jffs2_fs_sb.h +++ /dev/null @@ -1,120 +0,0 @@ -/* $Id: jffs2_fs_sb.h,v 1.52 2005/05/19 16:12:17 gleixner Exp $ */ - -#ifndef _JFFS2_FS_SB -#define _JFFS2_FS_SB - -#include "jffs2_config.h" -#include <linux/types.h> -#include <linux/spinlock.h> -#include <linux/workqueue.h> -#include <linux/completion.h> -#include <asm/semaphore.h> -#include <linux/timer.h> -#include <linux/wait.h> -#include <linux/list.h> -#include <linux/rwsem.h> - -#define JFFS2_SB_FLAG_RO 1 -#define JFFS2_SB_FLAG_SCANNING 2 /* Flash scanning is in progress */ -#define JFFS2_SB_FLAG_BUILDING 4 /* File system building is in progress */ - -struct jffs2_inodirty; - -/* A struct for the overall file system control. Pointers to - jffs2_sb_info structs are named `c' in the source code. - Nee jffs_control -*/ -struct jffs2_sb_info { - struct mtd_info *mtd; - - uint32_t highest_ino; - uint32_t checked_ino; - - unsigned int flags; - - struct task_struct *gc_task; /* GC task struct */ - struct completion gc_thread_start; /* GC thread start completion */ - struct completion gc_thread_exit; /* GC thread exit completion port */ - - struct semaphore alloc_sem; /* Used to protect all the following - fields, and also to protect against - out-of-order writing of nodes. And GC. */ - uint32_t cleanmarker_size; /* Size of an _inline_ CLEANMARKER - (i.e. zero for OOB CLEANMARKER */ - - uint32_t flash_size; - uint32_t used_size; - uint32_t dirty_size; - uint32_t wasted_size; - uint32_t free_size; - uint32_t erasing_size; - uint32_t bad_size; - uint32_t sector_size; - uint32_t unchecked_size; - - uint32_t nr_free_blocks; - uint32_t nr_erasing_blocks; - - /* Number of free blocks there must be before we... */ - uint8_t resv_blocks_write; /* ... allow a normal filesystem write */ - uint8_t resv_blocks_deletion; /* ... allow a normal filesystem deletion */ - uint8_t resv_blocks_gctrigger; /* ... wake up the GC thread */ - uint8_t resv_blocks_gcbad; /* ... pick a block from the bad_list to GC */ - uint8_t resv_blocks_gcmerge; /* ... merge pages when garbage collecting */ - - uint32_t nospc_dirty_size; - - uint32_t nr_blocks; - struct jffs2_eraseblock *blocks; /* The whole array of blocks. Used for getting blocks - * from the offset (blocks[ofs / sector_size]) */ - struct jffs2_eraseblock *nextblock; /* The block we're currently filling */ - - struct jffs2_eraseblock *gcblock; /* The block we're currently garbage-collecting */ - - struct list_head clean_list; /* Blocks 100% full of clean data */ - struct list_head very_dirty_list; /* Blocks with lots of dirty space */ - struct list_head dirty_list; /* Blocks with some dirty space */ - struct list_head erasable_list; /* Blocks which are completely dirty, and need erasing */ - struct list_head erasable_pending_wbuf_list; /* Blocks which need erasing but only after the current wbuf is flushed */ - struct list_head erasing_list; /* Blocks which are currently erasing */ - struct list_head erase_pending_list; /* Blocks which need erasing now */ - struct list_head erase_complete_list; /* Blocks which are erased and need the clean marker written to them */ - struct list_head free_list; /* Blocks which are free and ready to be used */ - struct list_head bad_list; /* Bad blocks. */ - struct list_head bad_used_list; /* Bad blocks with valid data in. */ - - spinlock_t erase_completion_lock; /* Protect free_list and erasing_list - against erase completion handler */ - wait_queue_head_t erase_wait; /* For waiting for erases to complete */ - - wait_queue_head_t inocache_wq; - struct jffs2_inode_cache **inocache_list; - spinlock_t inocache_lock; - - /* Sem to allow jffs2_garbage_collect_deletion_dirent to - drop the erase_completion_lock while it's holding a pointer - to an obsoleted node. I don't like this. Alternatives welcomed. */ - struct semaphore erase_free_sem; - -#ifdef CONFIG_JFFS2_FS_WRITEBUFFER - /* Write-behind buffer for NAND flash */ - unsigned char *wbuf; - uint32_t wbuf_ofs; - uint32_t wbuf_len; - uint32_t wbuf_pagesize; - struct jffs2_inodirty *wbuf_inodes; - - struct rw_semaphore wbuf_sem; /* Protects the write buffer */ - - /* Information about out-of-band area usage... */ - struct nand_oobinfo *oobinfo; - uint32_t badblock_pos; - uint32_t fsdata_pos; - uint32_t fsdata_len; -#endif - - /* OS-private pointer for getting back to master superblock info */ - void *os_priv; -}; - -#endif /* _JFFS2_FB_SB */ diff --git a/components/dfs/filesystems/jffs2/include/port/codes.h b/components/dfs/filesystems/jffs2/include/port/codes.h deleted file mode 100644 index 2426465c84..0000000000 --- a/components/dfs/filesystems/jffs2/include/port/codes.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef CYGONCE_ERROR_CODES_H -#define CYGONCE_ERROR_CODES_H -/*=========================================================================== -// -// codes.h -// -// Common error code definitions -// -//=========================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//=========================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jlarmour -// Contributors: jlarmour -// Date: 2000-04-14 -// Purpose: To provide a common set of error codes -// Description: This provides a common set of error codes that all -// packages can agree on. It doesn't preclude them defining -// their own error return system, but this is a preferable -// system to use to help error support be as general as -// possible. -// -// We try and conform to the ANSI/POSIX error code format, -// namely starting with the character 'E' -// -// Usage: #include <cyg/error/codes.h> -// -// Example: -// -// err=myfun(); -// if (err != ENOERR) -// { -// str=strerror(err); -// printf("myfun returned error: %s\n", str); -// } -// else .... -// -//####DESCRIPTIONEND#### -// -//=========================================================================*/ - -/* CONFIGURATION */ - -//#include <pkgconf/error.h> prife // Configuration header - -#ifdef __cplusplus -extern "C" { -#endif - -/* TYPE DEFINITIONS */ - -/* A type for error codes which may be useful to explain the purpose of - * a variable or return code. It shows that it contains an error code - * of the type defined below */ - -typedef int Cyg_ErrNo; - -#include <rtthread.h> - -#define ENOERR RT_EOK - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* CYGONCE_ERROR_CODES_H multiple inclusion protection */ - -/* EOF codes.h */ diff --git a/components/dfs/filesystems/jffs2/include/port/fcntl.h b/components/dfs/filesystems/jffs2/include/port/fcntl.h deleted file mode 100644 index fcc3088fc7..0000000000 --- a/components/dfs/filesystems/jffs2/include/port/fcntl.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef CYGONCE_ISO_FCNTL_H -#define CYGONCE_ISO_FCNTL_H - -/*------------------------------------------------------------------------*/ -/* for dfs_jffs2.c */ -/*------------------------------------------------------------------------*/ -/* File access modes used for open() and fnctl() */ -#define JFFS2_O_RDONLY (O_RDONLY) /* Open for reading only */ -#define JFFS2_O_WRONLY (O_WRONLY) /* Open for writing only */ -#define JFFS2_O_RDWR (O_RDONLY|O_WRONLY) /* Open for reading and writing */ - -/* File access mode mask */ -#define JFFS2_O_ACCMODE (O_RDONLY|O_RDWR|O_WRONLY) - -/* open() mode flags */ - -#define JFFS2_O_CREAT (O_CREAT) /* Create file it it does not exist */ -#define JFFS2_O_EXCL (O_EXCL) /* Exclusive use */ -#define JFFS2_O_NOCTTY (O_NOCTTY) /* Do not assign a controlling terminal */ -#define JFFS2_O_TRUNC (O_TRUNC) /* Truncate */ - -/* File status flags used for open() and fcntl() */ -#define JFFS2_O_APPEND (O_APPEND) /* Set append mode */ -#define JFFS2_O_DSYNC (O_DSYNC) /* Synchronized I/O data integrity writes */ -#define JFFS2_O_NONBLOCK (O_NONBLOCK)/* No delay */ -#define JFFS2_O_RSYNC (O_RSYNC) /* Synchronized read I/O */ -#define JFFS2_O_SYNC (O_SYNC) /* Synchronized I/O file integrity writes */ - -#endif - -/* EOF fcntl.h */ diff --git a/components/dfs/filesystems/jffs2/include/port/sys/stat.h b/components/dfs/filesystems/jffs2/include/port/sys/stat.h deleted file mode 100644 index 43958a752f..0000000000 --- a/components/dfs/filesystems/jffs2/include/port/sys/stat.h +++ /dev/null @@ -1,294 +0,0 @@ -#ifndef CYGONCE_ISO_SYS_TYPES_H -#define CYGONCE_ISO_SYS_TYPES_H -/*======================================================================== -// -// sys/types.h -// -// POSIX types -// -//======================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//======================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jlarmour -// Contributors: -// Date: 2000-04-14 -// Purpose: This file provides various types required by POSIX 1003.1. -// Description: The real contents of this file get set from the -// configuration (set by the implementation) -// Usage: #include <sys/types.h> -// -//####DESCRIPTIONEND#### -// -//====================================================================== -*/ - -/* CONFIGURATION */ - -//#include <pkgconf/system.h> -//#include <pkgconf/isoinfra.h> /* Configuration header */ - -/* INCLUDES */ - -/* This is the "standard" way to get size_t from stddef.h, - * which is the canonical location of the definition. - */ -//#define __need_size_t -//#include <stddef.h> -#include "port/codes.h" - -/* -#ifndef dev_t -typedef short dev_t; -#endif - -#ifndef ino_t -typedef unsigned int ino_t; -#endif - -#ifndef mode_t -typedef unsigned int mode_t; -#endif -*/ - -typedef unsigned short nlink_t; -typedef long off_t; - -typedef unsigned short gid_t; -typedef unsigned short uid_t; -typedef int pid_t; - -// -typedef void *cyg_io_handle_t; - -/* Variable names for pathconf() */ -#define _PC_ASYNC_IO 1 -#define _PC_CHOWN_RESTRICTED 2 -#define _PC_LINK_MAX 3 -#define _PC_MAX_CANON 4 -#define _PC_MAX_INPUT 5 -#define _PC_NAME_MAX 6 -#define _PC_NO_TRUNC 7 -#define _PC_PATH_MAX 8 -#define _PC_PIPE_BUF 9 -#define _PC_PRIO_IO 10 -#define _PC_SYNC_IO 11 -#define _PC_VDISABLE 12 - -//limit.h -/* DEFINES */ - -/*----------------------------------------------------------------------------- - * Minimum values from POSIX.1 tables 2-3, 2-7 and 2-7a. - - * These are the standard-mandated minimum values. - * These values do not vary with the implementation - they may - * simply be defined - */ - -/* Minimum number of operations in one list I/O call. */ -#define _POSIX_AIO_LISTIO_MAX 2 - -/* Minimal number of outstanding asynchronous I/O operations. */ -#define _POSIX_AIO_MAX 1 - -/* Maximum length of arguments to `execve', including environment. */ -#define _POSIX_ARG_MAX 4096 - -/* Maximum simultaneous processes per real user ID. */ -#define _POSIX_CHILD_MAX 6 - -/* Minimal number of timer expiration overruns. */ -#define _POSIX_DELAYTIMER_MAX 32 - -/* Maximum link count of a file. */ -#define _POSIX_LINK_MAX 8 - -/* Size of storage required for a login name */ -#define _POSIX_LOGIN_NAME_MAX 9 - -/* Number of bytes in a terminal canonical input queue. */ -#define _POSIX_MAX_CANON 255 - -/* Number of bytes for which space will be - available in a terminal input queue. */ -#define _POSIX_MAX_INPUT 255 - -/* Maximum number of message queues open for a process. */ -#define _POSIX_MQ_OPEN_MAX 8 - -/* Maximum number of supported message priorities. */ -#define _POSIX_MQ_PRIO_MAX 32 - -/* Number of bytes in a filename. */ -#define _POSIX_NAME_MAX 14 - -/* Number of simultaneous supplementary group IDs per process. */ -#define _POSIX_NGROUPS_MAX 0 - -/* Number of files one process can have open at once. */ -#define _POSIX_OPEN_MAX 16 - -/* Number of bytes in a pathname. */ -#define _POSIX_PATH_MAX 255 - -/* Number of bytes than can be written atomically to a pipe. */ -#define _POSIX_PIPE_BUF 512 - -/* Minimal number of realtime signals reserved for the application. */ -#define _POSIX_RTSIG_MAX 8 - -/* Number of semaphores a process can have. */ -#define _POSIX_SEM_NSEMS_MAX 256 - -/* Maximal value of a semaphore. */ -#define _POSIX_SEM_VALUE_MAX 32767 - -/* Number of pending realtime signals. */ -#define _POSIX_SIGQUEUE_MAX 32 - -/* Largest value of a `ssize_t'. */ -#define _POSIX_SSIZE_MAX 32767 - -/* Number of streams a process can have open at once. */ -#define _POSIX_STREAM_MAX 8 - -/* Controlling the iterations of destructors for thread-specific data. */ -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 - -/* The number of data keys per process. */ -#define _POSIX_THREAD_KEYS_MAX 128 - -/* The number of threads per process. */ -#define _POSIX_THREAD_THREADS_MAX 64 - -/* Maximum number of characters in a tty name. */ -#define _POSIX_TTY_NAME_MAX 9 - -/* Number of timer for a process. */ -#define _POSIX_TIMER_MAX 32 - -/* Maximum length of a timezone name (element of `tzname'). */ -#define _POSIX_TZNAME_MAX 3 - -/* Maximum clock resolution in nanoseconds. */ -#define _POSIX_CLOCKRES_MIN 20000000 - - -#ifdef CYGBLD_ISO_SSIZET_HEADER -# include CYGBLD_ISO_SSIZET_HEADER -#else -# ifndef __STRICT_ANSI__ -# define SSIZE_MAX LONG_MAX -# endif -#endif - -/* INCLUDES */ - -#ifdef CYGBLD_ISO_OPEN_MAX_HEADER -# include CYGBLD_ISO_OPEN_MAX_HEADER -#else -# ifndef __STRICT_ANSI__ -# define OPEN_MAX _POSIX_OPEN_MAX -# endif -#endif - -#ifdef CYGBLD_ISO_LINK_MAX_HEADER -# include CYGBLD_ISO_LINK_MAX_HEADER -#else -# ifndef __STRICT_ANSI__ -# define LINK_MAX _POSIX_LINK_MAX -# endif -#endif - -#ifdef CYGBLD_ISO_NAME_MAX_HEADER -# include CYGBLD_ISO_NAME_MAX_HEADER -#else -# ifndef __STRICT_ANSI__ -# define NAME_MAX _POSIX_NAME_MAX -# endif -#endif - -#ifdef CYGBLD_ISO_PATH_MAX_HEADER -# include CYGBLD_ISO_PATH_MAX_HEADER -#else -# ifndef __STRICT_ANSI__ -# define PATH_MAX _POSIX_PATH_MAX -# endif -#endif - -#if CYGINT_ISO_POSIX_LIMITS -# ifdef CYGBLD_ISO_POSIX_LIMITS_HEADER -# include CYGBLD_ISO_POSIX_LIMITS_HEADER -# endif -#endif - - -#define CYGNUM_FILEIO_MTAB_MAX 16 - -//----------------------------------------------- -// stat.h need by fs-ecos.h -//----------------------------------------------- -#define __stat_mode_DIR (1<<0) -#define __stat_mode_CHR (1<<1) -#define __stat_mode_BLK (1<<2) -#define __stat_mode_REG (1<<3) -#define __stat_mode_FIFO (1<<4) -#define __stat_mode_MQ (1<<5) -#define __stat_mode_SEM (1<<6) -#define __stat_mode_SHM (1<<7) -#define __stat_mode_LNK (1<<8) -#define __stat_mode_SOCK (1<<9) - -#if defined(MSVC) -/* for time_t */ -#include <time.h> -typedef unsigned long mode_t; -typedef unsigned int ino_t; -typedef unsigned int dev_t; -typedef long ssize_t; -#elif defined(__CC_ARM) -#define mode_t unsigned long -typedef unsigned int ino_t; -typedef unsigned int dev_t; -typedef long ssize_t; -typedef long time_t; -#elif defined(__GNUC__) && !defined(__CC_ARM) -#include <sys/types.h> -#endif - -#endif /* CYGONCE_ISO_SYS_TYPES_H multiple inclusion protection */ - -/* EOF sys/types.h */ - diff --git a/components/dfs/filesystems/jffs2/include/port/sys/types.h b/components/dfs/filesystems/jffs2/include/port/sys/types.h deleted file mode 100644 index ab195a57ea..0000000000 --- a/components/dfs/filesystems/jffs2/include/port/sys/types.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef CYGONCE_ISO_SYS_TYPES_H -#define CYGONCE_ISO_SYS_TYPES_H -/*======================================================================== -// -// sys/types.h -// -// POSIX types -// -//======================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//======================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): jlarmour -// Contributors: -// Date: 2000-04-14 -// Purpose: This file provides various types required by POSIX 1003.1. -// Description: The real contents of this file get set from the -// configuration (set by the implementation) -// Usage: #include <sys/types.h> -// -//####DESCRIPTIONEND#### -// -//====================================================================== -*/ - -/* CONFIGURATION */ - -//#include <pkgconf/system.h> -//#include <pkgconf/isoinfra.h> /* Configuration header */ - -/* INCLUDES */ - -/* This is the "standard" way to get size_t from stddef.h, - * which is the canonical location of the definition. - */ -//#define __need_size_t -//#include <stddef.h> - -typedef long ssize_t; - -typedef short dev_t; -typedef unsigned int ino_t; -typedef unsigned short nlink_t; -typedef long off_t; - -typedef unsigned short gid_t; -typedef unsigned short uid_t; -typedef int pid_t; - -#if defined(MSVC) -#include <time.h> -#else -typedef int time_t; -#endif -//#include "os_sys_stat.h" -#endif /* CYGONCE_ISO_SYS_TYPES_H multiple inclusion protection */ - -/* EOF sys/types.h */ - diff --git a/components/dfs/filesystems/jffs2/jffs2_config.h b/components/dfs/filesystems/jffs2/jffs2_config.h deleted file mode 100644 index 3340f1ff17..0000000000 --- a/components/dfs/filesystems/jffs2/jffs2_config.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef JFFS2_CONFIG_H -#define JFFS2_CONFIG_H - -#define __ECOS /* must be defined */ - -#define FILE_PATH_MAX 128 /* the longest file path */ -#define CONFIG_JFFS2_ENTRY_NAME_MAX 23 -#define JFFS2_NAME_MAX CONFIG_JFFS2_ENTRY_NAME_MAX -#define JFFS2_PATH_MAX FILE_PATH_MAX - -#define DEVICE_PART_MAX 1 /* the max partions on a nand deivce*/ - -/* memory page size in kernel/asm/page.h, it is correspond with flash read/write - * option, so this size has a great impact on reading/writing speed */ -#define CONFIG_JFFS2_PAGE_SHIFT 12 /* (1<<12) 4096bytes*/ - -/* jffs2 support relative dir, command "ls" will get - * +-------------------------------+ - * | finsh>>ls("/") | - * | Directory /: | - * | . <DIR> | - * | .. <DIR> | - * | dir1 <DIR> | - * +-------------------------------+ - */ -#define CONFIG_JFFS2_NO_RELATIVEDIR - -//#define CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE -#if defined(CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE) - #define CYGPKG_FILEIO_DIRENT_DTYPE -#endif - -#define CYGOPT_FS_JFFS2_WRITE /* if not defined, jffs2 is read only*/ - -/* jffs2 debug output opion */ -#define CONFIG_JFFS2_FS_DEBUG 0 /* 1 or 2 */ - -/* jffs2 gc thread section */ -//#define CYGOPT_FS_JFFS2_GCTHREAD -#define CYGNUM_JFFS2_GC_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX-2) /* GC thread's priority */ -#define CYGNUM_JFFS2_GS_THREAD_TICKS 20 /* event timeout ticks */ -#define CYGNUM_JFFS2_GC_THREAD_TICKS 20 /* GC thread's running ticks */ - -//#define CONFIG_JFFS2_FS_WRITEBUFFER /* should not be enabled */ - -/* zlib section*/ -//#define CONFIG_JFFS2_ZLIB -//#define CONFIG_JFFS2_RTIME -//#define CONFIG_JFFS2_RUBIN -//#define CONFIG_JFFS2_CMODE_NONE -//#define CONFIG_JFFS2_CMODE_SIZE - -#endif diff --git a/components/dfs/filesystems/jffs2/kernel/asm/atomic.h b/components/dfs/filesystems/jffs2/kernel/asm/atomic.h deleted file mode 100644 index 5cb72ff8ce..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/asm/atomic.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef __ASM_ATOMIC_H__ -#define __ASM_ATOMIC_H__ - -#define atomic_t int -#define atomic_inc(atom) (*atom)++ -#define atomic_dec(atom) (*atom)-- -#define atomic_read(atom) (*atom) - - -#endif /* __ASM_ATOMIC_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/asm/bug.h b/components/dfs/filesystems/jffs2/kernel/asm/bug.h deleted file mode 100644 index 054dedc3d3..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/asm/bug.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_BUG_H__ -#define __ASM_BUG_H__ - -#define BUG() do { printf("BUG() at %s %d\n", __FILE__, __LINE__); *(int *)0=0; } while (0) - -#endif /* __ASM_BUG_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/asm/page.h b/components/dfs/filesystems/jffs2/kernel/asm/page.h deleted file mode 100644 index af3081164f..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/asm/page.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __ASM_PAGE_H__ -#define __ASM_PAGE_H__ - -//#include <pkgconf/linux_compat.h> //mod by prife -#include "jffs2_config.h" -#define PAGE_SHIFT CONFIG_JFFS2_PAGE_SHIFT -/* These aren't used by much yet. If that changes, you might want - to make them actually correct :) */ -#define PAGE_SIZE (0x1 << PAGE_SHIFT) - - -#endif /* __ASM_PAGE_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/asm/semaphore.h b/components/dfs/filesystems/jffs2/kernel/asm/semaphore.h deleted file mode 100644 index 94a4f3abd9..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/asm/semaphore.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef __ASM_SEMAPHORE_H__ -#define __ASM_SEMAPHORE_H__ - -#define CONFIG_JFFS2_SEMAPHORE 0 // no mutex, 1 use static, 2 use dynamic -#if CONFIG_JFFS2_SEMAPHORE == 0 -//#include <cyg/hal/drv_api.h> - -struct semaphore { - int x; -}; - -#define DECLARE_MUTEX(x) -#define DECLARE_MUTEX_LOCKED(x) - -#define init_MUTEX(sem) -#define init_MUTEX_LOCKED(sem) -#define down(sem) -#define down_interruptible(sem) 0 -#define down_trylock(sem) -#define up(sem) - -#elif CONFIG_JFFS2_SEMAPHORE == 1 -#include <rtthread.h> - -struct semaphore { - struct rt_mutex mutex; -}; - -#define DECLARE_MUTEX(x) -#define DECLARE_MUTEX_LOCKED(x) -rt_inline void init_MUTEX(struct semaphore * sem) -{ - if (rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO) == RT_EOK) - { - /* detach the object from system object container */ - rt_object_detach(&(((rt_mutex_t)sem)->parent.parent)); - return; - } - rt_kprintf("get an error at %s:%d \n", __FUNCTION__, __LINE__); - RT_ASSERT(0); -} - -rt_inline void init_MUTEX_LOCKED(struct semaphore * sem) -{ - rt_enter_critical(); - if (rt_mutex_init((rt_mutex_t)sem, "mutex", RT_IPC_FLAG_FIFO) == RT_EOK) - { - /* detach the object from system object container */ - rt_object_detach(&(((rt_mutex_t)sem)->parent.parent)); - rt_exit_critical(); - rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER); - return; - } - rt_exit_critical(); - - rt_kprintf("get an error at %s:%d \n", __FUNCTION__, __LINE__); - RT_ASSERT(0); -} - -rt_inline down(struct semaphore * sem) -{ - rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER); -} -rt_inline int down_interruptible(struct semaphore* sem) -{ - rt_mutex_take((rt_mutex_t)sem, RT_WAITING_FOREVER); - return 0; -} -rt_inline up(struct semaphore * sem) -{ - rt_mutex_release((rt_mutex_t)sem); -} -#elif CONFIG_JFFS2_SEMAPHORE == 2 - -#include <rtthread.h> - -struct semaphore { - rt_mutex_t mutex; -}; - -#define DECLARE_MUTEX(x) -#define DECLARE_MUTEX_LOCKED(x) - -rt_inline void init_MUTEX(struct semaphore * sem) -{ - sem->mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); -} -rt_inline init_MUTEX_LOCKED(struct semaphore * sem) -{ - sem->mutex = rt_mutex_create("mutex", RT_IPC_FLAG_FIFO); - rt_mutex_take(sem->mutex, RT_WAITING_FOREVER); -} -rt_inline down(struct semaphore * sem) -{ - rt_mutex_take(sem->mutex, RT_WAITING_FOREVER); -} -rt_inline int down_interruptible(struct semaphore* sem) -{ - rt_mutex_take(sem->mutex, RT_WAITING_FOREVER); - return 0; -} -/* -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 -returns FALSE. If the function can lock the mutex without waiting, then -TRUE is returned. -void cyg_drv_mutex_unlock( cyg_drv_mutex *mutex ) -*/ - -//#define down_trylock(struct semaphore * sem) rt_mutex_take((rt_mutex_t)sem, RT_WAITING_NO) -rt_inline up(struct semaphore * sem) -{ - rt_mutex_release(sem->mutex); -} - -#else -#error "CONFIG_JFFS2_SEMAPHORE should be 0, 1 or 2" -#endif - -#endif /* __ASM_SEMAPHORE_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/TODO b/components/dfs/filesystems/jffs2/kernel/linux/TODO deleted file mode 100644 index df8a6d1a51..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/TODO +++ /dev/null @@ -1,11 +0,0 @@ - -This contains a very limited set of Linux-compatibility headers, initially -just for getting JFFS2 to build. - -Some things are simply stubs which don't _work_, to allow the JFFS2 code -to compile. Note that you may need to implement these _properly_ in order -to use these for making other Linux code work, or indeed for making the -JFFS2 NAND support work. - -The non-working parts include, but are not limited to: - workqueue.h, wait.h, timer.h, spinlock.h, sched.h, compiler.h diff --git a/components/dfs/filesystems/jffs2/kernel/linux/compiler.h b/components/dfs/filesystems/jffs2/kernel/linux/compiler.h deleted file mode 100644 index fb253651a3..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/compiler.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __LINUX_COMPILER_H__ -#define __LINUX_COMPILER_H__ - -#define likely(x) (x) -#define unlikely(x) (x) - -#endif /* __LINUX_COMPILER_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/completion.h b/components/dfs/filesystems/jffs2/kernel/linux/completion.h deleted file mode 100644 index d2493b2710..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/completion.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __LINUX_COMPLETION_H__ -#define __LINUX_COMPLETION_H__ - -#if defined (__GNUC__) -struct completion { } ; -#elif defined (MSVC) -struct completion {int no; } ; -#else -#error "please use a right C compiler" -#endif - -#endif /* __LINUX_COMPLETION_H__ */ - diff --git a/components/dfs/filesystems/jffs2/kernel/linux/config.h b/components/dfs/filesystems/jffs2/kernel/linux/config.h deleted file mode 100644 index 355e175f65..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/config.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __LINUX_CONFIG_H__ -#define __LINUX_CONFIG_H__ - -#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__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/crc32.h b/components/dfs/filesystems/jffs2/kernel/linux/crc32.h deleted file mode 100644 index 8d19a1eb62..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/crc32.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef CRC32_H -#define CRC32_H - -#include <cyg/crc/crc.h> - -#define crc32(val, s, len) cyg_crc32_accumulate(val, (unsigned char *)s, len) - -#endif diff --git a/components/dfs/filesystems/jffs2/kernel/linux/errno.h b/components/dfs/filesystems/jffs2/kernel/linux/errno.h deleted file mode 100644 index 2938632411..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/errno.h +++ /dev/null @@ -1,2 +0,0 @@ -//#include <errno.h> -#include "port/codes.h" //fixme diff --git a/components/dfs/filesystems/jffs2/kernel/linux/fs.h b/components/dfs/filesystems/jffs2/kernel/linux/fs.h deleted file mode 100644 index 94f493c91a..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/fs.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_FS_H__ -#define __LINUX_FS_H__ - -#include <linux/stat.h> - -#endif /* __LINUX_FS_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/init.h b/components/dfs/filesystems/jffs2/kernel/linux/init.h deleted file mode 100644 index e4c702f996..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/init.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef __LINUX_INIT_H__ -#define __LINUX_INIT_H__ -#endif diff --git a/components/dfs/filesystems/jffs2/kernel/linux/kernel.h b/components/dfs/filesystems/jffs2/kernel/linux/kernel.h deleted file mode 100644 index a0c94a1996..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/kernel.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef __LINUX_KERNEL_H__ -#define __LINUX_KERNEL_H__ -//#include <cyg/infra/diag.h> -//#include <stdio.h> //mod by prife @ 2011/11/20 -#include "jffs2_config.h" - -#define jiffies 100 - -#define ERR_PTR(err) ((void*)(err)) -#define PTR_ERR(err) ((unsigned long)(err)) -#define IS_ERR(err) ((unsigned long)err > (unsigned long)-1000L) - -#define CURRENT_TIME jffs2_get_timestamp() - -#define KERN_EMERG "<0>" // system is unusable -#define KERN_ALERT "<1>" // action must be taken immediately -#define KERN_CRIT "<2>" // critical conditions -#define KERN_ERR "<3>" // error conditions -#define KERN_WARNING "<4>" // warning conditions -#define KERN_NOTICE "<5>" // normal but significant condition -#define KERN_INFO "<6>" // informational -#define KERN_DEBUG "<7>" // debug-level messages -#define printk rt_kprintf//diag_printf //mod by prife - -#ifndef min //mod by prife -#define min(x,y) (x<y?x:y) -#endif -#ifndef max -#define max(x,y) (x<y?y:x) -#endif -#define min_t(t, x,y) ((t)x<(t)y?(t)x:(t)y) - - -#endif /* __LINUX_KERNEL_H__ */ - - - - diff --git a/components/dfs/filesystems/jffs2/kernel/linux/list.h b/components/dfs/filesystems/jffs2/kernel/linux/list.h deleted file mode 100644 index 03c7b39cca..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/list.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * - * Created by Jonathan Larmour <[email protected]> - * - *=========================================================================== - * ####ECOSGPLCOPYRIGHTBEGIN#### - * ------------------------------------------- - * This file is part of eCos, the Embedded Configurable Operating System. - * Copyright (C) 2002, 2003 Free Software Foundation, Inc. - * - * eCos is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 or (at your option) any later - * version. - * - * eCos is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with eCos; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * As a special exception, if other files instantiate templates or use - * macros or inline functions from this file, or you compile this file - * and link it with other works to produce a work based on this file, - * this file does not by itself cause the resulting work to be covered by - * the GNU General Public License. However the source code for this file - * must still be made available in accordance with section (3) of the GNU - * General Public License v2. - * - * This exception does not invalidate any other reasons why a work based - * on this file might be covered by the GNU General Public License. - * ------------------------------------------- - * ####ECOSGPLCOPYRIGHTEND#### - *=========================================================================== - * - */ - -#ifndef CYGONCE_FS_JFFS2_LIST_H -#define CYGONCE_FS_JFFS2_LIST_H - - -/* -----------------------------------------------------------------------*/ - -/* Doubly linked list implementation to replace the GPL'd one used in - the Linux kernel. */ - -#include <stddef.h> -#include <cyg/infra/cyg_type.h> - -/* TYPES */ - -struct list_head { - struct list_head *next; - struct list_head *prev; -}; - -/* MACROS */ - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -#define INIT_LIST_HEAD( _list_ ) \ -CYG_MACRO_START \ -(_list_)->next = (_list_)->prev = (_list_); \ -CYG_MACRO_END - -/* FUNCTIONS */ - -/* Insert an entry _after_ the specified entry */ -static __inline__ void -list_add( struct list_head *newent, struct list_head *afterthisent ) -{ - struct list_head *next = afterthisent->next; - newent->next = next; - newent->prev = afterthisent; - afterthisent->next = newent; - next->prev = newent; -} /* list_add() */ - -/* Insert an entry _before_ the specified entry */ -static __inline__ void -list_add_tail( struct list_head *newent, struct list_head *beforethisent ) -{ - struct list_head *prev = beforethisent->prev; - newent->prev = prev; - newent->next = beforethisent; - beforethisent->prev = newent; - prev->next = newent; -} /* list_add_tail() */ - -/* Delete the specified entry */ -static __inline__ void -list_del( struct list_head *ent ) -{ - ent->prev->next = ent->next; - ent->next->prev = ent->prev; -} /* list_del() */ - -/* Is this list empty? */ -static __inline__ int -list_empty( struct list_head *list ) -{ - return ( list->next == list ); -} /* list_empty() */ - -/* list_entry - Assuming you have a struct of type _type_ that contains a - list which has the name _member_ in that struct type, then given the - address of that list in the struct, _list_, this returns the address - of the container structure */ - -#define list_entry( _list_, _type_, _member_ ) \ - ((_type_ *)((char *)(_list_)-(char *)(offsetof(_type_,_member_)))) - -/* list_for_each - using _ent_, iterate through list _list_ */ - -#define list_for_each( _ent_, _list_ ) \ - for ( (_ent_) = (_list_)->next; \ - (_ent_) != (_list_); \ - (_ent_) = (_ent_)->next ) - -/* - * list_for_each_entry - this function can be use to iterate over all - * items in a list* _list_ with it's head at _head_ and link _item_ - */ -#if defined (__GNUC__) -#define list_for_each_entry(_list_, _head_, _item_) \ -for ((_list_) = list_entry((_head_)->next, typeof(*_list_), _item_); \ - &((_list_)->_item_) != (_head_); \ - (_list_) = list_entry((_list_)->_item_.next, typeof(*_list_), _item_)) - -#elif defined (MSVC) -#define list_for_each_entry(_list_, _head_, _item_) \ -for ((_list_) = list_entry((_head_)->next, struct jffs2_compressor, _item_); \ - &((_list_)->_item_) != (_head_); \ - (_list_) = list_entry((_list_)->_item_.next, struct jffs2_compressor, _item_)) -#else -#endif -/* -----------------------------------------------------------------------*/ -#endif /* #ifndef CYGONCE_FS_JFFS2_LIST_H */ -/* EOF list.h */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/mtd/compatmac.h b/components/dfs/filesystems/jffs2/kernel/linux/mtd/compatmac.h deleted file mode 100644 index cee3749250..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/mtd/compatmac.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __LINUX_MTD_COMPATMAC_H__ -#define __LINUX_MTD_COMPATMAC_H__ - - -#endif /* __LINUX_MTD_COMPATMAC_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/mtd/mtd.h b/components/dfs/filesystems/jffs2/kernel/linux/mtd/mtd.h deleted file mode 100644 index 817d31cf6f..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/mtd/mtd.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __LINUX_MTD_MTD_H__ -#define __LINUX_MTD_MTD_H__ - - -#endif /* __LINUX_MTD_MTD_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/pagemap.h b/components/dfs/filesystems/jffs2/kernel/linux/pagemap.h deleted file mode 100644 index fccf9c4061..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/pagemap.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __LINUX_PAGEMAP_H__ -#define __LINUX_PAGEMAP_H__ - -#include <asm/bug.h> -#include <asm/page.h> - -#define PAGE_CACHE_SHIFT PAGE_SHIFT -#define PAGE_CACHE_SIZE PAGE_SIZE - -#define PageLocked(pg) 1 -#define Page_Uptodate(pg) 0 -#define UnlockPage(pg) -#define PAGE_BUG(pg) BUG() -#define ClearPageUptodate(pg) -#define SetPageError(pg) -#define ClearPageError(pg) -#define SetPageUptodate(pg) - -#endif /* __LINUX_PAGEMAP_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/rbtree.h b/components/dfs/filesystems/jffs2/kernel/linux/rbtree.h deleted file mode 100644 index ffda277e88..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/rbtree.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _LINUX_RBTREE_H -#define _LINUX_RBTREE_H - -#if defined (__GNUC__) -#elif defined (MSVC) -#define __inline__ __inline -#define inline __inline -#else -#endif - -struct rb_node { - struct rb_node *rb_left; /* left element */ - struct rb_node *rb_right; /* right element */ - struct rb_node *rb_parent; /* parent element */ - int rb_color; /* node color */ -}; - -struct rb_root { - struct rb_node *rb_node; /* root of the tree */ -}; - -#ifndef NULL -#define NULL ((void *)0) -#endif - -#if defined (__GNUC__) -#define RB_ROOT ((struct rb_root){NULL}) -#elif defined (MSVC) -#define RB_ROOT {NULL}//{struct rb_root _x = {NULL};} -#else -#endif - -#define rb_entry(p, container, field) \ - ((container *) ((char *)p - ((char *)&(((container *)0)->field)))) - -#define RB_BLACK 0 -#define RB_RED 1 - - -extern void rb_insert_color(struct rb_node *, struct rb_root *); -extern void rb_erase(struct rb_node *, struct rb_root *); - -/* Find logical next and previous nodes in a tree */ -extern struct rb_node *rb_next(struct rb_node *); -extern struct rb_node *rb_prev(struct rb_node *); -extern struct rb_node *rb_first(struct rb_root *); - -/* Fast replacement of a single node without remove/rebalance/add/rebalance */ -extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, - struct rb_root *root); - -static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, - struct rb_node ** rb_link) -{ - node->rb_parent = parent; - node->rb_color = RB_RED; - node->rb_left = node->rb_right = NULL; - - *rb_link = node; -} - -#endif /* _LINUX_RBTREE_H */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/rwsem.h b/components/dfs/filesystems/jffs2/kernel/linux/rwsem.h deleted file mode 100644 index d648a150ca..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/rwsem.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __LINUX_RWSEM_H__ -#define __LINUX_RWSEM_H__ - -// eCos does not have the concept of a read/write semaphore. So just -// map them onto normal semaphores and hope we don't deadlock -// somewhere. - -#include <asm/semaphore.h> - -struct rw_semaphore; - -#define down_read(sem) cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem) -#define down_read_trylock(sem) cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem) -#define down_write(sem) cyg_drv_mutex_lock((cyg_drv_mutex_t *)sem) -#define down_write_trylock(sem) cyg_drv_mutex_trylock((cyg_drv_mutex_t *)sem) -#define up_read(sem) cyg_drv_mutex_unlock((cyg_drv_mutex_t *)sem) -#define up_write(sem) cyg_drv_mutex_unlock((cyg_drv_mutex_t *)sem) -#define downgrade_write(sem) - -#endif // __LINUX_RWSEM_H__ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/sched.h b/components/dfs/filesystems/jffs2/kernel/linux/sched.h deleted file mode 100644 index 14a7359754..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/sched.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __LINUX_SCHED_H__ -#define __LINUX_SCHED_H__ - -#define cond_resched() do { } while(0) -#define signal_pending(x) (0) - -#endif /* __LINUX_SCHED_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/slab.h b/components/dfs/filesystems/jffs2/kernel/linux/slab.h deleted file mode 100644 index f5c5745b0e..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/slab.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __LINUX_SLAB_H__ -#define __LINUX_SLAB_H__ - -//#include <stdlib.h> //prife - -#include <asm/page.h> /* Don't ask. Linux headers are a mess. */ - -#define kmalloc(x, y) rt_malloc(x) -#define kfree(x) rt_free(x) -#define vmalloc(x) rt_malloc(x) -#define vfree(x) rt_free(x) - -#endif /* __LINUX_SLAB_H__ */ - diff --git a/components/dfs/filesystems/jffs2/kernel/linux/spinlock.h b/components/dfs/filesystems/jffs2/kernel/linux/spinlock.h deleted file mode 100644 index db3f4d4502..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/spinlock.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef __LINUX_SPINLOCK_H__ -#define __LINUX_SPINLOCK_H__ - -#if defined (__GNUC__) -typedef struct { } spinlock_t; - -#define SPIN_LOCK_UNLOCKED (spinlock_t) { } -#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED -#elif defined (MSVC) -typedef struct {int no; } spinlock_t; - -#define SPIN_LOCK_UNLOCKED (spinlock_t) ( 0) -#define DEFINE_SPINLOCK(x) spinlock_t x -#else -#error "please use a right C compiler" -#endif - -#define spin_lock_init(lock) \ -CYG_MACRO_START; \ -CYG_UNUSED_PARAM(spinlock_t *, lock); \ -CYG_MACRO_END - -#define spin_lock(lock) \ -CYG_MACRO_START; \ -CYG_UNUSED_PARAM(spinlock_t *, lock); \ -CYG_MACRO_END - -#define spin_unlock(lock) \ -CYG_MACRO_START; \ -CYG_UNUSED_PARAM(spinlock_t *, lock); \ -CYG_MACRO_END - -#define spin_lock_bh(lock) \ -CYG_MACRO_START; \ -CYG_UNUSED_PARAM(spinlock_t *, lock); \ -CYG_MACRO_END - -#define spin_unlock_bh(lock) \ -CYG_MACRO_START; \ -CYG_UNUSED_PARAM(spinlock_t *, lock); \ -CYG_MACRO_END - -#endif /* __LINUX_SPINLOCK_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/stat.h b/components/dfs/filesystems/jffs2/kernel/linux/stat.h deleted file mode 100644 index 8c79205229..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/stat.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef __LINUX_STAT_H__ -#define __LINUX_STAT_H__ - - -#include "port/sys/stat.h" //mod by prife - -#define S_IRUGO (S_IRUSR|S_IRGRP|S_IROTH) -#define S_IWUGO (S_IWUSR|S_IWGRP|S_IWOTH) -#define S_IXUGO (S_IXUSR|S_IXGRP|S_IXOTH) -#define S_IRWXUGO (S_IRWXU|S_IRWXG|S_IRWXO) - -#endif /* __LINUX_STAT_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/string.h b/components/dfs/filesystems/jffs2/kernel/linux/string.h deleted file mode 100644 index fc14ba607f..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/string.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_STRING_H__ -#define __LINUX_STRING_H__ - -#include <string.h> - -#endif /* __LINUX_STRING_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/timer.h b/components/dfs/filesystems/jffs2/kernel/linux/timer.h deleted file mode 100644 index d6f91a68bc..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/timer.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __LINUX_TIMER_H__ -#define __LINUX_TIMER_H__ - -/* Not yet */ - -#if defined (__GNUC__) -struct timer_list { } ; -#elif defined (MSVC) -struct timer_list {int no; } ; -#else -#error "please use a right C compiler" -#endif - -#endif /* __LINUX_TIMER_H__ */ - diff --git a/components/dfs/filesystems/jffs2/kernel/linux/types.h b/components/dfs/filesystems/jffs2/kernel/linux/types.h deleted file mode 100644 index bfa09c14c0..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/types.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef __LINUX_TYPES_H__ -#define __LINUX_TYPES_H__ - -#include "cyg/infra/cyg_type.h" - -#define loff_t off_t - -#define kvec iovec -#endif /* __LINUX_TYPES_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/version.h b/components/dfs/filesystems/jffs2/kernel/linux/version.h deleted file mode 100644 index cd3a45aa38..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/version.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_VERSION_H__ -#define __LINUX_VERSION_H__ - -#include <rtthread.h> - -#endif /* __LINUX_VERSION_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/vmalloc.h b/components/dfs/filesystems/jffs2/kernel/linux/vmalloc.h deleted file mode 100644 index 6f18ab2255..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/vmalloc.h +++ /dev/null @@ -1,3 +0,0 @@ -#ifndef __LINUX_VMALLOC_H__ -#define __LINUX_VMALLOC_H__ -#endif diff --git a/components/dfs/filesystems/jffs2/kernel/linux/wait.h b/components/dfs/filesystems/jffs2/kernel/linux/wait.h deleted file mode 100644 index db3fd7a608..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/wait.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __LINUX_WAIT_H__ -#define __LINUX_WAIT_H__ - - -#if defined (__GNUC__) -typedef struct { } wait_queue_head_t; -#elif defined (MSVC) -typedef struct {int no; } wait_queue_head_t; -#else -#error "please use a right C compiler" -#endif - -#define init_waitqueue_head(wait) do{} while (0) -#define add_wait_queue(wait,new_wait) do{} while (0) -#define remove_wait_queue(wait,old_wait) do{} while (0) -#define DECLARE_WAITQUEUE(wait,current) do{} while (0) - -static inline void wake_up(wait_queue_head_t *erase_wait) -{ /* Only used for waking up threads blocks on erases. Not used in eCos */ } - -#endif /* __LINUX_WAIT_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/workqueue.h b/components/dfs/filesystems/jffs2/kernel/linux/workqueue.h deleted file mode 100644 index 8b334d5593..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/workqueue.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __LINUX_WORKQUEUE_H__ -#define __LINUX_WORKQUEUE_H__ - -/* We don't do this yet */ -#if defined (__GNUC__) -struct work_struct { } ; -#elif defined (MSVC) -struct work_struct {int no; } ; -#else -#error "please use a right C compiler" -#endif - - -#define INIT_WORK(x,y,z) /* */ -#define schedule_work(x) do { } while(0) -#define flush_scheduled_work() do { } while(0) - -#endif /* __LINUX_WORKQUEUE_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/zlib.h b/components/dfs/filesystems/jffs2/kernel/linux/zlib.h deleted file mode 100644 index 4c32b68c9c..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/zlib.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __LINUX_ZLIB_H__ -#define __LINUX_ZLIB_H__ - -#include <cyg/compress/zlib.h> - -#define zlib_deflateInit(x,y) deflateInit(x,y) -#define zlib_deflate(x,y) deflate(x,y) -#define zlib_deflateEnd(x) deflateEnd(x) -#define zlib_inflateInit(x) inflateInit(x) -#define zlib_inflateInit2(x,y) inflateInit2(x,y) -#define zlib_inflate(x,y) inflate(x,y) -#define zlib_inflateEnd(x) inflateEnd(x) - - -#endif /* __LINUX_ZLIB_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/linux/zutil.h b/components/dfs/filesystems/jffs2/kernel/linux/zutil.h deleted file mode 100644 index c3774baf9e..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/linux/zutil.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __LINUX_ZUTIL_H__ -#define __LINUX_ZUTIL_H__ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - -#endif /* __LINUX_ZUTIL_H__ */ diff --git a/components/dfs/filesystems/jffs2/kernel/rbtree.c b/components/dfs/filesystems/jffs2/kernel/rbtree.c deleted file mode 100644 index 5bc1cc53e2..0000000000 --- a/components/dfs/filesystems/jffs2/kernel/rbtree.c +++ /dev/null @@ -1,408 +0,0 @@ -/*======================================================================== -// -// rbtree.c -// -// Red Black tree implementation -// -//======================================================================== -// ####ECOSGPLCOPYRIGHTBEGIN#### -// ------------------------------------------- -// This file is part of eCos, the Embedded Configurable Operating System. -// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. -// -// eCos is free software; you can redistribute it and/or modify it under -// the terms of the GNU General Public License as published by the Free -// Software Foundation; either version 2 or (at your option) any later -// version. -// -// eCos is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -// for more details. -// -// You should have received a copy of the GNU General Public License -// along with eCos; if not, write to the Free Software Foundation, Inc., -// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -// -// As a special exception, if other files instantiate templates or use -// macros or inline functions from this file, or you compile this file -// and link it with other works to produce a work based on this file, -// this file does not by itself cause the resulting work to be covered by -// the GNU General Public License. However the source code for this file -// must still be made available in accordance with section (3) of the GNU -// General Public License v2. -// -// This exception does not invalidate any other reasons why a work based -// on this file might be covered by the GNU General Public License. -// ------------------------------------------- -// ####ECOSGPLCOPYRIGHTEND#### -//======================================================================== -//#####DESCRIPTIONBEGIN#### -// -// Author(s): Niels Provos/OpenBSD -// Contributors: dwmw2 -// Date: 2003-01-21 -// Purpose: This file provides an implementation of red-black trees. -// Description: Derived from OpenBSD src/sys/sys/tree.h -// Usage: -// -//####DESCRIPTIONEND#### -// -//====================================================================== -*/ - -/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ -/* - * Copyright 2002 Niels Provos <[email protected]> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Fields renamed to match Linux ones. */ -#include <linux/rbtree.h> - - -#define RB_HEAD(head) (head)->rb_node -#define RB_LEFT(elm) (elm)->rb_left -#define RB_RIGHT(elm) (elm)->rb_right -#define RB_PARENT(elm) (elm)->rb_parent -#define RB_COLOR(elm) (elm)->rb_color - - -#define RB_SET(elm, parent) do { \ - RB_PARENT(elm) = parent; \ - RB_LEFT(elm) = RB_RIGHT(elm) = NULL; \ - RB_COLOR(elm) = RB_RED; \ -} while (0) - -#define RB_SET_BLACKRED(black, red) do { \ - RB_COLOR(black) = RB_BLACK; \ - RB_COLOR(red) = RB_RED; \ -} while (0) - -#ifndef RB_AUGMENT -#define RB_AUGMENT(x) -#endif - -#define RB_ROTATE_LEFT(head, elm, tmp) do { \ - (tmp) = RB_RIGHT(elm); \ - if ((RB_RIGHT(elm) = RB_LEFT(tmp))) { \ - RB_PARENT(RB_LEFT(tmp)) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp) = RB_PARENT(elm))) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm))) \ - RB_LEFT(RB_PARENT(elm)) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm)) = (tmp); \ - } else \ - (head)->rb_node = (tmp); \ - RB_LEFT(tmp) = (elm); \ - RB_PARENT(elm) = (tmp); \ - RB_AUGMENT(tmp); \ - if ((RB_PARENT(tmp))) \ - RB_AUGMENT(RB_PARENT(tmp)); \ -} while (0) - -#define RB_ROTATE_RIGHT(head, elm, tmp) do { \ - (tmp) = RB_LEFT(elm); \ - if ((RB_LEFT(elm) = RB_RIGHT(tmp))) { \ - RB_PARENT(RB_RIGHT(tmp)) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp) = RB_PARENT(elm))) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm))) \ - RB_LEFT(RB_PARENT(elm)) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm)) = (tmp); \ - } else \ - (head)->rb_node = (tmp); \ - RB_RIGHT(tmp) = (elm); \ - RB_PARENT(elm) = (tmp); \ - RB_AUGMENT(tmp); \ - if ((RB_PARENT(tmp))) \ - RB_AUGMENT(RB_PARENT(tmp)); \ -} while(0) - -/* Note args swapped to match Linux */ -void rb_insert_color(struct rb_node *elm, struct rb_root *head) -{ - struct rb_node *parent, *gparent, *tmp; - while ((parent = RB_PARENT(elm)) && - RB_COLOR(parent) == RB_RED) { - gparent = RB_PARENT(parent); - if (parent == RB_LEFT(gparent)) { - tmp = RB_RIGHT(gparent); - if (tmp && RB_COLOR(tmp) == RB_RED) { - RB_COLOR(tmp) = RB_BLACK; - RB_SET_BLACKRED(parent, gparent); - elm = gparent; - continue; - } - if (RB_RIGHT(parent) == elm) { - RB_ROTATE_LEFT(head, parent, tmp); - tmp = parent; - parent = elm; - elm = tmp; - } - RB_SET_BLACKRED(parent, gparent); - RB_ROTATE_RIGHT(head, gparent, tmp); - } else { - tmp = RB_LEFT(gparent); - if (tmp && RB_COLOR(tmp) == RB_RED) { - RB_COLOR(tmp) = RB_BLACK; - RB_SET_BLACKRED(parent, gparent); - elm = gparent; - continue; - } - if (RB_LEFT(parent) == elm) { - RB_ROTATE_RIGHT(head, parent, tmp); - tmp = parent; - parent = elm; - elm = tmp; - } - RB_SET_BLACKRED(parent, gparent); - RB_ROTATE_LEFT(head, gparent, tmp); - } - } - RB_COLOR(head->rb_node) = RB_BLACK; -} - - -static void rb_remove_color(struct rb_root *head, struct rb_node *parent, - struct rb_node *elm) -{ - struct rb_node *tmp; - while ((elm == NULL || RB_COLOR(elm) == RB_BLACK) && - elm != RB_HEAD(head)) { - if (RB_LEFT(parent) == elm) { - tmp = RB_RIGHT(parent); - if (RB_COLOR(tmp) == RB_RED) { - RB_SET_BLACKRED(tmp, parent); - RB_ROTATE_LEFT(head, parent, tmp); - tmp = RB_RIGHT(parent); - } - if ((RB_LEFT(tmp) == NULL || - RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) && - (RB_RIGHT(tmp) == NULL || - RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) { - RB_COLOR(tmp) = RB_RED; - elm = parent; - parent = RB_PARENT(elm); - } else { - if (RB_RIGHT(tmp) == NULL || - RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK) { - struct rb_node *oleft; - if ((oleft = RB_LEFT(tmp))) - RB_COLOR(oleft) = RB_BLACK; - RB_COLOR(tmp) = RB_RED; - RB_ROTATE_RIGHT(head, tmp, oleft); - tmp = RB_RIGHT(parent); - } - RB_COLOR(tmp) = RB_COLOR(parent); - RB_COLOR(parent) = RB_BLACK; - if (RB_RIGHT(tmp)) - RB_COLOR(RB_RIGHT(tmp)) = RB_BLACK; - RB_ROTATE_LEFT(head, parent, tmp); - elm = RB_HEAD(head); - break; - } - } else { - tmp = RB_LEFT(parent); - if (RB_COLOR(tmp) == RB_RED) { - RB_SET_BLACKRED(tmp, parent); - RB_ROTATE_RIGHT(head, parent, tmp); - tmp = RB_LEFT(parent); - } - if ((RB_LEFT(tmp) == NULL || - RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) && - (RB_RIGHT(tmp) == NULL || - RB_COLOR(RB_RIGHT(tmp)) == RB_BLACK)) { - RB_COLOR(tmp) = RB_RED; - elm = parent; - parent = RB_PARENT(elm); - } else { - if (RB_LEFT(tmp) == NULL || - RB_COLOR(RB_LEFT(tmp)) == RB_BLACK) { - struct rb_node *oright; - if ((oright = RB_RIGHT(tmp))) - RB_COLOR(oright) = RB_BLACK; - RB_COLOR(tmp) = RB_RED; - RB_ROTATE_LEFT(head, tmp, oright); - tmp = RB_LEFT(parent); - } - RB_COLOR(tmp) = RB_COLOR(parent); - RB_COLOR(parent) = RB_BLACK; - if (RB_LEFT(tmp)) - RB_COLOR(RB_LEFT(tmp)) = RB_BLACK; - RB_ROTATE_RIGHT(head, parent, tmp); - elm = RB_HEAD(head); - break; - } - } - } - if (elm) - RB_COLOR(elm) = RB_BLACK; -} - -/* Note name changed. Guess why :) */ -void rb_erase(struct rb_node *elm, struct rb_root *head) -{ - struct rb_node *child, *parent, *old = elm; - int color; - if (RB_LEFT(elm) == NULL) - child = RB_RIGHT(elm); - else if (RB_RIGHT(elm) == NULL) - child = RB_LEFT(elm); - else { - struct rb_node *left; - elm = RB_RIGHT(elm); - while ((left = RB_LEFT(elm))) - elm = left; - child = RB_RIGHT(elm); - parent = RB_PARENT(elm); - color = RB_COLOR(elm); - if (child) - RB_PARENT(child) = parent; - if (parent) { - if (RB_LEFT(parent) == elm) - RB_LEFT(parent) = child; - else - RB_RIGHT(parent) = child; - RB_AUGMENT(parent); - } else - RB_HEAD(head) = child; - if (RB_PARENT(elm) == old) - parent = elm; - *(elm) = *(old); - if (RB_PARENT(old)) { - if (RB_LEFT(RB_PARENT(old)) == old) - RB_LEFT(RB_PARENT(old)) = elm; - else - RB_RIGHT(RB_PARENT(old)) = elm; - RB_AUGMENT(RB_PARENT(old)); - } else - RB_HEAD(head) = elm; - RB_PARENT(RB_LEFT(old)) = elm; - if (RB_RIGHT(old)) - RB_PARENT(RB_RIGHT(old)) = elm; - if (parent) { - left = parent; - do { - RB_AUGMENT(left); - } while ((left = RB_PARENT(left))); - } - goto color; - } - parent = RB_PARENT(elm); - color = RB_COLOR(elm); - if (child) - RB_PARENT(child) = parent; - if (parent) { - if (RB_LEFT(parent) == elm) - RB_LEFT(parent) = child; - else - RB_RIGHT(parent) = child; - RB_AUGMENT(parent); - } else - RB_HEAD(head) = child; -color: - if (color == RB_BLACK) - rb_remove_color(head, parent, child); -} - -struct rb_node *rb_next(struct rb_node *elm) -{ - if (RB_RIGHT(elm)) { - elm = RB_RIGHT(elm); - while (RB_LEFT(elm)) - elm = RB_LEFT(elm); - } else { - if (RB_PARENT(elm) && - (elm == RB_LEFT(RB_PARENT(elm)))) - elm = RB_PARENT(elm); - else { - while (RB_PARENT(elm) && - (elm == RB_RIGHT(RB_PARENT(elm)))) - elm = RB_PARENT(elm); - elm = RB_PARENT(elm); - } - } - return (elm); -} - -struct rb_node *rb_prev(struct rb_node *elm) -{ - if (RB_LEFT(elm)) { - elm = RB_LEFT(elm); - while (RB_RIGHT(elm)) - elm = RB_RIGHT(elm); - } else { - if (RB_PARENT(elm) && - (elm == RB_RIGHT(RB_PARENT(elm)))) - elm = RB_PARENT(elm); - else { - while (RB_PARENT(elm) && - (elm == RB_LEFT(RB_PARENT(elm)))) - elm = RB_PARENT(elm); - elm = RB_PARENT(elm); - } - } - return (elm); -} - -/* These ones are lifted from Linux -- but that's OK because I - wrote them. dwmw2. */ -struct rb_node *rb_first(struct rb_root *root) -{ - struct rb_node *n; - - n = root->rb_node; - if (!n) - return 0; - while (n->rb_left) - n = n->rb_left; - return n; -} - -void rb_replace_node(struct rb_node *victim, struct rb_node *new, - struct rb_root *root) -{ - struct rb_node *parent = victim->rb_parent; - - /* Set the surrounding nodes to point to the replacement */ - if (parent) { - if (victim == parent->rb_left) - parent->rb_left = new; - else - parent->rb_right = new; - } else { - root->rb_node = new; - } - if (victim->rb_left) - victim->rb_left->rb_parent = new; - if (victim->rb_right) - victim->rb_right->rb_parent = new; - - /* Copy the pointers/colour from the victim to the replacement */ - *new = *victim; -} diff --git a/components/dfs/filesystems/jffs2/porting.c b/components/dfs/filesystems/jffs2/porting.c deleted file mode 100644 index 81290bdc32..0000000000 --- a/components/dfs/filesystems/jffs2/porting.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <linux/kernel.h> -#include "nodelist.h" - -#include "porting.h" - -time_t jffs2_get_timestamp(void) -{ - return 0; -} - -void jffs2_get_info_from_sb(void * data, struct jffs2_fs_info * info) -{ - struct jffs2_fs_info; - struct super_block *jffs2_sb; - struct jffs2_sb_info *c; - - jffs2_sb = (struct super_block *)(data); - c = JFFS2_SB_INFO(jffs2_sb); - - info->sector_size = c->sector_size; - info->nr_blocks = c->nr_blocks; - info->free_size = c->free_size + c->dirty_size; //fixme need test! -} - -int jffs2_porting_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - void * stat_buf) -{ - return jffs2_fste.stat(mte, mte->root, name, (struct stat *)stat_buf); -} diff --git a/components/dfs/filesystems/jffs2/porting.h b/components/dfs/filesystems/jffs2/porting.h deleted file mode 100644 index 2671f46dde..0000000000 --- a/components/dfs/filesystems/jffs2/porting.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _PORTING_H -#define _PORTING_H - -#include "jffs2_config.h" -/* the following should be same with os_sys_stat.h */ -#define JFFS2_S_IFMT 0x000003FF -#define JFFS2_S_IFDIR (1<<0) -#define JFFS2_S_IFREG (1<<3) - -struct jffs2_fs_info -{ - unsigned sector_size; /* a erasing block size*/ - unsigned nr_blocks; /* number of blocks in flash */ - unsigned free_size; -}; - -struct jffs2_stat { - unsigned long st_mode; /* File mode */ - unsigned int st_ino; /* File serial number */ - unsigned int st_dev; /* ID of device containing file */ - unsigned short st_nlink; /* Number of hard links */ - unsigned short st_uid; /* User ID of the file owner */ - unsigned short st_gid; /* Group ID of the file's group */ - long st_size; /* File size (regular files only) */ - long st_atime; /* Last access time */ - long st_mtime; /* Last data modification time */ - long st_ctime; /* Last file status change time */ -}; - -struct jffs2_dirent -{ -#ifdef CYGPKG_FILEIO_DIRENT_DTYPE - - unsigned long 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[JFFS2_NAME_MAX+1]; -}; - -extern cyg_fileops jffs2_fileops; -extern cyg_fileops jffs2_dirops; -extern struct cyg_fstab_entry jffs2_fste; - -time_t jffs2_get_timestamp(void); -void jffs2_get_info_from_sb(void * data, struct jffs2_fs_info * info); -int jffs2_porting_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - void * stat_buf); - -#endif diff --git a/components/dfs/filesystems/jffs2/src/LICENCE b/components/dfs/filesystems/jffs2/src/LICENCE deleted file mode 100644 index f3f9a6f6ec..0000000000 --- a/components/dfs/filesystems/jffs2/src/LICENCE +++ /dev/null @@ -1,35 +0,0 @@ -The files in this directory and elsewhere which refer to this LICENCE -file are part of JFFS2, the Journalling Flash File System v2. - - Copyright (C) 2001-2003 Red Hat, Inc. - -JFFS2 is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free -Software Foundation; either version 2 or (at your option) any later -version. - -JFFS2 is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received a copy of the GNU General Public License along -with JFFS2; if not, write to the Free Software Foundation, Inc., -59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. - -As a special exception, if other files instantiate templates or use -macros or inline functions from these files, or you compile these -files and link them with other works to produce a work based on these -files, these files do not by themselves cause the resulting work to be -covered by the GNU General Public License. However the source code for -these files must still be made available in accordance with section (3) -of the GNU General Public License. - -This exception does not invalidate any other reasons why a work based on -this file might be covered by the GNU General Public License. - -For information on obtaining alternative licences for JFFS2, see -http://sources.redhat.com/jffs2/jffs2-licence.html - - - $Id: LICENCE,v 1.2 2003/10/04 08:33:05 dwmw2 Exp $ diff --git a/components/dfs/filesystems/jffs2/src/build.c b/components/dfs/filesystems/jffs2/src/build.c deleted file mode 100644 index 158b01a829..0000000000 --- a/components/dfs/filesystems/jffs2/src/build.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: build.c,v 1.75 2005/07/22 10:32:07 dedekind Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> -#include <linux/mtd/mtd.h> -#include "nodelist.h" - -static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *, struct jffs2_inode_cache *, struct jffs2_full_dirent **); - -static inline struct jffs2_inode_cache * -first_inode_chain(int *i, struct jffs2_sb_info *c) -{ - for (; *i < INOCACHE_HASHSIZE; (*i)++) { - if (c->inocache_list[*i]) - return c->inocache_list[*i]; - } - return NULL; -} - -static inline struct jffs2_inode_cache * -next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c) -{ - /* More in this chain? */ - if (ic->next) - return ic->next; - (*i)++; - return first_inode_chain(i, c); -} - -#define for_each_inode(i, c, ic) \ - for (i = 0, ic = first_inode_chain(&i, (c)); \ - ic; \ - ic = next_inode(&i, ic, (c))) - - -static inline void jffs2_build_inode_pass1(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) -{ - struct jffs2_full_dirent *fd; - - D1(printk(KERN_DEBUG "jffs2_build_inode building directory inode #%u\n", ic->ino)); - - /* For each child, increase nlink */ - for(fd = ic->scan_dents; fd; fd = fd->next) { - struct jffs2_inode_cache *child_ic; - if (!fd->ino) - continue; - - /* XXX: Can get high latency here with huge directories */ - - child_ic = jffs2_get_ino_cache(c, fd->ino); - if (!child_ic) { - printk(KERN_NOTICE "Eep. Child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n", - fd->name, fd->ino, ic->ino); - jffs2_mark_node_obsolete(c, fd->raw); - continue; - } - - if (child_ic->nlink++ && fd->type == DT_DIR) { - printk(KERN_NOTICE "Child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n", fd->name, fd->ino, ic->ino); - if (fd->ino == 1 && ic->ino == 1) { - printk(KERN_NOTICE "This is mostly harmless, and probably caused by creating a JFFS2 image\n"); - printk(KERN_NOTICE "using a buggy version of mkfs.jffs2. Use at least v1.17.\n"); - } - /* What do we do about it? */ - } - D1(printk(KERN_DEBUG "Increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino)); - /* Can't free them. We might need them in pass 2 */ - } -} - -/* Scan plan: - - Scan physical nodes. Build map of inodes/dirents. Allocate inocaches as we go - - Scan directory tree from top down, setting nlink in inocaches - - Scan inocaches for inodes with nlink==0 -*/ -static int jffs2_build_filesystem(struct jffs2_sb_info *c) -{ - int ret; - int i; - struct jffs2_inode_cache *ic; - struct jffs2_full_dirent *fd; - struct jffs2_full_dirent *dead_fds = NULL; - - /* First, scan the medium and build all the inode caches with - lists of physical nodes */ - - c->flags |= JFFS2_SB_FLAG_SCANNING; - ret = jffs2_scan_medium(c); - c->flags &= ~JFFS2_SB_FLAG_SCANNING; - if (ret) - goto exit; - - D1(printk(KERN_DEBUG "Scanned flash completely\n")); - jffs2_dbg_dump_block_lists_nolock(c); - - c->flags |= JFFS2_SB_FLAG_BUILDING; - /* Now scan the directory tree, increasing nlink according to every dirent found. */ - for_each_inode(i, c, ic) { - D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino)); - - D1(BUG_ON(ic->ino > c->highest_ino)); - - if (ic->scan_dents) { - jffs2_build_inode_pass1(c, ic); - cond_resched(); - } - } - - D1(printk(KERN_DEBUG "Pass 1 complete\n")); - - /* Next, scan for inodes with nlink == 0 and remove them. If - they were directories, then decrement the nlink of their - children too, and repeat the scan. As that's going to be - a fairly uncommon occurrence, it's not so evil to do it this - way. Recursion bad. */ - D1(printk(KERN_DEBUG "Pass 2 starting\n")); - - for_each_inode(i, c, ic) { - D1(printk(KERN_DEBUG "Pass 2: ino #%u, nlink %d, ic %p, nodes %p\n", ic->ino, ic->nlink, ic, ic->nodes)); - if (ic->nlink) - continue; - - jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); - cond_resched(); - } - - D1(printk(KERN_DEBUG "Pass 2a starting\n")); - - while (dead_fds) { - fd = dead_fds; - dead_fds = fd->next; - - ic = jffs2_get_ino_cache(c, fd->ino); - D1(printk(KERN_DEBUG "Removing dead_fd ino #%u (\"%s\"), ic at %p\n", fd->ino, fd->name, ic)); - - if (ic) - jffs2_build_remove_unlinked_inode(c, ic, &dead_fds); - jffs2_free_full_dirent(fd); - } - - D1(printk(KERN_DEBUG "Pass 2 complete\n")); - - /* Finally, we can scan again and free the dirent structs */ - for_each_inode(i, c, ic) { - D1(printk(KERN_DEBUG "Pass 3: ino #%u, ic %p, nodes %p\n", ic->ino, ic, ic->nodes)); - - while(ic->scan_dents) { - fd = ic->scan_dents; - ic->scan_dents = fd->next; - jffs2_free_full_dirent(fd); - } - ic->scan_dents = NULL; - cond_resched(); - } - c->flags &= ~JFFS2_SB_FLAG_BUILDING; - - D1(printk(KERN_DEBUG "Pass 3 complete\n")); - jffs2_dbg_dump_block_lists_nolock(c); - - /* Rotate the lists by some number to ensure wear levelling */ - jffs2_rotate_lists(c); - - ret = 0; - -exit: - if (ret) { - for_each_inode(i, c, ic) { - while(ic->scan_dents) { - fd = ic->scan_dents; - ic->scan_dents = fd->next; - jffs2_free_full_dirent(fd); - } - } - } - - return ret; -} - -static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, struct jffs2_full_dirent **dead_fds) -{ - struct jffs2_raw_node_ref *raw; - struct jffs2_full_dirent *fd; - - D1(printk(KERN_DEBUG "JFFS2: Removing ino #%u with nlink == zero.\n", ic->ino)); - - raw = ic->nodes; - while (raw != (void *)ic) { - struct jffs2_raw_node_ref *next = raw->next_in_ino; - D1(printk(KERN_DEBUG "obsoleting node at 0x%08x\n", ref_offset(raw))); - jffs2_mark_node_obsolete(c, raw); - raw = next; - } - - if (ic->scan_dents) { - int whinged = 0; - D1(printk(KERN_DEBUG "Inode #%u was a directory which may have children...\n", ic->ino)); - - while(ic->scan_dents) { - struct jffs2_inode_cache *child_ic; - - fd = ic->scan_dents; - ic->scan_dents = fd->next; - - if (!fd->ino) { - /* It's a deletion dirent. Ignore it */ - D1(printk(KERN_DEBUG "Child \"%s\" is a deletion dirent, skipping...\n", fd->name)); - jffs2_free_full_dirent(fd); - continue; - } - if (!whinged) { - whinged = 1; - printk(KERN_NOTICE "Inode #%u was a directory with children - removing those too...\n", ic->ino); - } - - D1(printk(KERN_DEBUG "Removing child \"%s\", ino #%u\n", - fd->name, fd->ino)); - - child_ic = jffs2_get_ino_cache(c, fd->ino); - if (!child_ic) { - printk(KERN_NOTICE "Cannot remove child \"%s\", ino #%u, because it doesn't exist\n", fd->name, fd->ino); - jffs2_free_full_dirent(fd); - continue; - } - - /* Reduce nlink of the child. If it's now zero, stick it on the - dead_fds list to be cleaned up later. Else just free the fd */ - - child_ic->nlink--; - - if (!child_ic->nlink) { - D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got zero nlink. Adding to dead_fds list.\n", - fd->ino, fd->name)); - fd->next = *dead_fds; - *dead_fds = fd; - } else { - D1(printk(KERN_DEBUG "Inode #%u (\"%s\") has now got nlink %d. Ignoring.\n", - fd->ino, fd->name, child_ic->nlink)); - jffs2_free_full_dirent(fd); - } - } - } - - /* - We don't delete the inocache from the hash list and free it yet. - The erase code will do that, when all the nodes are completely gone. - */ -} - -static void jffs2_calc_trigger_levels(struct jffs2_sb_info *c) -{ - uint32_t size; - - /* Deletion should almost _always_ be allowed. We're fairly - buggered once we stop allowing people to delete stuff - because there's not enough free space... */ - c->resv_blocks_deletion = 2; - - /* Be conservative about how much space we need before we allow writes. - On top of that which is required for deletia, require an extra 2% - of the medium to be available, for overhead caused by nodes being - split across blocks, etc. */ - - size = c->flash_size / 50; /* 2% of flash size */ - size += c->nr_blocks * 100; /* And 100 bytes per eraseblock */ - size += c->sector_size - 1; /* ... and round up */ - - c->resv_blocks_write = c->resv_blocks_deletion + (size / c->sector_size); - - /* When do we let the GC thread run in the background */ - - c->resv_blocks_gctrigger = c->resv_blocks_write + 1; - - /* When do we allow garbage collection to merge nodes to make - long-term progress at the expense of short-term space exhaustion? */ - c->resv_blocks_gcmerge = c->resv_blocks_deletion + 1; - - /* When do we allow garbage collection to eat from bad blocks rather - than actually making progress? */ - c->resv_blocks_gcbad = 0;//c->resv_blocks_deletion + 2; - - /* If there's less than this amount of dirty space, don't bother - trying to GC to make more space. It'll be a fruitless task */ - c->nospc_dirty_size = c->sector_size + (c->flash_size / 100); - - D1(printk(KERN_DEBUG "JFFS2 trigger levels (size %d KiB, block size %d KiB, %d blocks)\n", - c->flash_size / 1024, c->sector_size / 1024, c->nr_blocks)); - D1(printk(KERN_DEBUG "Blocks required to allow deletion: %d (%d KiB)\n", - c->resv_blocks_deletion, c->resv_blocks_deletion*c->sector_size/1024)); - D1(printk(KERN_DEBUG "Blocks required to allow writes: %d (%d KiB)\n", - c->resv_blocks_write, c->resv_blocks_write*c->sector_size/1024)); - D1(printk(KERN_DEBUG "Blocks required to quiesce GC thread: %d (%d KiB)\n", - c->resv_blocks_gctrigger, c->resv_blocks_gctrigger*c->sector_size/1024)); - D1(printk(KERN_DEBUG "Blocks required to allow GC merges: %d (%d KiB)\n", - c->resv_blocks_gcmerge, c->resv_blocks_gcmerge*c->sector_size/1024)); - D1(printk(KERN_DEBUG "Blocks required to GC bad blocks: %d (%d KiB)\n", - c->resv_blocks_gcbad, c->resv_blocks_gcbad*c->sector_size/1024)); - D1(printk(KERN_DEBUG "Amount of dirty space required to GC: %d bytes\n", - c->nospc_dirty_size)); -} - -int jffs2_do_mount_fs(struct jffs2_sb_info *c) -{ - int i; - - c->free_size = c->flash_size; - c->nr_blocks = c->flash_size / c->sector_size; -#ifndef __ECOS - if (c->mtd->flags & MTD_NO_VIRTBLOCKS) - c->blocks = vmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks); - else -#endif - c->blocks = kmalloc(sizeof(struct jffs2_eraseblock) * c->nr_blocks, GFP_KERNEL); - if (!c->blocks) - return -ENOMEM; - for (i=0; i<c->nr_blocks; i++) { - INIT_LIST_HEAD(&c->blocks[i].list); - c->blocks[i].offset = i * c->sector_size; - c->blocks[i].free_size = c->sector_size; - c->blocks[i].dirty_size = 0; - c->blocks[i].wasted_size = 0; - c->blocks[i].unchecked_size = 0; - c->blocks[i].used_size = 0; - c->blocks[i].first_node = NULL; - c->blocks[i].last_node = NULL; - c->blocks[i].bad_count = 0; - } - - INIT_LIST_HEAD(&c->clean_list); - INIT_LIST_HEAD(&c->very_dirty_list); - INIT_LIST_HEAD(&c->dirty_list); - INIT_LIST_HEAD(&c->erasable_list); - INIT_LIST_HEAD(&c->erasing_list); - INIT_LIST_HEAD(&c->erase_pending_list); - INIT_LIST_HEAD(&c->erasable_pending_wbuf_list); - INIT_LIST_HEAD(&c->erase_complete_list); - INIT_LIST_HEAD(&c->free_list); - INIT_LIST_HEAD(&c->bad_list); - INIT_LIST_HEAD(&c->bad_used_list); - c->highest_ino = 1; - - if (jffs2_build_filesystem(c)) { - D1(printk(KERN_DEBUG "build_fs failed\n")); - jffs2_free_ino_caches(c); - jffs2_free_raw_node_refs(c); -#ifndef __ECOS - if (c->mtd->flags & MTD_NO_VIRTBLOCKS) - vfree(c->blocks); - else -#endif - kfree(c->blocks); - - return -EIO; - } - - jffs2_calc_trigger_levels(c); - - return 0; -} diff --git a/components/dfs/filesystems/jffs2/src/compr.c b/components/dfs/filesystems/jffs2/src/compr.c deleted file mode 100644 index c9e54b97db..0000000000 --- a/components/dfs/filesystems/jffs2/src/compr.c +++ /dev/null @@ -1,457 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * Created by Arjan van de Ven <[email protected]> - * - * Copyright (C) 2004 Ferenc Havasi <[email protected]>, - * University of Szeged, Hungary - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: compr.c,v 1.45 2005/07/26 13:24:40 havasi Exp $ - * - */ - -#include "compr.h" - -static DEFINE_SPINLOCK(jffs2_compressor_list_lock); - -/* Available compressors are on this list */ -static LIST_HEAD(jffs2_compressor_list); - -/* Actual compression mode */ -static int jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; - -/* Statistics for blocks stored without compression */ -static uint32_t none_stat_compr_blocks=0,none_stat_decompr_blocks=0,none_stat_compr_size=0; - -/* jffs2_compress: - * @data: Pointer to uncompressed data - * @cdata: Pointer to returned pointer to buffer for compressed data - * @datalen: On entry, holds the amount of data available for compression. - * On exit, expected to hold the amount of data actually compressed. - * @cdatalen: On entry, holds the amount of space available for compressed - * data. On exit, expected to hold the actual size of the compressed - * data. - * - * Returns: Lower byte to be stored with data indicating compression type used. - * Zero is used to show that the data could not be compressed - the - * compressed version was actually larger than the original. - * Upper byte will be used later. (soon) - * - * If the cdata buffer isn't large enough to hold all the uncompressed data, - * jffs2_compress should compress as much as will fit, and should set - * *datalen accordingly to show the amount of data which were compressed. - */ -uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - unsigned char *data_in, unsigned char **cpage_out, - uint32_t *datalen, uint32_t *cdatalen) -{ - int ret = JFFS2_COMPR_NONE; - int compr_ret; - struct jffs2_compressor *this, *best=NULL; - unsigned char *output_buf = NULL, *tmp_buf; - uint32_t orig_slen, orig_dlen; - uint32_t best_slen=0, best_dlen=0; - - switch (jffs2_compression_mode) { - case JFFS2_COMPR_MODE_NONE: - break; - case JFFS2_COMPR_MODE_PRIORITY: - output_buf = kmalloc(*cdatalen,GFP_KERNEL); - if (!output_buf) { - printk(KERN_WARNING "JFFS2: No memory for compressor allocation. Compression failed.\n"); - goto out; - } - orig_slen = *datalen; - orig_dlen = *cdatalen; - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - /* Skip decompress-only backwards-compatibility and disabled modules */ - if ((!this->compress)||(this->disabled)) - continue; - - this->usecount++; - spin_unlock(&jffs2_compressor_list_lock); - *datalen = orig_slen; - *cdatalen = orig_dlen; - compr_ret = this->compress(data_in, output_buf, datalen, cdatalen, NULL); - spin_lock(&jffs2_compressor_list_lock); - this->usecount--; - if (!compr_ret) { - ret = this->compr; - this->stat_compr_blocks++; - this->stat_compr_orig_size += *datalen; - this->stat_compr_new_size += *cdatalen; - break; - } - } - spin_unlock(&jffs2_compressor_list_lock); - if (ret == JFFS2_COMPR_NONE) kfree(output_buf); - break; - case JFFS2_COMPR_MODE_SIZE: - orig_slen = *datalen; - orig_dlen = *cdatalen; - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - /* Skip decompress-only backwards-compatibility and disabled modules */ - if ((!this->compress)||(this->disabled)) - continue; - /* Allocating memory for output buffer if necessary */ - if ((this->compr_buf_size<orig_dlen)&&(this->compr_buf)) { - spin_unlock(&jffs2_compressor_list_lock); - kfree(this->compr_buf); - spin_lock(&jffs2_compressor_list_lock); - this->compr_buf_size=0; - this->compr_buf=NULL; - } - if (!this->compr_buf) { - spin_unlock(&jffs2_compressor_list_lock); - tmp_buf = kmalloc(orig_dlen,GFP_KERNEL); - spin_lock(&jffs2_compressor_list_lock); - if (!tmp_buf) { - printk(KERN_WARNING "JFFS2: No memory for compressor allocation. (%d bytes)\n",orig_dlen); - continue; - } - else { - this->compr_buf = tmp_buf; - this->compr_buf_size = orig_dlen; - } - } - this->usecount++; - spin_unlock(&jffs2_compressor_list_lock); - *datalen = orig_slen; - *cdatalen = orig_dlen; - compr_ret = this->compress(data_in, this->compr_buf, datalen, cdatalen, NULL); - spin_lock(&jffs2_compressor_list_lock); - this->usecount--; - if (!compr_ret) { - if ((!best_dlen)||(best_dlen>*cdatalen)) { - best_dlen = *cdatalen; - best_slen = *datalen; - best = this; - } - } - } - if (best_dlen) { - *cdatalen = best_dlen; - *datalen = best_slen; - output_buf = best->compr_buf; - best->compr_buf = NULL; - best->compr_buf_size = 0; - best->stat_compr_blocks++; - best->stat_compr_orig_size += best_slen; - best->stat_compr_new_size += best_dlen; - ret = best->compr; - } - spin_unlock(&jffs2_compressor_list_lock); - break; - default: - printk(KERN_ERR "JFFS2: unknow compression mode.\n"); - } - out: - if (ret == JFFS2_COMPR_NONE) { - *cpage_out = data_in; - *datalen = *cdatalen; - none_stat_compr_blocks++; - none_stat_compr_size += *datalen; - } - else { - *cpage_out = output_buf; - } - return ret; -} - -int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - uint16_t comprtype, unsigned char *cdata_in, - unsigned char *data_out, uint32_t cdatalen, uint32_t datalen) -{ - struct jffs2_compressor *this; - int ret; - - /* Older code had a bug where it would write non-zero 'usercompr' - fields. Deal with it. */ - if ((comprtype & 0xff) <= JFFS2_COMPR_ZLIB) - comprtype &= 0xff; - - switch (comprtype & 0xff) { - case JFFS2_COMPR_NONE: - /* This should be special-cased elsewhere, but we might as well deal with it */ - memcpy(data_out, cdata_in, datalen); - none_stat_decompr_blocks++; - break; - case JFFS2_COMPR_ZERO: - memset(data_out, 0, datalen); - break; - default: - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - if (comprtype == this->compr) { - this->usecount++; - spin_unlock(&jffs2_compressor_list_lock); - ret = this->decompress(cdata_in, data_out, cdatalen, datalen, NULL); - spin_lock(&jffs2_compressor_list_lock); - if (ret) { - printk(KERN_WARNING "Decompressor \"%s\" returned %d\n", this->name, ret); - } - else { - this->stat_decompr_blocks++; - } - this->usecount--; - spin_unlock(&jffs2_compressor_list_lock); - return ret; - } - } - printk(KERN_WARNING "JFFS2 compression type 0x%02x not available.\n", comprtype); - spin_unlock(&jffs2_compressor_list_lock); - return -EIO; - } - return 0; -} - -int jffs2_register_compressor(struct jffs2_compressor *comp) -{ - struct jffs2_compressor *this; - - if (!comp->name) { - printk(KERN_WARNING "NULL compressor name at registering JFFS2 compressor. Failed.\n"); - return -1; - } - comp->compr_buf_size=0; - comp->compr_buf=NULL; - comp->usecount=0; - comp->stat_compr_orig_size=0; - comp->stat_compr_new_size=0; - comp->stat_compr_blocks=0; - comp->stat_decompr_blocks=0; - D1(printk(KERN_DEBUG "Registering JFFS2 compressor \"%s\"\n", comp->name)); - - spin_lock(&jffs2_compressor_list_lock); - - list_for_each_entry(this, &jffs2_compressor_list, list) { - if (this->priority < comp->priority) { - list_add(&comp->list, this->list.prev); - goto out; - } - } - list_add_tail(&comp->list, &jffs2_compressor_list); -out: - D2(list_for_each_entry(this, &jffs2_compressor_list, list) { - printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); - }) - - spin_unlock(&jffs2_compressor_list_lock); - - return 0; -} - -int jffs2_unregister_compressor(struct jffs2_compressor *comp) -{ - D2(struct jffs2_compressor *this;) - - D1(printk(KERN_DEBUG "Unregistering JFFS2 compressor \"%s\"\n", comp->name)); - - spin_lock(&jffs2_compressor_list_lock); - - if (comp->usecount) { - spin_unlock(&jffs2_compressor_list_lock); - printk(KERN_WARNING "JFFS2: Compressor modul is in use. Unregister failed.\n"); - return -1; - } - list_del(&comp->list); - - D2(list_for_each_entry(this, &jffs2_compressor_list, list) { - printk(KERN_DEBUG "Compressor \"%s\", prio %d\n", this->name, this->priority); - }) - spin_unlock(&jffs2_compressor_list_lock); - return 0; -} - -#ifdef CONFIG_JFFS2_PROC - -#define JFFS2_STAT_BUF_SIZE 16000 - -char *jffs2_list_compressors(void) -{ - struct jffs2_compressor *this; - char *buf, *act_buf; - - act_buf = buf = kmalloc(JFFS2_STAT_BUF_SIZE,GFP_KERNEL); - list_for_each_entry(this, &jffs2_compressor_list, list) { - act_buf += sprintf(act_buf, "%10s priority:%d ", this->name, this->priority); - if ((this->disabled)||(!this->compress)) - act_buf += sprintf(act_buf,"disabled"); - else - act_buf += sprintf(act_buf,"enabled"); - act_buf += sprintf(act_buf,"\n"); - } - return buf; -} - -char *jffs2_stats(void) -{ - struct jffs2_compressor *this; - char *buf, *act_buf; - - act_buf = buf = kmalloc(JFFS2_STAT_BUF_SIZE,GFP_KERNEL); - - act_buf += sprintf(act_buf,"JFFS2 compressor statistics:\n"); - act_buf += sprintf(act_buf,"%10s ","none"); - act_buf += sprintf(act_buf,"compr: %d blocks (%d) decompr: %d blocks\n", none_stat_compr_blocks, - none_stat_compr_size, none_stat_decompr_blocks); - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - act_buf += sprintf(act_buf,"%10s ",this->name); - if ((this->disabled)||(!this->compress)) - act_buf += sprintf(act_buf,"- "); - else - act_buf += sprintf(act_buf,"+ "); - act_buf += sprintf(act_buf,"compr: %d blocks (%d/%d) decompr: %d blocks ", this->stat_compr_blocks, - this->stat_compr_new_size, this->stat_compr_orig_size, - this->stat_decompr_blocks); - act_buf += sprintf(act_buf,"\n"); - } - spin_unlock(&jffs2_compressor_list_lock); - - return buf; -} - -char *jffs2_get_compression_mode_name(void) -{ - switch (jffs2_compression_mode) { - case JFFS2_COMPR_MODE_NONE: - return "none"; - case JFFS2_COMPR_MODE_PRIORITY: - return "priority"; - case JFFS2_COMPR_MODE_SIZE: - return "size"; - } - return "unkown"; -} - -int jffs2_set_compression_mode_name(const char *name) -{ - if (!strcmp("none",name)) { - jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; - return 0; - } - if (!strcmp("priority",name)) { - jffs2_compression_mode = JFFS2_COMPR_MODE_PRIORITY; - return 0; - } - if (!strcmp("size",name)) { - jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; - return 0; - } - return 1; -} - -static int jffs2_compressor_Xable(const char *name, int disabled) -{ - struct jffs2_compressor *this; - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - if (!strcmp(this->name, name)) { - this->disabled = disabled; - spin_unlock(&jffs2_compressor_list_lock); - return 0; - } - } - spin_unlock(&jffs2_compressor_list_lock); - printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name); - return 1; -} - -int jffs2_enable_compressor_name(const char *name) -{ - return jffs2_compressor_Xable(name, 0); -} - -int jffs2_disable_compressor_name(const char *name) -{ - return jffs2_compressor_Xable(name, 1); -} - -int jffs2_set_compressor_priority(const char *name, int priority) -{ - struct jffs2_compressor *this,*comp; - spin_lock(&jffs2_compressor_list_lock); - list_for_each_entry(this, &jffs2_compressor_list, list) { - if (!strcmp(this->name, name)) { - this->priority = priority; - comp = this; - goto reinsert; - } - } - spin_unlock(&jffs2_compressor_list_lock); - printk(KERN_WARNING "JFFS2: compressor %s not found.\n",name); - return 1; -reinsert: - /* list is sorted in the order of priority, so if - we change it we have to reinsert it into the - good place */ - list_del(&comp->list); - list_for_each_entry(this, &jffs2_compressor_list, list) { - if (this->priority < comp->priority) { - list_add(&comp->list, this->list.prev); - spin_unlock(&jffs2_compressor_list_lock); - return 0; - } - } - list_add_tail(&comp->list, &jffs2_compressor_list); - spin_unlock(&jffs2_compressor_list_lock); - return 0; -} - -#endif - -void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig) -{ - if (orig != comprbuf) - kfree(comprbuf); -} - -int jffs2_compressors_init(void) -{ -/* Registering compressors */ -#ifdef CONFIG_JFFS2_ZLIB - jffs2_zlib_init(); -#endif -#ifdef CONFIG_JFFS2_RTIME - jffs2_rtime_init(); -#endif -#ifdef CONFIG_JFFS2_RUBIN - jffs2_rubinmips_init(); - jffs2_dynrubin_init(); -#endif -/* Setting default compression mode */ -#ifdef CONFIG_JFFS2_CMODE_NONE - jffs2_compression_mode = JFFS2_COMPR_MODE_NONE; - D1(printk(KERN_INFO "JFFS2: default compression mode: none\n");) -#else -#ifdef CONFIG_JFFS2_CMODE_SIZE - jffs2_compression_mode = JFFS2_COMPR_MODE_SIZE; - D1(printk(KERN_INFO "JFFS2: default compression mode: size\n");) -#else - D1(printk(KERN_INFO "JFFS2: default compression mode: priority\n");) -#endif -#endif - return 0; -} - -int jffs2_compressors_exit(void) -{ -/* Unregistering compressors */ -#ifdef CONFIG_JFFS2_RUBIN - jffs2_dynrubin_exit(); - jffs2_rubinmips_exit(); -#endif -#ifdef CONFIG_JFFS2_RTIME - jffs2_rtime_exit(); -#endif -#ifdef CONFIG_JFFS2_ZLIB - jffs2_zlib_exit(); -#endif - return 0; -} diff --git a/components/dfs/filesystems/jffs2/src/compr.h b/components/dfs/filesystems/jffs2/src/compr.h deleted file mode 100644 index 9ec6e37d38..0000000000 --- a/components/dfs/filesystems/jffs2/src/compr.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2004 Ferenc Havasi <[email protected]>, - * University of Szeged, Hungary - * - * For licensing information, see the file 'LICENCE' in the - * jffs2 directory. - * - * $Id: compr.h,v 1.8 2005/07/26 13:24:40 havasi Exp $ - * - */ - -#ifndef __JFFS2_COMPR_H__ -#define __JFFS2_COMPR_H__ - -#include <linux/kernel.h> -#include <linux/vmalloc.h> -#include <linux/list.h> -#include <linux/types.h> -#include <linux/string.h> -#include <linux/slab.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/jffs2.h> -#include <linux/jffs2_fs_i.h> -#include <linux/jffs2_fs_sb.h> -#include "nodelist.h" - -#define JFFS2_RUBINMIPS_PRIORITY 10 -#define JFFS2_DYNRUBIN_PRIORITY 20 -#define JFFS2_LZARI_PRIORITY 30 -#define JFFS2_LZO_PRIORITY 40 -#define JFFS2_RTIME_PRIORITY 50 -#define JFFS2_ZLIB_PRIORITY 60 - -#define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */ -#define JFFS2_DYNRUBIN_DISABLED /* for decompression */ - -#define JFFS2_COMPR_MODE_NONE 0 -#define JFFS2_COMPR_MODE_PRIORITY 1 -#define JFFS2_COMPR_MODE_SIZE 2 - -struct jffs2_compressor { - struct list_head list; - int priority; /* used by prirority comr. mode */ - char *name; - char compr; /* JFFS2_COMPR_XXX */ - int (*compress)(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *srclen, uint32_t *destlen, void *model); - int (*decompress)(unsigned char *cdata_in, unsigned char *data_out, - uint32_t cdatalen, uint32_t datalen, void *model); - int usecount; - int disabled; /* if seted the compressor won't compress */ - unsigned char *compr_buf; /* used by size compr. mode */ - uint32_t compr_buf_size; /* used by size compr. mode */ - uint32_t stat_compr_orig_size; - uint32_t stat_compr_new_size; - uint32_t stat_compr_blocks; - uint32_t stat_decompr_blocks; -}; - -int jffs2_register_compressor(struct jffs2_compressor *comp); -int jffs2_unregister_compressor(struct jffs2_compressor *comp); - -int jffs2_compressors_init(void); -int jffs2_compressors_exit(void); - -uint16_t jffs2_compress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - unsigned char *data_in, unsigned char **cpage_out, - uint32_t *datalen, uint32_t *cdatalen); - -int jffs2_decompress(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - uint16_t comprtype, unsigned char *cdata_in, - unsigned char *data_out, uint32_t cdatalen, uint32_t datalen); - -void jffs2_free_comprbuf(unsigned char *comprbuf, unsigned char *orig); - -#ifdef CONFIG_JFFS2_PROC -int jffs2_enable_compressor_name(const char *name); -int jffs2_disable_compressor_name(const char *name); -int jffs2_set_compression_mode_name(const char *mode_name); -char *jffs2_get_compression_mode_name(void); -int jffs2_set_compressor_priority(const char *mode_name, int priority); -char *jffs2_list_compressors(void); -char *jffs2_stats(void); -#endif - -/* Compressor modules */ -/* These functions will be called by jffs2_compressors_init/exit */ - -#ifdef CONFIG_JFFS2_RUBIN -int jffs2_rubinmips_init(void); -void jffs2_rubinmips_exit(void); -int jffs2_dynrubin_init(void); -void jffs2_dynrubin_exit(void); -#endif -#ifdef CONFIG_JFFS2_RTIME -int jffs2_rtime_init(void); -void jffs2_rtime_exit(void); -#endif -#ifdef CONFIG_JFFS2_ZLIB -int jffs2_zlib_init(void); -void jffs2_zlib_exit(void); -#endif - -#endif /* __JFFS2_COMPR_H__ */ diff --git a/components/dfs/filesystems/jffs2/src/compr_rtime.c b/components/dfs/filesystems/jffs2/src/compr_rtime.c deleted file mode 100644 index c7f6b2914e..0000000000 --- a/components/dfs/filesystems/jffs2/src/compr_rtime.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by Arjan van de Ven <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: compr_rtime.c,v 1.15 2005/03/17 20:23:06 gleixner Exp $ - * - * - * Very simple lz77-ish encoder. - * - * Theory of operation: Both encoder and decoder have a list of "last - * occurrences" for every possible source-value; after sending the - * first source-byte, the second byte indicated the "run" length of - * matches - * - * The algorithm is intended to only send "whole bytes", no bit-messing. - * - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/jffs2.h> -#include "compr.h" - -/* _compress returns the compressed size, -1 if bigger */ -static int jffs2_rtime_compress(unsigned char *data_in, - unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen, - void *model) -{ - short positions[256]; - int outpos = 0; - int pos=0; - - memset(positions,0,sizeof(positions)); - - while (pos < (*sourcelen) && outpos <= (*dstlen)-2) { - int backpos, runlen=0; - unsigned char value; - - value = data_in[pos]; - - cpage_out[outpos++] = data_in[pos++]; - - backpos = positions[value]; - positions[value]=pos; - - while ((backpos < pos) && (pos < (*sourcelen)) && - (data_in[pos]==data_in[backpos++]) && (runlen<255)) { - pos++; - runlen++; - } - cpage_out[outpos++] = runlen; - } - - if (outpos >= pos) { - /* We failed */ - return -1; - } - - /* Tell the caller how much we managed to compress, and how much space it took */ - *sourcelen = pos; - *dstlen = outpos; - return 0; -} - - -static int jffs2_rtime_decompress(unsigned char *data_in, - unsigned char *cpage_out, - uint32_t srclen, uint32_t destlen, - void *model) -{ - short positions[256]; - int outpos = 0; - int pos=0; - - memset(positions,0,sizeof(positions)); - - while (outpos<destlen) { - unsigned char value; - int backoffs; - int repeat; - - value = data_in[pos++]; - cpage_out[outpos++] = value; /* first the verbatim copied byte */ - repeat = data_in[pos++]; - backoffs = positions[value]; - - positions[value]=outpos; - if (repeat) { - if (backoffs + repeat >= outpos) { - while(repeat) { - cpage_out[outpos++] = cpage_out[backoffs++]; - repeat--; - } - } else { - memcpy(&cpage_out[outpos],&cpage_out[backoffs],repeat); - outpos+=repeat; - } - } - } - return 0; -} - -#if defined (__GNUC__) -static struct jffs2_compressor jffs2_rtime_comp = { - .priority = JFFS2_RTIME_PRIORITY, - .name = "rtime", - .compr = JFFS2_COMPR_RTIME, - .compress = &jffs2_rtime_compress, - .decompress = &jffs2_rtime_decompress, -#ifdef JFFS2_RTIME_DISABLED - .disabled = 1, -#else - .disabled = 0, -#endif -}; -#elif defined (MSVC) -static struct jffs2_compressor jffs2_rtime_comp = { - {NULL}, - JFFS2_RTIME_PRIORITY,//.priority = - "rtime",//.name = - JFFS2_COMPR_RTIME,//.compr = - &jffs2_rtime_compress,//.compress = - &jffs2_rtime_decompress,//.decompress = - 0, -#ifdef JFFS2_RTIME_DISABLED - 1,//.disabled = -#else - 0,//.disabled = -#endif - NULL, - 0, - 0, - 0, - 0, - 0 -}; -#else -#endif - -int jffs2_rtime_init(void) -{ - return jffs2_register_compressor(&jffs2_rtime_comp); -} - -void jffs2_rtime_exit(void) -{ - jffs2_unregister_compressor(&jffs2_rtime_comp); -} diff --git a/components/dfs/filesystems/jffs2/src/compr_rubin.c b/components/dfs/filesystems/jffs2/src/compr_rubin.c deleted file mode 100644 index e1030d6778..0000000000 --- a/components/dfs/filesystems/jffs2/src/compr_rubin.c +++ /dev/null @@ -1,427 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001, 2002 Red Hat, Inc. - * - * Created by Arjan van de Ven <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: compr_rubin.c,v 1.21 2005/05/20 15:39:54 gleixner Exp $ - * - */ - - -#include <linux/string.h> -#include <linux/types.h> -#include <linux/jffs2.h> -#include "compr_rubin.h" -#include "histo_mips.h" -#include "compr.h" - -static void init_rubin(struct rubin_state *rs, int div, int *bits) -{ - int c; - - rs->q = 0; - rs->p = (long) (2 * UPPER_BIT_RUBIN); - rs->bit_number = (long) 0; - rs->bit_divider = div; - for (c=0; c<8; c++) - rs->bits[c] = bits[c]; -} - - -static int encode(struct rubin_state *rs, long A, long B, int symbol) -{ - - long i0, i1; - int ret; - - while ((rs->q >= UPPER_BIT_RUBIN) || ((rs->p + rs->q) <= UPPER_BIT_RUBIN)) { - rs->bit_number++; - - ret = pushbit(&rs->pp, (rs->q & UPPER_BIT_RUBIN) ? 1 : 0, 0); - if (ret) - return ret; - rs->q &= LOWER_BITS_RUBIN; - rs->q <<= 1; - rs->p <<= 1; - } - i0 = A * rs->p / (A + B); - if (i0 <= 0) { - i0 = 1; - } - if (i0 >= rs->p) { - i0 = rs->p - 1; - } - i1 = rs->p - i0; - - if (symbol == 0) - rs->p = i0; - else { - rs->p = i1; - rs->q += i0; - } - return 0; -} - - -static void end_rubin(struct rubin_state *rs) -{ - - int i; - - for (i = 0; i < RUBIN_REG_SIZE; i++) { - pushbit(&rs->pp, (UPPER_BIT_RUBIN & rs->q) ? 1 : 0, 1); - rs->q &= LOWER_BITS_RUBIN; - rs->q <<= 1; - } -} - - -static void init_decode(struct rubin_state *rs, int div, int *bits) -{ - init_rubin(rs, div, bits); - - /* behalve lower */ - rs->rec_q = 0; - - for (rs->bit_number = 0; rs->bit_number++ < RUBIN_REG_SIZE; rs->rec_q = rs->rec_q * 2 + (long) (pullbit(&rs->pp))) - ; -} - -static void __do_decode(struct rubin_state *rs, unsigned long p, unsigned long q) -{ - register unsigned long lower_bits_rubin = LOWER_BITS_RUBIN; - unsigned long rec_q; - int c, bits = 0; - - /* - * First, work out how many bits we need from the input stream. - * Note that we have already done the initial check on this - * loop prior to calling this function. - */ - do { - bits++; - q &= lower_bits_rubin; - q <<= 1; - p <<= 1; - } while ((q >= UPPER_BIT_RUBIN) || ((p + q) <= UPPER_BIT_RUBIN)); - - rs->p = p; - rs->q = q; - - rs->bit_number += bits; - - /* - * Now get the bits. We really want this to be "get n bits". - */ - rec_q = rs->rec_q; - do { - c = pullbit(&rs->pp); - rec_q &= lower_bits_rubin; - rec_q <<= 1; - rec_q += c; - } while (--bits); - rs->rec_q = rec_q; -} - -static int decode(struct rubin_state *rs, long A, long B) -{ - unsigned long p = rs->p, q = rs->q; - long i0, threshold; - int symbol; - - if (q >= UPPER_BIT_RUBIN || ((p + q) <= UPPER_BIT_RUBIN)) - __do_decode(rs, p, q); - - i0 = A * rs->p / (A + B); - if (i0 <= 0) { - i0 = 1; - } - if (i0 >= rs->p) { - i0 = rs->p - 1; - } - - threshold = rs->q + i0; - symbol = rs->rec_q >= threshold; - if (rs->rec_q >= threshold) { - rs->q += i0; - i0 = rs->p - i0; - } - - rs->p = i0; - - return symbol; -} - - - -static int out_byte(struct rubin_state *rs, unsigned char byte) -{ - int i, ret; - struct rubin_state rs_copy; - rs_copy = *rs; - - for (i=0;i<8;i++) { - ret = encode(rs, rs->bit_divider-rs->bits[i],rs->bits[i],byte&1); - if (ret) { - /* Failed. Restore old state */ - *rs = rs_copy; - return ret; - } - byte=byte>>1; - } - return 0; -} - -static int in_byte(struct rubin_state *rs) -{ - int i, result = 0, bit_divider = rs->bit_divider; - - for (i = 0; i < 8; i++) - result |= decode(rs, bit_divider - rs->bits[i], rs->bits[i]) << i; - - return result; -} - - - -static int rubin_do_compress(int bit_divider, int *bits, unsigned char *data_in, - unsigned char *cpage_out, uint32_t *sourcelen, uint32_t *dstlen) - { - int outpos = 0; - int pos=0; - struct rubin_state rs; - - init_pushpull(&rs.pp, (char *)cpage_out, *dstlen * 8, 0, 32); - - init_rubin(&rs, bit_divider, bits); - - while (pos < (*sourcelen) && !out_byte(&rs, data_in[pos])) - pos++; - - end_rubin(&rs); - - if (outpos > pos) { - /* We failed */ - return -1; - } - - /* Tell the caller how much we managed to compress, - * and how much space it took */ - - outpos = (pushedbits(&rs.pp)+7)/8; - - if (outpos >= pos) - return -1; /* We didn't actually compress */ - *sourcelen = pos; - *dstlen = outpos; - return 0; -} -#if 0 -/* _compress returns the compressed size, -1 if bigger */ -int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen, void *model) -{ - return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); -} -#endif -static int jffs2_dynrubin_compress(unsigned char *data_in, - unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen, - void *model) -{ - int bits[8]; - unsigned char histo[256]; - int i; - int ret; - uint32_t mysrclen, mydstlen; - - mysrclen = *sourcelen; - mydstlen = *dstlen - 8; - - if (*dstlen <= 12) - return -1; - - memset(histo, 0, 256); - for (i=0; i<mysrclen; i++) { - histo[data_in[i]]++; - } - memset(bits, 0, sizeof(int)*8); - for (i=0; i<256; i++) { - if (i&128) - bits[7] += histo[i]; - if (i&64) - bits[6] += histo[i]; - if (i&32) - bits[5] += histo[i]; - if (i&16) - bits[4] += histo[i]; - if (i&8) - bits[3] += histo[i]; - if (i&4) - bits[2] += histo[i]; - if (i&2) - bits[1] += histo[i]; - if (i&1) - bits[0] += histo[i]; - } - - for (i=0; i<8; i++) { - bits[i] = (bits[i] * 256) / mysrclen; - if (!bits[i]) bits[i] = 1; - if (bits[i] > 255) bits[i] = 255; - cpage_out[i] = bits[i]; - } - - ret = rubin_do_compress(256, bits, data_in, cpage_out+8, &mysrclen, &mydstlen); - if (ret) - return ret; - - /* Add back the 8 bytes we took for the probabilities */ - mydstlen += 8; - - if (mysrclen <= mydstlen) { - /* We compressed */ - return -1; - } - - *sourcelen = mysrclen; - *dstlen = mydstlen; - return 0; -} - -static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata_in, - unsigned char *page_out, uint32_t srclen, uint32_t destlen) -{ - int outpos = 0; - struct rubin_state rs; - - init_pushpull(&rs.pp, (char *)cdata_in, srclen, 0, 0); - init_decode(&rs, bit_divider, bits); - - while (outpos < destlen) { - page_out[outpos++] = in_byte(&rs); - } -} - - -static int jffs2_rubinmips_decompress(unsigned char *data_in, - unsigned char *cpage_out, - uint32_t sourcelen, uint32_t dstlen, - void *model) -{ - rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); - return 0; -} - -static int jffs2_dynrubin_decompress(unsigned char *data_in, - unsigned char *cpage_out, - uint32_t sourcelen, uint32_t dstlen, - void *model) -{ - int bits[8]; - int c; - - for (c=0; c<8; c++) - bits[c] = data_in[c]; - - rubin_do_decompress(256, bits, data_in+8, cpage_out, sourcelen-8, dstlen); - return 0; -} - -#if defined (__GNUC__) -static struct jffs2_compressor jffs2_rubinmips_comp = { - .priority = JFFS2_RUBINMIPS_PRIORITY, - .name = "rubinmips", - .compr = JFFS2_COMPR_DYNRUBIN, - .compress = NULL, /*&jffs2_rubinmips_compress,*/ - .decompress = &jffs2_rubinmips_decompress, -#ifdef JFFS2_RUBINMIPS_DISABLED - .disabled = 1, -#else - .disabled = 0, -#endif -}; -#elif defined (MSVC) -static struct jffs2_compressor jffs2_rubinmips_comp = { - {NULL}, - JFFS2_RUBINMIPS_PRIORITY, - "rubinmips", - JFFS2_COMPR_DYNRUBIN, - NULL, /*&jffs2_rubinmips_compress,*/ - &jffs2_rubinmips_decompress, - 0, -#ifdef JFFS2_RUBINMIPS_DISABLED - 1, -#else - 0, -#endif - NULL, - 0, - 0, - 0, - 0, - 0 -}; -#else -#endif - -int jffs2_rubinmips_init(void) -{ - return jffs2_register_compressor(&jffs2_rubinmips_comp); -} - -void jffs2_rubinmips_exit(void) -{ - jffs2_unregister_compressor(&jffs2_rubinmips_comp); -} - -#if defined (__GNUC__) -static struct jffs2_compressor jffs2_dynrubin_comp = { - .priority = JFFS2_DYNRUBIN_PRIORITY, - .name = "dynrubin", - .compr = JFFS2_COMPR_RUBINMIPS, - .compress = jffs2_dynrubin_compress, - .decompress = &jffs2_dynrubin_decompress, -#ifdef JFFS2_DYNRUBIN_DISABLED - .disabled = 1, -#else - .disabled = 0, -#endif -}; -#elif defined (MSVC) -static struct jffs2_compressor jffs2_dynrubin_comp = { - {NULL}, - JFFS2_DYNRUBIN_PRIORITY, - "dynrubin", - JFFS2_COMPR_RUBINMIPS, - jffs2_dynrubin_compress, - &jffs2_dynrubin_decompress, - 0, -#ifdef JFFS2_DYNRUBIN_DISABLED - 1, -#else - 0, -#endif - NULL, - 0, - 0, - 0, - 0, - 0 -}; -#else -#endif - -int jffs2_dynrubin_init(void) -{ - return jffs2_register_compressor(&jffs2_dynrubin_comp); -} - -void jffs2_dynrubin_exit(void) -{ - jffs2_unregister_compressor(&jffs2_dynrubin_comp); -} diff --git a/components/dfs/filesystems/jffs2/src/compr_rubin.h b/components/dfs/filesystems/jffs2/src/compr_rubin.h deleted file mode 100644 index cf51e34f65..0000000000 --- a/components/dfs/filesystems/jffs2/src/compr_rubin.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Rubin encoder/decoder header */ -/* work started at : aug 3, 1994 */ -/* last modification : aug 15, 1994 */ -/* $Id: compr_rubin.h,v 1.6 2002/01/25 01:49:26 dwmw2 Exp $ */ - -#include "pushpull.h" - -#define RUBIN_REG_SIZE 16 -#define UPPER_BIT_RUBIN (((long) 1)<<(RUBIN_REG_SIZE-1)) -#define LOWER_BITS_RUBIN ((((long) 1)<<(RUBIN_REG_SIZE-1))-1) - - -struct rubin_state { - unsigned long p; - unsigned long q; - unsigned long rec_q; - long bit_number; - struct pushpull pp; - int bit_divider; - int bits[8]; -}; diff --git a/components/dfs/filesystems/jffs2/src/compr_zlib.c b/components/dfs/filesystems/jffs2/src/compr_zlib.c deleted file mode 100644 index 7fe18e088c..0000000000 --- a/components/dfs/filesystems/jffs2/src/compr_zlib.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: compr_zlib.c,v 1.31 2005/05/20 19:30:06 gleixner Exp $ - * - */ -#include "jffs2_config.h" -#if !defined(__KERNEL__) && !defined(__ECOS) -#error "The userspace support got too messy and was removed. Update your mkfs.jffs2" -#endif - -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/zlib.h> -#include <linux/zutil.h> -#include "nodelist.h" -#include "compr.h" - - /* Plan: call deflate() with avail_in == *sourcelen, - avail_out = *dstlen - 12 and flush == Z_FINISH. - If it doesn't manage to finish, call it again with - avail_in == 0 and avail_out set to the remaining 12 - bytes for it to clean up. - Q: Is 12 bytes sufficient? - */ -#define STREAM_END_SPACE 12 - -static DECLARE_MUTEX(deflate_sem); -static DECLARE_MUTEX(inflate_sem); -static z_stream inf_strm, def_strm; - -#ifdef __KERNEL__ /* Linux-only */ -#include <linux/vmalloc.h> -#include <linux/init.h> - -static int __init alloc_workspaces(void) -{ - def_strm.workspace = vmalloc(zlib_deflate_workspacesize()); - if (!def_strm.workspace) { - printk(KERN_WARNING "Failed to allocate %d bytes for deflate workspace\n", zlib_deflate_workspacesize()); - return -ENOMEM; - } - D1(printk(KERN_DEBUG "Allocated %d bytes for deflate workspace\n", zlib_deflate_workspacesize())); - inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); - if (!inf_strm.workspace) { - printk(KERN_WARNING "Failed to allocate %d bytes for inflate workspace\n", zlib_inflate_workspacesize()); - vfree(def_strm.workspace); - return -ENOMEM; - } - D1(printk(KERN_DEBUG "Allocated %d bytes for inflate workspace\n", zlib_inflate_workspacesize())); - return 0; -} - -static void free_workspaces(void) -{ - vfree(def_strm.workspace); - vfree(inf_strm.workspace); -} -#else -#define alloc_workspaces() (0) -#define free_workspaces() do { } while(0) -#endif /* __KERNEL__ */ - -static int jffs2_zlib_compress(unsigned char *data_in, - unsigned char *cpage_out, - uint32_t *sourcelen, uint32_t *dstlen, - void *model) -{ - int ret; - - if (*dstlen <= STREAM_END_SPACE) - return -1; - - down(&deflate_sem); - - if (Z_OK != zlib_deflateInit(&def_strm, 3)) { - printk(KERN_WARNING "deflateInit failed\n"); - up(&deflate_sem); - return -1; - } - - def_strm.next_in = data_in; - def_strm.total_in = 0; - - def_strm.next_out = cpage_out; - def_strm.total_out = 0; - - while (def_strm.total_out < *dstlen - STREAM_END_SPACE && def_strm.total_in < *sourcelen) { - def_strm.avail_out = *dstlen - (def_strm.total_out + STREAM_END_SPACE); - def_strm.avail_in = min((unsigned)(*sourcelen-def_strm.total_in), def_strm.avail_out); - D1(printk(KERN_DEBUG "calling deflate with avail_in %d, avail_out %d\n", - def_strm.avail_in, def_strm.avail_out)); - ret = zlib_deflate(&def_strm, Z_PARTIAL_FLUSH); - D1(printk(KERN_DEBUG "deflate returned with avail_in %d, avail_out %d, total_in %ld, total_out %ld\n", - def_strm.avail_in, def_strm.avail_out, def_strm.total_in, def_strm.total_out)); - if (ret != Z_OK) { - D1(printk(KERN_DEBUG "deflate in loop returned %d\n", ret)); - zlib_deflateEnd(&def_strm); - up(&deflate_sem); - return -1; - } - } - def_strm.avail_out += STREAM_END_SPACE; - def_strm.avail_in = 0; - ret = zlib_deflate(&def_strm, Z_FINISH); - zlib_deflateEnd(&def_strm); - - if (ret != Z_STREAM_END) { - D1(printk(KERN_DEBUG "final deflate returned %d\n", ret)); - ret = -1; - goto out; - } - - if (def_strm.total_out >= def_strm.total_in) { - D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld; failing\n", - def_strm.total_in, def_strm.total_out)); - ret = -1; - goto out; - } - - D1(printk(KERN_DEBUG "zlib compressed %ld bytes into %ld\n", - def_strm.total_in, def_strm.total_out)); - - *dstlen = def_strm.total_out; - *sourcelen = def_strm.total_in; - ret = 0; - out: - up(&deflate_sem); - return ret; -} - -static int jffs2_zlib_decompress(unsigned char *data_in, - unsigned char *cpage_out, - uint32_t srclen, uint32_t destlen, - void *model) -{ - int ret; - int wbits = MAX_WBITS; - - down(&inflate_sem); - - inf_strm.next_in = data_in; - inf_strm.avail_in = srclen; - inf_strm.total_in = 0; - - inf_strm.next_out = cpage_out; - inf_strm.avail_out = destlen; - inf_strm.total_out = 0; - - /* If it's deflate, and it's got no preset dictionary, then - we can tell zlib to skip the adler32 check. */ - if (srclen > 2 && !(data_in[1] & PRESET_DICT) && - ((data_in[0] & 0x0f) == Z_DEFLATED) && - !(((data_in[0]<<8) + data_in[1]) % 31)) { - - D2(printk(KERN_DEBUG "inflate skipping adler32\n")); - wbits = -((data_in[0] >> 4) + 8); - inf_strm.next_in += 2; - inf_strm.avail_in -= 2; - } else { - /* Let this remain D1 for now -- it should never happen */ - D1(printk(KERN_DEBUG "inflate not skipping adler32\n")); - } - - - if (Z_OK != zlib_inflateInit2(&inf_strm, wbits)) { - printk(KERN_WARNING "inflateInit failed\n"); - up(&inflate_sem); - return 1; - } - - while((ret = zlib_inflate(&inf_strm, Z_FINISH)) == Z_OK) - ; - if (ret != Z_STREAM_END) { - printk(KERN_NOTICE "inflate returned %d\n", ret); - } - zlib_inflateEnd(&inf_strm); - up(&inflate_sem); - return 0; -} - -#if defined (__GNUC__) -static struct jffs2_compressor jffs2_zlib_comp = { - .priority = JFFS2_ZLIB_PRIORITY, - .name = "zlib", - .compr = JFFS2_COMPR_ZLIB, - .compress = &jffs2_zlib_compress, - .decompress = &jffs2_zlib_decompress, -#ifdef JFFS2_ZLIB_DISABLED - .disabled = 1, -#else - .disabled = 0, -#endif -}; -#elif defined (MSVC) -static struct jffs2_compressor jffs2_zlib_comp = { - {NULL}, - JFFS2_ZLIB_PRIORITY,//.priority = - "zlib",//.name = - JFFS2_COMPR_ZLIB,//.compr = - &jffs2_zlib_compress,//.compress = - &jffs2_zlib_decompress,//.decompress = - 0, -#ifdef JFFS2_ZLIB_DISABLED - 1,//.disabled = -#else - 0,//.disabled = -#endif - NULL, - 0, - 0, - 0, - 0, - 0 -}; -#else -#endif - -int __init jffs2_zlib_init(void) -{ - int ret; - - ret = alloc_workspaces(); - if (ret) - return ret; - - ret = jffs2_register_compressor(&jffs2_zlib_comp); - if (ret) - free_workspaces(); - - return ret; -} - -void jffs2_zlib_exit(void) -{ - jffs2_unregister_compressor(&jffs2_zlib_comp); - free_workspaces(); -} diff --git a/components/dfs/filesystems/jffs2/src/debug.c b/components/dfs/filesystems/jffs2/src/debug.c deleted file mode 100644 index 3a7c5ea6fc..0000000000 --- a/components/dfs/filesystems/jffs2/src/debug.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: debug.c,v 1.1 2005/07/30 15:30:42 asl Exp $ - * - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/pagemap.h> -#include <linux/crc32.h> -#include <linux/jffs2.h> -#include <linux/slab.h> -#include "nodelist.h" -#include "debug.h" - -#ifdef JFFS2_DBG_PARANOIA_CHECKS -/* - * Check the fragtree. - */ -void -__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f) -{ - down(&f->sem); - __jffs2_dbg_fragtree_paranoia_check_nolock(f); - up(&f->sem); -} - -void -__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f) -{ - struct jffs2_node_frag *frag; - int bitched = 0; - - for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) { - struct jffs2_full_dnode *fn = frag->node; - - if (!fn || !fn->raw) - continue; - - if (ref_flags(fn->raw) == REF_PRISTINE) { - if (fn->frags > 1) { - JFFS2_ERROR("REF_PRISTINE node at 0x%08x had %d frags. Tell dwmw2.\n", - ref_offset(fn->raw), fn->frags); - bitched = 1; - } - - /* A hole node which isn't multi-page should be garbage-collected - and merged anyway, so we just check for the frag size here, - rather than mucking around with actually reading the node - and checking the compression type, which is the real way - to tell a hole node. */ - if (frag->ofs & (PAGE_CACHE_SIZE-1) && frag_prev(frag) - && frag_prev(frag)->size < PAGE_CACHE_SIZE && frag_prev(frag)->node) { - JFFS2_ERROR("REF_PRISTINE node at 0x%08x had a previous non-hole frag " - "in the same page. Tell dwmw2.\n", ref_offset(fn->raw)); - bitched = 1; - } - - if ((frag->ofs+frag->size) & (PAGE_CACHE_SIZE-1) && frag_next(frag) - && frag_next(frag)->size < PAGE_CACHE_SIZE && frag_next(frag)->node) { - JFFS2_ERROR("REF_PRISTINE node at 0x%08x (%08x-%08x) had a following " - "non-hole frag in the same page. Tell dwmw2.\n", - ref_offset(fn->raw), frag->ofs, frag->ofs+frag->size); - bitched = 1; - } - } - } - - if (bitched) { - JFFS2_ERROR("fragtree is corrupted.\n"); - __jffs2_dbg_dump_fragtree_nolock(f); - BUG(); - } -} - -/* - * Check if the flash contains all 0xFF before we start writing. - */ -void -__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c, - uint32_t ofs, int len) -{ - size_t retlen; - int ret, i; - unsigned char *buf; - - buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return; - - ret = jffs2_flash_read(c, ofs, len, &retlen, buf); - if (ret || (retlen != len)) { - JFFS2_WARNING("read %d bytes failed or short. ret %d, retlen %zd.\n", - len, ret, retlen); - kfree(buf); - return; - } - - ret = 0; - for (i = 0; i < len; i++) - if (buf[i] != 0xff) - ret = 1; - - if (ret) { - JFFS2_ERROR("argh, about to write node to %#08x on flash, but there are data " - "already there. The first corrupted byte is at %#08x offset.\n", ofs, ofs + i); - __jffs2_dbg_dump_buffer(buf, len, ofs); - kfree(buf); - BUG(); - } - - kfree(buf); -} - -/* - * Check the space accounting and node_ref list correctness for the JFFS2 erasable block 'jeb'. - */ -void -__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb) -{ - spin_lock(&c->erase_completion_lock); - __jffs2_dbg_acct_paranoia_check_nolock(c, jeb); - spin_unlock(&c->erase_completion_lock); -} - -void -__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb) -{ - uint32_t my_used_size = 0; - uint32_t my_unchecked_size = 0; - uint32_t my_dirty_size = 0; - struct jffs2_raw_node_ref *ref2 = jeb->first_node; - - while (ref2) { - uint32_t totlen = ref_totlen(c, jeb, ref2); - - if (ref2->flash_offset < jeb->offset || - ref2->flash_offset > jeb->offset + c->sector_size) { - JFFS2_ERROR("node_ref %#08x shouldn't be in block at %#08x.\n", - ref_offset(ref2), jeb->offset); - goto error; - - } - if (ref_flags(ref2) == REF_UNCHECKED) - my_unchecked_size += totlen; - else if (!ref_obsolete(ref2)) - my_used_size += totlen; - else - my_dirty_size += totlen; - - if ((!ref2->next_phys) != (ref2 == jeb->last_node)) { - JFFS2_ERROR("node_ref for node at %#08x (mem %p) has next_phys at %#08x (mem %p), " - "last_node is at %#08x (mem %p).\n", - ref_offset(ref2), ref2, ref_offset(ref2->next_phys), ref2->next_phys, - ref_offset(jeb->last_node), jeb->last_node); - goto error; - } - ref2 = ref2->next_phys; - } - - if (my_used_size != jeb->used_size) { - JFFS2_ERROR("Calculated used size %#08x != stored used size %#08x.\n", - my_used_size, jeb->used_size); - goto error; - } - - if (my_unchecked_size != jeb->unchecked_size) { - JFFS2_ERROR("Calculated unchecked size %#08x != stored unchecked size %#08x.\n", - my_unchecked_size, jeb->unchecked_size); - goto error; - } - -#if 0 - /* This should work when we implement ref->__totlen elemination */ - if (my_dirty_size != jeb->dirty_size + jeb->wasted_size) { - JFFS2_ERROR("Calculated dirty+wasted size %#08x != stored dirty + wasted size %#08x\n", - my_dirty_size, jeb->dirty_size + jeb->wasted_size); - goto error; - } - - if (jeb->free_size == 0 - && my_used_size + my_unchecked_size + my_dirty_size != c->sector_size) { - JFFS2_ERROR("The sum of all nodes in block (%#x) != size of block (%#x)\n", - my_used_size + my_unchecked_size + my_dirty_size, - c->sector_size); - goto error; - } -#endif - - return; - -error: - __jffs2_dbg_dump_node_refs_nolock(c, jeb); - __jffs2_dbg_dump_jeb_nolock(jeb); - __jffs2_dbg_dump_block_lists_nolock(c); - BUG(); - -} -#endif /* JFFS2_DBG_PARANOIA_CHECKS */ - -#if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS) -/* - * Dump the node_refs of the 'jeb' JFFS2 eraseblock. - */ -void -__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb) -{ - spin_lock(&c->erase_completion_lock); - __jffs2_dbg_dump_node_refs_nolock(c, jeb); - spin_unlock(&c->erase_completion_lock); -} - -void -__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb) -{ - struct jffs2_raw_node_ref *ref; - int i = 0; - - JFFS2_DEBUG("Dump node_refs of the eraseblock %#08x\n", jeb->offset); - if (!jeb->first_node) { - JFFS2_DEBUG("no nodes in the eraseblock %#08x\n", jeb->offset); - return; - } - - printk(JFFS2_DBG_LVL); - for (ref = jeb->first_node; ; ref = ref->next_phys) { - printk("%#08x(%#x)", ref_offset(ref), ref->__totlen); - if (ref->next_phys) - printk("->"); - else - break; - if (++i == 4) { - i = 0; - printk("\n" JFFS2_DBG_LVL); - } - } - printk("\n"); -} - -/* - * Dump an eraseblock's space accounting. - */ -void -__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) -{ - spin_lock(&c->erase_completion_lock); - __jffs2_dbg_dump_jeb_nolock(jeb); - spin_unlock(&c->erase_completion_lock); -} - -void -__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb) -{ - if (!jeb) - return; - - JFFS2_DEBUG("dump space accounting for the eraseblock at %#08x:\n", - jeb->offset); - - printk(JFFS2_DBG_LVL "used_size: %#08x\n", jeb->used_size); - printk(JFFS2_DBG_LVL "dirty_size: %#08x\n", jeb->dirty_size); - printk(JFFS2_DBG_LVL "wasted_size: %#08x\n", jeb->wasted_size); - printk(JFFS2_DBG_LVL "unchecked_size: %#08x\n", jeb->unchecked_size); - printk(JFFS2_DBG_LVL "free_size: %#08x\n", jeb->free_size); -} - -void -__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c) -{ - spin_lock(&c->erase_completion_lock); - __jffs2_dbg_dump_block_lists_nolock(c); - spin_unlock(&c->erase_completion_lock); -} - -void -__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c) -{ - JFFS2_DEBUG("dump JFFS2 blocks lists:\n"); - - printk(JFFS2_DBG_LVL "flash_size: %#08x\n", c->flash_size); - printk(JFFS2_DBG_LVL "used_size: %#08x\n", c->used_size); - printk(JFFS2_DBG_LVL "dirty_size: %#08x\n", c->dirty_size); - printk(JFFS2_DBG_LVL "wasted_size: %#08x\n", c->wasted_size); - printk(JFFS2_DBG_LVL "unchecked_size: %#08x\n", c->unchecked_size); - printk(JFFS2_DBG_LVL "free_size: %#08x\n", c->free_size); - printk(JFFS2_DBG_LVL "erasing_size: %#08x\n", c->erasing_size); - printk(JFFS2_DBG_LVL "bad_size: %#08x\n", c->bad_size); - printk(JFFS2_DBG_LVL "sector_size: %#08x\n", c->sector_size); - printk(JFFS2_DBG_LVL "jffs2_reserved_blocks size: %#08x\n", - c->sector_size * c->resv_blocks_write); - - if (c->nextblock) - printk(JFFS2_DBG_LVL "nextblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - c->nextblock->offset, c->nextblock->used_size, - c->nextblock->dirty_size, c->nextblock->wasted_size, - c->nextblock->unchecked_size, c->nextblock->free_size); - else - printk(JFFS2_DBG_LVL "nextblock: NULL\n"); - - if (c->gcblock) - printk(JFFS2_DBG_LVL "gcblock: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - c->gcblock->offset, c->gcblock->used_size, c->gcblock->dirty_size, - c->gcblock->wasted_size, c->gcblock->unchecked_size, c->gcblock->free_size); - else - printk(JFFS2_DBG_LVL "gcblock: NULL\n"); - - if (list_empty(&c->clean_list)) { - printk(JFFS2_DBG_LVL "clean_list: empty\n"); - } else { - struct list_head *this; - int numblocks = 0; - uint32_t dirty = 0; - - list_for_each(this, &c->clean_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - numblocks ++; - dirty += jeb->wasted_size; - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "clean_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - - printk (JFFS2_DBG_LVL "Contains %d blocks with total wasted size %u, average wasted size: %u\n", - numblocks, dirty, dirty / numblocks); - } - - if (list_empty(&c->very_dirty_list)) { - printk(JFFS2_DBG_LVL "very_dirty_list: empty\n"); - } else { - struct list_head *this; - int numblocks = 0; - uint32_t dirty = 0; - - list_for_each(this, &c->very_dirty_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - numblocks ++; - dirty += jeb->dirty_size; - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "very_dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - - printk (JFFS2_DBG_LVL "Contains %d blocks with total dirty size %u, average dirty size: %u\n", - numblocks, dirty, dirty / numblocks); - } - - if (list_empty(&c->dirty_list)) { - printk(JFFS2_DBG_LVL "dirty_list: empty\n"); - } else { - struct list_head *this; - int numblocks = 0; - uint32_t dirty = 0; - - list_for_each(this, &c->dirty_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - numblocks ++; - dirty += jeb->dirty_size; - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "dirty_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - - printk (JFFS2_DBG_LVL "contains %d blocks with total dirty size %u, average dirty size: %u\n", - numblocks, dirty, dirty / numblocks); - } - - if (list_empty(&c->erasable_list)) { - printk(JFFS2_DBG_LVL "erasable_list: empty\n"); - } else { - struct list_head *this; - - list_for_each(this, &c->erasable_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "erasable_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - } - - if (list_empty(&c->erasing_list)) { - printk(JFFS2_DBG_LVL "erasing_list: empty\n"); - } else { - struct list_head *this; - - list_for_each(this, &c->erasing_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "erasing_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - } - - if (list_empty(&c->erase_pending_list)) { - printk(JFFS2_DBG_LVL "erase_pending_list: empty\n"); - } else { - struct list_head *this; - - list_for_each(this, &c->erase_pending_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "erase_pending_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - } - - if (list_empty(&c->erasable_pending_wbuf_list)) { - printk(JFFS2_DBG_LVL "erasable_pending_wbuf_list: empty\n"); - } else { - struct list_head *this; - - list_for_each(this, &c->erasable_pending_wbuf_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "erasable_pending_wbuf_list: %#08x (used %#08x, dirty %#08x, " - "wasted %#08x, unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - } - - if (list_empty(&c->free_list)) { - printk(JFFS2_DBG_LVL "free_list: empty\n"); - } else { - struct list_head *this; - - list_for_each(this, &c->free_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "free_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - } - - if (list_empty(&c->bad_list)) { - printk(JFFS2_DBG_LVL "bad_list: empty\n"); - } else { - struct list_head *this; - - list_for_each(this, &c->bad_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "bad_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - } - - if (list_empty(&c->bad_used_list)) { - printk(JFFS2_DBG_LVL "bad_used_list: empty\n"); - } else { - struct list_head *this; - - list_for_each(this, &c->bad_used_list) { - struct jffs2_eraseblock *jeb = list_entry(this, struct jffs2_eraseblock, list); - - if (!(jeb->used_size == 0 && jeb->dirty_size == 0 && jeb->wasted_size == 0)) { - printk(JFFS2_DBG_LVL "bad_used_list: %#08x (used %#08x, dirty %#08x, wasted %#08x, " - "unchecked %#08x, free %#08x)\n", - jeb->offset, jeb->used_size, jeb->dirty_size, jeb->wasted_size, - jeb->unchecked_size, jeb->free_size); - } - } - } -} - -void -__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f) -{ - down(&f->sem); - jffs2_dbg_dump_fragtree_nolock(f); - up(&f->sem); -} - -void -__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f) -{ - struct jffs2_node_frag *this = frag_first(&f->fragtree); - uint32_t lastofs = 0; - int buggy = 0; - - JFFS2_DEBUG("dump fragtree of ino #%u\n", f->inocache->ino); - while(this) { - if (this->node) - printk(JFFS2_DBG_LVL "frag %#04x-%#04x: %#08x(%d) on flash (*%p), left (%p), " - "right (%p), parent (%p)\n", - this->ofs, this->ofs+this->size, ref_offset(this->node->raw), - ref_flags(this->node->raw), this, frag_left(this), frag_right(this), - frag_parent(this)); - else - printk(JFFS2_DBG_LVL "frag %#04x-%#04x: hole (*%p). left (%p), right (%p), parent (%p)\n", - this->ofs, this->ofs+this->size, this, frag_left(this), - frag_right(this), frag_parent(this)); - if (this->ofs != lastofs) - buggy = 1; - lastofs = this->ofs + this->size; - this = frag_next(this); - } - - if (f->metadata) - printk(JFFS2_DBG_LVL "metadata at 0x%08x\n", ref_offset(f->metadata->raw)); - - if (buggy) { - JFFS2_ERROR("frag tree got a hole in it.\n"); - BUG(); - } -} - -#define JFFS2_BUFDUMP_BYTES_PER_LINE 32 -void -__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs) -{ - int skip; - int i; - - JFFS2_DEBUG("dump from offset %#08x to offset %#08x (%x bytes).\n", - offs, offs + len, len); - i = skip = offs % JFFS2_BUFDUMP_BYTES_PER_LINE; - offs = offs & ~(JFFS2_BUFDUMP_BYTES_PER_LINE - 1); - - if (skip != 0) - printk(JFFS2_DBG_LVL "%#08x: ", offs); - - while (skip--) - printk(" "); - - while (i < len) { - if ((i % JFFS2_BUFDUMP_BYTES_PER_LINE) == 0 && i != len -1) { - if (i != 0) - printk("\n"); - offs += JFFS2_BUFDUMP_BYTES_PER_LINE; - printk(JFFS2_DBG_LVL "%0#8x: ", offs); - } - - printk("%02x ", buf[i]); - - i += 1; - } - - printk("\n"); -} - -/* - * Dump a JFFS2 node. - */ -void -__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs) -{ - union jffs2_node_union node; - int len = sizeof(union jffs2_node_union); - size_t retlen; - uint32_t crc; - int ret; - - JFFS2_DEBUG("dump node at offset %#08x.\n", ofs); - - ret = jffs2_flash_read(c, ofs, len, &retlen, (unsigned char *)&node); - if (ret || (retlen != len)) { - JFFS2_ERROR("read %d bytes failed or short. ret %d, retlen %zd.\n", - len, ret, retlen); - return; - } - - printk(JFFS2_DBG_LVL "magic:\t%#04x\n", - je16_to_cpu(node.u.magic)); - printk(JFFS2_DBG_LVL "nodetype:\t%#04x\n", - je16_to_cpu(node.u.nodetype)); - printk(JFFS2_DBG_LVL "totlen:\t%#08x\n", - je32_to_cpu(node.u.totlen)); - printk(JFFS2_DBG_LVL "hdr_crc:\t%#08x\n", - je32_to_cpu(node.u.hdr_crc)); - - crc = crc32(0, &node.u, sizeof(node.u) - 4); - if (crc != je32_to_cpu(node.u.hdr_crc)) { - JFFS2_ERROR("wrong common header CRC.\n"); - return; - } - - if (je16_to_cpu(node.u.magic) != JFFS2_MAGIC_BITMASK && - je16_to_cpu(node.u.magic) != JFFS2_OLD_MAGIC_BITMASK) - { - JFFS2_ERROR("wrong node magic: %#04x instead of %#04x.\n", - je16_to_cpu(node.u.magic), JFFS2_MAGIC_BITMASK); - return; - } - - switch(je16_to_cpu(node.u.nodetype)) { - - case JFFS2_NODETYPE_INODE: - - printk(JFFS2_DBG_LVL "the node is inode node\n"); - printk(JFFS2_DBG_LVL "ino:\t%#08x\n", - je32_to_cpu(node.i.ino)); - printk(JFFS2_DBG_LVL "version:\t%#08x\n", - je32_to_cpu(node.i.version)); - printk(JFFS2_DBG_LVL "mode:\t%#08x\n", - node.i.mode.m); - printk(JFFS2_DBG_LVL "uid:\t%#04x\n", - je16_to_cpu(node.i.uid)); - printk(JFFS2_DBG_LVL "gid:\t%#04x\n", - je16_to_cpu(node.i.gid)); - printk(JFFS2_DBG_LVL "isize:\t%#08x\n", - je32_to_cpu(node.i.isize)); - printk(JFFS2_DBG_LVL "atime:\t%#08x\n", - je32_to_cpu(node.i.atime)); - printk(JFFS2_DBG_LVL "mtime:\t%#08x\n", - je32_to_cpu(node.i.mtime)); - printk(JFFS2_DBG_LVL "ctime:\t%#08x\n", - je32_to_cpu(node.i.ctime)); - printk(JFFS2_DBG_LVL "offset:\t%#08x\n", - je32_to_cpu(node.i.offset)); - printk(JFFS2_DBG_LVL "csize:\t%#08x\n", - je32_to_cpu(node.i.csize)); - printk(JFFS2_DBG_LVL "dsize:\t%#08x\n", - je32_to_cpu(node.i.dsize)); - printk(JFFS2_DBG_LVL "compr:\t%#02x\n", - node.i.compr); - printk(JFFS2_DBG_LVL "usercompr:\t%#02x\n", - node.i.usercompr); - printk(JFFS2_DBG_LVL "flags:\t%#04x\n", - je16_to_cpu(node.i.flags)); - printk(JFFS2_DBG_LVL "data_crc:\t%#08x\n", - je32_to_cpu(node.i.data_crc)); - printk(JFFS2_DBG_LVL "node_crc:\t%#08x\n", - je32_to_cpu(node.i.node_crc)); - crc = crc32(0, &node.i, sizeof(node.i) - 8); - if (crc != je32_to_cpu(node.i.node_crc)) { - JFFS2_ERROR("wrong node header CRC.\n"); - return; - } - break; - - case JFFS2_NODETYPE_DIRENT: - - printk(JFFS2_DBG_LVL "the node is dirent node\n"); - printk(JFFS2_DBG_LVL "pino:\t%#08x\n", - je32_to_cpu(node.d.pino)); - printk(JFFS2_DBG_LVL "version:\t%#08x\n", - je32_to_cpu(node.d.version)); - printk(JFFS2_DBG_LVL "ino:\t%#08x\n", - je32_to_cpu(node.d.ino)); - printk(JFFS2_DBG_LVL "mctime:\t%#08x\n", - je32_to_cpu(node.d.mctime)); - printk(JFFS2_DBG_LVL "nsize:\t%#02x\n", - node.d.nsize); - printk(JFFS2_DBG_LVL "type:\t%#02x\n", - node.d.type); - printk(JFFS2_DBG_LVL "node_crc:\t%#08x\n", - je32_to_cpu(node.d.node_crc)); - printk(JFFS2_DBG_LVL "name_crc:\t%#08x\n", - je32_to_cpu(node.d.name_crc)); - - node.d.name[node.d.nsize] = '\0'; - printk(JFFS2_DBG_LVL "name:\t\"%s\"\n", node.d.name); - - crc = crc32(0, &node.d, sizeof(node.d) - 8); - if (crc != je32_to_cpu(node.d.node_crc)) { - JFFS2_ERROR("wrong node header CRC.\n"); - return; - } - break; - - default: - printk(JFFS2_DBG_LVL "node type is unknown\n"); - break; - } -} -#endif /* JFFS2_DBG_DUMPS || JFFS2_DBG_PARANOIA_CHECKS */ diff --git a/components/dfs/filesystems/jffs2/src/debug.h b/components/dfs/filesystems/jffs2/src/debug.h deleted file mode 100644 index 652f59068d..0000000000 --- a/components/dfs/filesystems/jffs2/src/debug.h +++ /dev/null @@ -1,276 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: debug.h,v 1.1 2005/07/30 15:30:42 asl Exp $ - * - */ -#ifndef _JFFS2_DEBUG_H_ -#define _JFFS2_DEBUG_H_ -#include "jffs2_config.h" -#include <linux/config.h> - -#ifndef CONFIG_JFFS2_FS_DEBUG -#define CONFIG_JFFS2_FS_DEBUG 0 -#endif - -#if CONFIG_JFFS2_FS_DEBUG == 1 -/* Enable "paranoia" checks and dumps */ -#define JFFS2_DBG_PARANOIA_CHECKS -#define JFFS2_DBG_DUMPS -#define JFFS2_DBG_READINODE_MESSAGES -#define JFFS2_DBG_FRAGTREE_MESSAGES -#define JFFS2_DBG_DENTLIST_MESSAGES -#define JFFS2_DBG_NODEREF_MESSAGES -#define JFFS2_DBG_INOCACHE_MESSAGES -#endif - -#if CONFIG_JFFS2_FS_DEBUG == 2 -#define JFFS2_DBG_FRAGTREE2_MESSAGES -#endif - -/* Enable JFFS2 sanity checks by default */ -#define JFFS2_DBG_SANITY_CHECKS - -/* - * Dx() are mainly used for debugging messages, they must go away and be - * superseded by nicer JFFS2_DBG_XXX() macros... - */ -#if CONFIG_JFFS2_FS_DEBUG > 0 -#define D1(x) x -#else -#define D1(x) -#endif - -#if CONFIG_JFFS2_FS_DEBUG > 1 -#define D2(x) x -#else -#define D2(x) -#endif - -/* The prefixes of JFFS2 messages */ -#define JFFS2_DBG_MSG_PREFIX "[JFFS2 DBG]" -#define JFFS2_ERR_MSG_PREFIX "JFFS2 error: " -#define JFFS2_WARN_MSG_PREFIX "JFFS2 warning: " -#define JFFS2_NOTICE_MSG_PREFIX "JFFS2 notice: " - -#define JFFS2_ERR_LVL KERN_ERR -#define JFFS2_WARN_LVL KERN_WARNING -#define JFFS2_NOTICE_LVL KERN_NOTICE -#define JFFS2_DBG_LVL KERN_DEBUG - -/* JFFS2 message macros */ -#define JFFS2_ERROR(fmt, ...) \ - do { \ - printk(JFFS2_ERR_LVL JFFS2_ERR_MSG_PREFIX " %s: " \ - fmt, __FUNCTION__, ##__VA_ARGS__); \ - } while(0) - -#define JFFS2_WARNING(fmt, ...) \ - do { \ - printk(JFFS2_WARN_LVL JFFS2_WARN_MSG_PREFIX " %s: " \ - fmt, __FUNCTION__, ##__VA_ARGS__); \ - } while(0) - -#define JFFS2_NOTICE(fmt, ...) \ - do { \ - printk(JFFS2_NOTICE_LVL JFFS2_NOTICE_MSG_PREFIX " %s: " \ - fmt, __FUNCTION__, ##__VA_ARGS__); \ - } while(0) - -#define JFFS2_DEBUG(fmt, ...) \ - do { \ - printk(JFFS2_DBG_LVL JFFS2_DBG_MSG_PREFIX " %s: " \ - fmt, __FUNCTION__, ##__VA_ARGS__); \ - } while(0) - -/* - * We split our debugging messages on several parts, depending on the JFFS2 - * subsystem the message belongs to. - */ -/* Read inode debugging messages */ -#ifdef JFFS2_DBG_READINODE_MESSAGES -#define JFFS2_DBG_READINODE(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) -#else -#define JFFS2_DBG_READINODE(fmt, ...) -#endif - -/* Fragtree build debugging messages */ -#ifdef JFFS2_DBG_FRAGTREE_MESSAGES -#define JFFS2_DBG_FRAGTREE(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) -#else -#define JFFS2_DBG_FRAGTREE(fmt, ...) -#endif - -/* Directory entry list manilulation debugging messages */ -#ifdef JFFS2_DBG_DENTLIST_MESSAGES -#define JFFS2_DBG_DENTLIST(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) -#else -#define JFFS2_DBG_DENTLIST(fmt, ...) -#endif -#ifdef JFFS2_DBG_FRAGTREE2_MESSAGES -#define JFFS2_DBG_FRAGTREE2(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) -#else -#define JFFS2_DBG_FRAGTREE2(fmt, ...) -#endif - -/* Print the messages about manipulating node_refs */ -#ifdef JFFS2_DBG_NODEREF_MESSAGES -#define JFFS2_DBG_NODEREF(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) -#else -#define JFFS2_DBG_NODEREF(fmt, ...) -#endif - -/* Manipulations with the list of inodes (JFFS2 inocache) */ -#ifdef JFFS2_DBG_INOCACHE_MESSAGES -#define JFFS2_DBG_INOCACHE(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) -#else -#define JFFS2_DBG_INOCACHE(fmt, ...) -#endif - -/* Watch the object allocations */ -#ifdef JFFS2_DBG_MEMALLOC_MESSAGES -#define JFFS2_DBG_MEMALLOC(fmt, ...) JFFS2_DEBUG(fmt, ##__VA_ARGS__) -#else -#define JFFS2_DBG_MEMALLOC(fmt, ...) -#endif - - -/* "Paranoia" checks */ -void -__jffs2_dbg_fragtree_paranoia_check(struct jffs2_inode_info *f); -void -__jffs2_dbg_fragtree_paranoia_check_nolock(struct jffs2_inode_info *f); -void -__jffs2_dbg_acct_paranoia_check(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb); -void -__jffs2_dbg_acct_paranoia_check_nolock(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb); -void -__jffs2_dbg_prewrite_paranoia_check(struct jffs2_sb_info *c, - uint32_t ofs, int len); - -/* "Dump" functions */ -void -__jffs2_dbg_dump_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); -void -__jffs2_dbg_dump_jeb_nolock(struct jffs2_eraseblock *jeb); -void -__jffs2_dbg_dump_block_lists(struct jffs2_sb_info *c); -void -__jffs2_dbg_dump_block_lists_nolock(struct jffs2_sb_info *c); -void -__jffs2_dbg_dump_node_refs(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb); -void -__jffs2_dbg_dump_node_refs_nolock(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb); -void -__jffs2_dbg_dump_fragtree(struct jffs2_inode_info *f); -void -__jffs2_dbg_dump_fragtree_nolock(struct jffs2_inode_info *f); -void -__jffs2_dbg_dump_buffer(unsigned char *buf, int len, uint32_t offs); -void -__jffs2_dbg_dump_node(struct jffs2_sb_info *c, uint32_t ofs); - -#ifdef JFFS2_DBG_PARANOIA_CHECKS -#define jffs2_dbg_fragtree_paranoia_check(f) \ - __jffs2_dbg_fragtree_paranoia_check(f) -#define jffs2_dbg_fragtree_paranoia_check_nolock(f) \ - __jffs2_dbg_fragtree_paranoia_check_nolock(f) -#define jffs2_dbg_acct_paranoia_check(c, jeb) \ - __jffs2_dbg_acct_paranoia_check(c,jeb) -#define jffs2_dbg_acct_paranoia_check_nolock(c, jeb) \ - __jffs2_dbg_acct_paranoia_check_nolock(c,jeb) -#define jffs2_dbg_prewrite_paranoia_check(c, ofs, len) \ - __jffs2_dbg_prewrite_paranoia_check(c, ofs, len) -#else -#define jffs2_dbg_fragtree_paranoia_check(f) -#define jffs2_dbg_fragtree_paranoia_check_nolock(f) -#define jffs2_dbg_acct_paranoia_check(c, jeb) -#define jffs2_dbg_acct_paranoia_check_nolock(c, jeb) -#define jffs2_dbg_prewrite_paranoia_check(c, ofs, len) -#endif /* !JFFS2_PARANOIA_CHECKS */ - -#ifdef JFFS2_DBG_DUMPS -#define jffs2_dbg_dump_jeb(c, jeb) \ - __jffs2_dbg_dump_jeb(c, jeb); -#define jffs2_dbg_dump_jeb_nolock(jeb) \ - __jffs2_dbg_dump_jeb_nolock(jeb); -#define jffs2_dbg_dump_block_lists(c) \ - __jffs2_dbg_dump_block_lists(c) -#define jffs2_dbg_dump_block_lists_nolock(c) \ - __jffs2_dbg_dump_block_lists_nolock(c) -#define jffs2_dbg_dump_fragtree(f) \ - __jffs2_dbg_dump_fragtree(f); -#define jffs2_dbg_dump_fragtree_nolock(f) \ - __jffs2_dbg_dump_fragtree_nolock(f); -#define jffs2_dbg_dump_buffer(buf, len, offs) \ - __jffs2_dbg_dump_buffer(*buf, len, offs); -#define jffs2_dbg_dump_node(c, ofs) \ - __jffs2_dbg_dump_node(c, ofs); -#else -#define jffs2_dbg_dump_jeb(c, jeb) -#define jffs2_dbg_dump_jeb_nolock(jeb) -#define jffs2_dbg_dump_block_lists(c) -#define jffs2_dbg_dump_block_lists_nolock(c) -#define jffs2_dbg_dump_fragtree(f) -#define jffs2_dbg_dump_fragtree_nolock(f) -#define jffs2_dbg_dump_buffer(buf, len, offs) -#define jffs2_dbg_dump_node(c, ofs) -#endif /* !JFFS2_DBG_DUMPS */ - -/* - * Sanity checks are supposed to be light-weight and enabled by default. - */ -#ifdef JFFS2_DBG_SANITY_CHECKS -/* - * Check the space accounting of the file system and of - * the JFFS2 erasable block 'jeb'. - */ -static inline void -jffs2_dbg_acct_sanity_check_nolock(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb) -{ - if (unlikely(jeb && jeb->used_size + jeb->dirty_size + - jeb->free_size + jeb->wasted_size + - jeb->unchecked_size != c->sector_size)) { - JFFS2_ERROR("eeep, space accounting for block at 0x%08x is screwed.\n", jeb->offset); - JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + wasted %#08x + unchecked " - "%#08x != total %#08x.\n", jeb->free_size, jeb->dirty_size, jeb->used_size, - jeb->wasted_size, jeb->unchecked_size, c->sector_size); - BUG(); - } - - if (unlikely(c->used_size + c->dirty_size + c->free_size + c->erasing_size + c->bad_size - + c->wasted_size + c->unchecked_size != c->flash_size)) { - JFFS2_ERROR("eeep, space accounting superblock info is screwed.\n"); - JFFS2_ERROR("free %#08x + dirty %#08x + used %#08x + erasing %#08x + bad %#08x + " - "wasted %#08x + unchecked %#08x != total %#08x.\n", - c->free_size, c->dirty_size, c->used_size, c->erasing_size, c->bad_size, - c->wasted_size, c->unchecked_size, c->flash_size); - BUG(); - } -} - -static inline void -jffs2_dbg_acct_sanity_check(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb) -{ - spin_lock(&c->erase_completion_lock); - jffs2_dbg_acct_sanity_check_nolock(c, jeb); - spin_unlock(&c->erase_completion_lock); -} -#else -#define jffs2_dbg_acct_sanity_check(c, jeb) -#define jffs2_dbg_acct_sanity_check_nolock(c, jeb) -#endif /* !JFFS2_DBG_SANITY_CHECKS */ - -#endif /* _JFFS2_DEBUG_H_ */ diff --git a/components/dfs/filesystems/jffs2/src/dir-ecos.c b/components/dfs/filesystems/jffs2/src/dir-ecos.c deleted file mode 100644 index b52b89928f..0000000000 --- a/components/dfs/filesystems/jffs2/src/dir-ecos.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Free Software Foundation, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: dir-ecos.c,v 1.11 2005/02/08 19:36:27 lunn Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/crc32.h> -#include "nodelist.h" - -/***********************************************************************/ - -/* Takes length argument because it can be either NUL-terminated or '/'-terminated */ -struct _inode *jffs2_lookup(struct _inode *dir_i, const unsigned char *d_name, int namelen) -{ - struct jffs2_inode_info *dir_f; - struct jffs2_full_dirent *fd = NULL, *fd_list; - uint32_t ino = 0; - uint32_t hash = full_name_hash(d_name, namelen); - struct _inode *inode = NULL; - - D1(printk("jffs2_lookup()\n")); - - dir_f = JFFS2_INODE_INFO(dir_i); - - down(&dir_f->sem); - - /* NB: The 2.2 backport will need to explicitly check for '.' and '..' here */ - for (fd_list = dir_f->dents; fd_list && fd_list->nhash <= hash; fd_list = fd_list->next) { - if (fd_list->nhash == hash && - (!fd || fd_list->version > fd->version) && - strlen((char *)fd_list->name) == namelen && - !strncmp((char *)fd_list->name, (char *)d_name, namelen)) { - fd = fd_list; - } - } - if (fd) - ino = fd->ino; - up(&dir_f->sem); - if (ino) { - inode = jffs2_iget(dir_i->i_sb, ino); - if (IS_ERR(inode)) { - printk("jffs2_iget() failed for ino #%u\n", ino); - return inode; - } - } - - return inode; -} - -/***********************************************************************/ - - - -int jffs2_create(struct _inode *dir_i, const unsigned char *d_name, int mode, - struct _inode **new_i) -{ - struct jffs2_raw_inode *ri; - struct jffs2_inode_info *f, *dir_f; - struct jffs2_sb_info *c; - struct _inode *inode; - int ret; - - ri = jffs2_alloc_raw_inode(); - if (!ri) - return -ENOMEM; - - c = JFFS2_SB_INFO(dir_i->i_sb); - - D1(printk(KERN_DEBUG "jffs2_create()\n")); - - inode = jffs2_new_inode(dir_i, mode, ri); - - if (IS_ERR(inode)) { - D1(printk(KERN_DEBUG "jffs2_new_inode() failed\n")); - jffs2_free_raw_inode(ri); - return PTR_ERR(inode); - } - - f = JFFS2_INODE_INFO(inode); - dir_f = JFFS2_INODE_INFO(dir_i); - - ret = jffs2_do_create(c, dir_f, f, ri, - (const char *)d_name, - strlen((char *)d_name)); - - if (ret) { - inode->i_nlink = 0; - jffs2_iput(inode); - jffs2_free_raw_inode(ri); - return ret; - } - - jffs2_free_raw_inode(ri); - - D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d)\n", - inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink)); - *new_i = inode; - return 0; -} - -/***********************************************************************/ - - -int jffs2_unlink(struct _inode *dir_i, struct _inode *d_inode, const unsigned char *d_name) -{ - struct jffs2_sb_info *c = JFFS2_SB_INFO(dir_i->i_sb); - struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); - struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(d_inode); - int ret; - - ret = jffs2_do_unlink(c, dir_f, (const char *)d_name, - strlen((char *)d_name), dead_f); - if (dead_f->inocache) - d_inode->i_nlink = dead_f->inocache->nlink; - return ret; -} -/***********************************************************************/ - - -int jffs2_link (struct _inode *old_d_inode, struct _inode *dir_i, const unsigned char *d_name) -{ - struct jffs2_sb_info *c = JFFS2_SB_INFO(old_d_inode->i_sb); - struct jffs2_inode_info *f = JFFS2_INODE_INFO(old_d_inode); - struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); - int ret; - - /* XXX: This is ugly */ - uint8_t type = (old_d_inode->i_mode & S_IFMT) >> 12; - if (!type) type = DT_REG; - - ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, - (const char * )d_name, - strlen((char *)d_name)); - - if (!ret) { - down(&f->sem); - old_d_inode->i_nlink = ++f->inocache->nlink; - up(&f->sem); - } - return ret; -} - -int jffs2_mkdir (struct _inode *dir_i, const unsigned char *d_name, int mode) -{ - struct jffs2_inode_info *f, *dir_f; - struct jffs2_sb_info *c; - struct _inode *inode; - struct jffs2_raw_inode *ri; - struct jffs2_raw_dirent *rd; - struct jffs2_full_dnode *fn; - struct jffs2_full_dirent *fd; - int namelen; - uint32_t alloclen, phys_ofs; - int ret; - - mode |= S_IFDIR; - - ri = jffs2_alloc_raw_inode(); - if (!ri) - return -ENOMEM; - - c = JFFS2_SB_INFO(dir_i->i_sb); - - /* Try to reserve enough space for both node and dirent. - * Just the node will do for now, though - */ - namelen = strlen((char *)d_name); - ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); - - if (ret) { - jffs2_free_raw_inode(ri); - return ret; - } - - inode = jffs2_new_inode(dir_i, mode, ri); - - if (IS_ERR(inode)) { - jffs2_free_raw_inode(ri); - jffs2_complete_reservation(c); - return PTR_ERR(inode); - } - - f = JFFS2_INODE_INFO(inode); - - ri->data_crc = cpu_to_je32(0); - ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); - - fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); - - jffs2_free_raw_inode(ri); - - if (IS_ERR(fn)) { - /* Eeek. Wave bye bye */ - up(&f->sem); - jffs2_complete_reservation(c); - inode->i_nlink = 0; - jffs2_iput(inode); - return PTR_ERR(fn); - } - /* No data here. Only a metadata node, which will be - obsoleted by the first data write - */ - f->metadata = fn; - up(&f->sem); - - jffs2_complete_reservation(c); - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); - if (ret) { - /* Eep. */ - inode->i_nlink = 0; - jffs2_iput(inode); - return ret; - } - - rd = jffs2_alloc_raw_dirent(); - if (!rd) { - /* Argh. Now we treat it like a normal delete */ - jffs2_complete_reservation(c); - inode->i_nlink = 0; - jffs2_iput(inode); - return -ENOMEM; - } - - dir_f = JFFS2_INODE_INFO(dir_i); - down(&dir_f->sem); - - rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); - rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); - rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); - - rd->pino = cpu_to_je32(dir_i->i_ino); - rd->version = cpu_to_je32(++dir_f->highest_version); - rd->ino = cpu_to_je32(inode->i_ino); - rd->mctime = cpu_to_je32(jffs2_get_timestamp()); - rd->nsize = namelen; - rd->type = DT_DIR; - rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); - rd->name_crc = cpu_to_je32(crc32(0, d_name, namelen)); - - fd = jffs2_write_dirent(c, dir_f, rd, d_name, namelen, phys_ofs, ALLOC_NORMAL); - - jffs2_complete_reservation(c); - jffs2_free_raw_dirent(rd); - - if (IS_ERR(fd)) { - /* dirent failed to write. Delete the inode normally - as if it were the final unlink() */ - up(&dir_f->sem); - inode->i_nlink = 0; - jffs2_iput(inode); - return PTR_ERR(fd); - } - - /* Link the fd into the inode's list, obsoleting an old - one if necessary. */ - jffs2_add_fd_to_list(c, fd, &dir_f->dents); - up(&dir_f->sem); - - jffs2_iput(inode); - return 0; -} - -int jffs2_rmdir (struct _inode *dir_i, struct _inode *d_inode, const unsigned char *d_name) -{ - struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode); - struct jffs2_full_dirent *fd; - - for (fd = f->dents ; fd; fd = fd->next) { - if (fd->ino) - return EPERM; //-ENOTEMPTY; - } - return jffs2_unlink(dir_i, d_inode, 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) -{ - int ret; - struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); - struct jffs2_inode_info *victim_f = NULL; - uint8_t type; - -#if 0 /* FIXME -- this really doesn't belong in individual file systems. - The fileio code ought to do this for us, or at least part of it */ - if (new_dentry->d_inode) { - if (S_ISDIR(d_inode->i_mode) && - !S_ISDIR(new_dentry->d_inode->i_mode)) { - /* Cannot rename directory over non-directory */ - return -EINVAL; - } - - victim_f = JFFS2_INODE_INFO(new_dentry->d_inode); - - if (S_ISDIR(new_dentry->d_inode->i_mode)) { - struct jffs2_full_dirent *fd; - - if (!S_ISDIR(d_inode->i_mode)) { - /* Cannot rename non-directory over directory */ - return -EINVAL; - } - down(&victim_f->sem); - for (fd = victim_f->dents; fd; fd = fd->next) { - if (fd->ino) { - up(&victim_f->sem); - return -ENOTEMPTY; - } - } - up(&victim_f->sem); - } - } -#endif - - /* XXX: We probably ought to alloc enough space for - both nodes at the same time. Writing the new link, - then getting -ENOSPC, is quite bad :) - */ - - /* Make a hard link */ - - /* XXX: This is ugly */ - type = (d_inode->i_mode & S_IFMT) >> 12; - if (!type) type = DT_REG; - - ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i), - d_inode->i_ino, type, - (const char *)new_d_name, - strlen((char *)new_d_name)); - - if (ret) - return ret; - - if (victim_f) { - /* There was a victim. Kill it off nicely */ - /* Don't oops if the victim was a dirent pointing to an - inode which didn't exist. */ - if (victim_f->inocache) { - down(&victim_f->sem); - victim_f->inocache->nlink--; - up(&victim_f->sem); - } - } - - /* Unlink the original */ - ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), - (const char *)old_d_name, - strlen((char *)old_d_name), NULL); - - if (ret) { - /* Oh shit. We really ought to make a single node which can do both atomically */ - struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode); - down(&f->sem); - if (f->inocache) - d_inode->i_nlink = f->inocache->nlink++; - up(&f->sem); - - printk(KERN_NOTICE "jffs2_rename(): Link succeeded, unlink failed (err %d). You now have a hard link\n", ret); - } - return ret; -} - diff --git a/components/dfs/filesystems/jffs2/src/dir.txt b/components/dfs/filesystems/jffs2/src/dir.txt deleted file mode 100644 index 93767aa2ba..0000000000 --- a/components/dfs/filesystems/jffs2/src/dir.txt +++ /dev/null @@ -1,70 +0,0 @@ -��� PATH �б� -�����к�Ϊ 00000200 38BE:1B05 -F:. -jffs2/dfs_jffs2.c -jffs2/porting.c - -adler32.c - -compress.c -configure -deflate.c - -example.c - -gzio.c - -infback.c -infblock.c - -inffast.c - - -inflate.c - -inftrees.c - -infutil.c - - - - -maketree.c - -minigzip.c - - -trees.c - -uncompr.c - -zutil.c - - -jffs2/crc/crcd -jffs2/crc/crc16.c -jffs2/crc/crc32.c -jffs2/crc/posix_crc.c - -jffs2/kernel/rbtree.c - -jffs2/src/build.c -jffs2/src/compr.c -jffs2/src/compr_rtime.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 - diff --git a/components/dfs/filesystems/jffs2/src/erase.c b/components/dfs/filesystems/jffs2/src/erase.c deleted file mode 100644 index 3844e1d389..0000000000 --- a/components/dfs/filesystems/jffs2/src/erase.c +++ /dev/null @@ -1,469 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: erase.c,v 1.83 2005/07/22 10:32:08 dedekind Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/mtd/mtd.h> -#include <linux/compiler.h> -#include <linux/crc32.h> -#include <linux/sched.h> -#include <linux/pagemap.h> -#include "nodelist.h" - -struct erase_priv_struct { - struct jffs2_eraseblock *jeb; - struct jffs2_sb_info *c; -}; - -#ifndef __ECOS -static void jffs2_erase_callback(struct erase_info *); -#endif -static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset); -static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); -static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); -static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); - -static void jffs2_erase_block(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb) -{ - int ret; - uint32_t bad_offset; -#ifdef __ECOS - ret = jffs2_flash_erase(c, jeb); - if (!ret) { - jffs2_erase_succeeded(c, jeb); - return; - } - bad_offset = jeb->offset; -#else /* Linux */ - struct erase_info *instr; - - D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#08x (range %#08x-%#08x)\n", - jeb->offset, jeb->offset, jeb->offset + c->sector_size)); - instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); - if (!instr) { - printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); - spin_lock(&c->erase_completion_lock); - list_del(&jeb->list); - list_add(&jeb->list, &c->erase_pending_list); - c->erasing_size -= c->sector_size; - c->dirty_size += c->sector_size; - jeb->dirty_size = c->sector_size; - spin_unlock(&c->erase_completion_lock); - return; - } - - memset(instr, 0, sizeof(*instr)); - - instr->mtd = c->mtd; - instr->addr = jeb->offset; - instr->len = c->sector_size; - instr->callback = jffs2_erase_callback; - instr->priv = (unsigned long)(&instr[1]); - instr->fail_addr = 0xffffffff; - - ((struct erase_priv_struct *)instr->priv)->jeb = jeb; - ((struct erase_priv_struct *)instr->priv)->c = c; - - ret = c->mtd->erase(c->mtd, instr); - if (!ret) - return; - - bad_offset = instr->fail_addr; - kfree(instr); -#endif /* __ECOS */ - - if (ret == -ENOMEM || ret == -EAGAIN) { - /* Erase failed immediately. Refile it on the list */ - D1(printk(KERN_DEBUG "Erase at 0x%08x failed: %d. Refiling on erase_pending_list\n", jeb->offset, ret)); - spin_lock(&c->erase_completion_lock); - list_del(&jeb->list); - list_add(&jeb->list, &c->erase_pending_list); - c->erasing_size -= c->sector_size; - c->dirty_size += c->sector_size; - jeb->dirty_size = c->sector_size; - spin_unlock(&c->erase_completion_lock); - return; - } - - if (ret == -EROFS) - printk(KERN_WARNING "Erase at 0x%08x failed immediately: -EROFS. Is the sector locked?\n", jeb->offset); - else - printk(KERN_WARNING "Erase at 0x%08x failed immediately: errno %d\n", jeb->offset, ret); - - jffs2_erase_failed(c, jeb, bad_offset); -} - -void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count) -{ - struct jffs2_eraseblock *jeb; - - down(&c->erase_free_sem); - - spin_lock(&c->erase_completion_lock); - - while (!list_empty(&c->erase_complete_list) || - !list_empty(&c->erase_pending_list)) { - - if (!list_empty(&c->erase_complete_list)) { - jeb = list_entry(c->erase_complete_list.next, struct jffs2_eraseblock, list); - list_del(&jeb->list); - spin_unlock(&c->erase_completion_lock); - jffs2_mark_erased_block(c, jeb); - - if (!--count) { - D1(printk(KERN_DEBUG "Count reached. jffs2_erase_pending_blocks leaving\n")); - goto done; - } - - } else if (!list_empty(&c->erase_pending_list)) { - jeb = list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list); - D1(printk(KERN_DEBUG "Starting erase of pending block 0x%08x\n", jeb->offset)); - list_del(&jeb->list); - c->erasing_size += c->sector_size; - c->wasted_size -= jeb->wasted_size; - c->free_size -= jeb->free_size; - c->used_size -= jeb->used_size; - c->dirty_size -= jeb->dirty_size; - jeb->wasted_size = jeb->used_size = jeb->dirty_size = jeb->free_size = 0; - jffs2_free_all_node_refs(c, jeb); - list_add(&jeb->list, &c->erasing_list); - spin_unlock(&c->erase_completion_lock); - - jffs2_erase_block(c, jeb); - - } else { - BUG(); - } - - /* Be nice */ - cond_resched(); - spin_lock(&c->erase_completion_lock); - } - - spin_unlock(&c->erase_completion_lock); - done: - D1(printk(KERN_DEBUG "jffs2_erase_pending_blocks completed\n")); - - up(&c->erase_free_sem); -} - -static void jffs2_erase_succeeded(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) -{ - D1(printk(KERN_DEBUG "Erase completed successfully at 0x%08x\n", jeb->offset)); - spin_lock(&c->erase_completion_lock); - list_del(&jeb->list); - list_add_tail(&jeb->list, &c->erase_complete_list); - spin_unlock(&c->erase_completion_lock); - /* Ensure that kupdated calls us again to mark them clean */ - jffs2_erase_pending_trigger(c); -} - -static void jffs2_erase_failed(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t bad_offset) -{ - /* For NAND, if the failure did not occur at the device level for a - specific physical page, don't bother updating the bad block table. */ - if (jffs2_cleanmarker_oob(c) && (bad_offset != 0xffffffff)) { - /* We had a device-level failure to erase. Let's see if we've - failed too many times. */ - if (!jffs2_write_nand_badblock(c, jeb, bad_offset)) { - /* We'd like to give this block another try. */ - spin_lock(&c->erase_completion_lock); - list_del(&jeb->list); - list_add(&jeb->list, &c->erase_pending_list); - c->erasing_size -= c->sector_size; - c->dirty_size += c->sector_size; - jeb->dirty_size = c->sector_size; - spin_unlock(&c->erase_completion_lock); - return; - } - } - - spin_lock(&c->erase_completion_lock); - c->erasing_size -= c->sector_size; - c->bad_size += c->sector_size; - list_del(&jeb->list); - list_add(&jeb->list, &c->bad_list); - c->nr_erasing_blocks--; - spin_unlock(&c->erase_completion_lock); - wake_up(&c->erase_wait); -} - -#ifndef __ECOS -static void jffs2_erase_callback(struct erase_info *instr) -{ - struct erase_priv_struct *priv = (void *)instr->priv; - - if(instr->state != MTD_ERASE_DONE) { - printk(KERN_WARNING "Erase at 0x%08x finished, but state != MTD_ERASE_DONE. State is 0x%x instead.\n", instr->addr, instr->state); - jffs2_erase_failed(priv->c, priv->jeb, instr->fail_addr); - } else { - jffs2_erase_succeeded(priv->c, priv->jeb); - } - kfree(instr); -} -#endif /* !__ECOS */ - -/* Hmmm. Maybe we should accept the extra space it takes and make - this a standard doubly-linked list? */ -static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c, - struct jffs2_raw_node_ref *ref, struct jffs2_eraseblock *jeb) -{ - struct jffs2_inode_cache *ic = NULL; - struct jffs2_raw_node_ref **prev; - - prev = &ref->next_in_ino; - - /* Walk the inode's list once, removing any nodes from this eraseblock */ - while (1) { - if (!(*prev)->next_in_ino) { - /* We're looking at the jffs2_inode_cache, which is - at the end of the linked list. Stash it and continue - from the beginning of the list */ - ic = (struct jffs2_inode_cache *)(*prev); - prev = &ic->nodes; - continue; - } - - if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) { - /* It's in the block we're erasing */ - struct jffs2_raw_node_ref *this; - - this = *prev; - *prev = this->next_in_ino; - this->next_in_ino = NULL; - - if (this == ref) - break; - - continue; - } - /* Not to be deleted. Skip */ - prev = &((*prev)->next_in_ino); - } - - /* PARANOIA */ - if (!ic) { - printk(KERN_WARNING "inode_cache not found in remove_node_refs()!!\n"); - return; - } - - D1(printk(KERN_DEBUG "Removed nodes in range 0x%08x-0x%08x from ino #%u\n", - jeb->offset, jeb->offset + c->sector_size, ic->ino)); - - D2({ - int i=0; - struct jffs2_raw_node_ref *this; - printk(KERN_DEBUG "After remove_node_refs_from_ino_list: \n" KERN_DEBUG); - - this = ic->nodes; - - while(this) { - printk( "0x%08x(%d)->", ref_offset(this), ref_flags(this)); - if (++i == 5) { - printk("\n" KERN_DEBUG); - i=0; - } - this = this->next_in_ino; - } - printk("\n"); - }); - - if (ic->nodes == (void *)ic && ic->nlink == 0) - jffs2_del_ino_cache(c, ic); -} - -static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) -{ - struct jffs2_raw_node_ref *ref; - D1(printk(KERN_DEBUG "Freeing all node refs for eraseblock offset 0x%08x\n", jeb->offset)); - while(jeb->first_node) { - ref = jeb->first_node; - jeb->first_node = ref->next_phys; - - /* Remove from the inode-list */ - if (ref->next_in_ino) - jffs2_remove_node_refs_from_ino_list(c, ref, jeb); - /* else it was a non-inode node or already removed, so don't bother */ - - jffs2_free_raw_node_ref(ref); - } - jeb->last_node = NULL; -} - -static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t *bad_offset) -{ - void *ebuf; - uint32_t ofs; - size_t retlen; - int ret = -EIO; - - ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!ebuf) { - printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset); - return -EAGAIN; - } - - D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset)); - - for (ofs = jeb->offset; ofs < jeb->offset + c->sector_size; ) { - uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs); - int i; - - *bad_offset = ofs; - - ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf); - if (ret) { - printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); - goto fail; - } - if (retlen != readlen) { - printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen); - goto fail; - } - for (i=0; i<readlen; i += sizeof(unsigned long)) { - /* It's OK. We know it's properly aligned */ - unsigned long *datum = (unsigned long *)((char *)ebuf + i); - if (*datum + 1) { - *bad_offset += i; - printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", *datum, *bad_offset); - goto fail; - } - } - ofs += readlen; - cond_resched(); - } - ret = 0; -fail: - kfree(ebuf); - return ret; -} - -static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) -{ - struct jffs2_raw_node_ref *marker_ref = NULL; - size_t retlen; - int ret; - uint32_t bad_offset; - - switch (jffs2_block_check_erase(c, jeb, &bad_offset)) { - case -EAGAIN: goto refile; - case -EIO: goto filebad; - } - - /* Write the erase complete marker */ - D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset)); - bad_offset = jeb->offset; - - /* Cleanmarker in oob area or no cleanmarker at all ? */ - if (jffs2_cleanmarker_oob(c) || c->cleanmarker_size == 0) { - - if (jffs2_cleanmarker_oob(c)) { - if (jffs2_write_nand_cleanmarker(c, jeb)) - goto filebad; - } - - jeb->first_node = jeb->last_node = NULL; - jeb->free_size = c->sector_size; - jeb->used_size = 0; - jeb->dirty_size = 0; - jeb->wasted_size = 0; - - } else { - - struct kvec vecs[1]; - #if defined (__GNUC__) - struct jffs2_unknown_node marker = { - .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK), - .nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), - .totlen = cpu_to_je32(c->cleanmarker_size) - }; - #elif defined (MSVC) - struct jffs2_unknown_node marker = { - cpu_to_je16(JFFS2_MAGIC_BITMASK), - cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER), - cpu_to_je32(c->cleanmarker_size), - 0 - }; - #else - #endif - - marker_ref = jffs2_alloc_raw_node_ref(); - if (!marker_ref) { - printk(KERN_WARNING "Failed to allocate raw node ref for clean marker. Refiling\n"); - goto refile; - } - - marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4)); - - vecs[0].iov_base = (unsigned char *) ▮ - vecs[0].iov_len = sizeof(marker); - ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen); - - if (ret || retlen != sizeof(marker)) { - if (ret) - printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n", - jeb->offset, ret); - else - printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n", - jeb->offset, sizeof(marker), retlen); - - jffs2_free_raw_node_ref(marker_ref); - goto filebad; - } - - marker_ref->next_in_ino = NULL; - marker_ref->next_phys = NULL; - marker_ref->flash_offset = jeb->offset | REF_NORMAL; - marker_ref->__totlen = c->cleanmarker_size; - - jeb->first_node = jeb->last_node = marker_ref; - - jeb->free_size = c->sector_size - c->cleanmarker_size; - jeb->used_size = c->cleanmarker_size; - jeb->dirty_size = 0; - jeb->wasted_size = 0; - } - - spin_lock(&c->erase_completion_lock); - c->erasing_size -= c->sector_size; - c->free_size += jeb->free_size; - c->used_size += jeb->used_size; - - jffs2_dbg_acct_sanity_check_nolock(c,jeb); - jffs2_dbg_acct_paranoia_check_nolock(c, jeb); - - list_add_tail(&jeb->list, &c->free_list); - c->nr_erasing_blocks--; - c->nr_free_blocks++; - spin_unlock(&c->erase_completion_lock); - wake_up(&c->erase_wait); - return; - -filebad: - spin_lock(&c->erase_completion_lock); - /* Stick it on a list (any list) so erase_failed can take it - right off again. Silly, but shouldn't happen often. */ - list_add(&jeb->list, &c->erasing_list); - spin_unlock(&c->erase_completion_lock); - jffs2_erase_failed(c, jeb, bad_offset); - return; - -refile: - /* Stick it back on the list from whence it came and come back later */ - jffs2_erase_pending_trigger(c); - spin_lock(&c->erase_completion_lock); - list_add(&jeb->list, &c->erase_complete_list); - spin_unlock(&c->erase_completion_lock); - return; -} diff --git a/components/dfs/filesystems/jffs2/src/flashio.c b/components/dfs/filesystems/jffs2/src/flashio.c deleted file mode 100644 index 37c332de70..0000000000 --- a/components/dfs/filesystems/jffs2/src/flashio.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by Dominic Ostrowski <[email protected]> - * Contributors: David Woodhouse, Nick Garnett, Richard Panton. - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: flashio.c,v 1.1 2003/11/26 14:09:29 dwmw2 Exp $ - * - */ - -#include <linux/kernel.h> -#include "nodelist.h" -#include <rtdevice.h> - -int jffs2_flash_read(struct jffs2_sb_info * c, cyg_uint32 offset, - const size_t size, - size_t * return_size, - unsigned char *buffer) -{ - uint32_t len; - struct super_block *sb = OFNI_BS_2SFFJ(c); - - len = rt_mtd_nor_read(RT_MTD_NOR_DEVICE(sb->s_dev), offset, buffer, size); - if (len != size) - return -EIO; - - * return_size = len; - return ENOERR; -} - -int jffs2_flash_write(struct jffs2_sb_info * c, - cyg_uint32 offset, const size_t size, - size_t * return_size, unsigned char *buffer) -{ - uint32_t len; - struct super_block *sb = OFNI_BS_2SFFJ(c); - - len = rt_mtd_nor_write(RT_MTD_NOR_DEVICE(sb->s_dev), offset, buffer, size); - if (len != size) - return -EIO; - - * return_size = len; - return ENOERR; -} - -int jffs2_flash_erase(struct jffs2_sb_info * c, - struct jffs2_eraseblock * jeb) -{ - rt_err_t result; - struct super_block *sb = OFNI_BS_2SFFJ(c); - - result = rt_mtd_nor_erase_block(RT_MTD_NOR_DEVICE(sb->s_dev), jeb->offset, c->sector_size); - if (result != RT_EOK) - return -EIO; - - return ENOERR; -} - -int jffs2_flash_direct_writev(struct jffs2_sb_info *c, - const struct iovec *vecs, unsigned long count, loff_t to, - size_t * retlen) -{ - unsigned long i; - size_t totlen = 0, thislen; - int ret = 0; - - for (i = 0; i < count; i++) - { - // writes need to be aligned but the data we're passed may not be - // Observation suggests most unaligned writes are small, so we - // optimize for that case. - - if (((vecs[i].iov_len & (sizeof(int) - 1))) || - (((unsigned long) vecs[i].iov_base & (sizeof(unsigned long) - 1)))) - { - // are there iov's after this one? Or is it so much we'd need - // to do multiple writes anyway? - if ((i + 1) < count || vecs[i].iov_len > 256) - { - // cop out and malloc - unsigned long j; - ssize_t sizetomalloc = 0, totvecsize = 0; - char *cbuf, *cbufptr; - - for (j = i; j < count; j++) - totvecsize += vecs[j].iov_len; - - // pad up in case unaligned - sizetomalloc = totvecsize + sizeof(int) - 1; - sizetomalloc &= ~(sizeof(int) - 1); - cbuf = (char *) rt_malloc(sizetomalloc); - // malloc returns aligned memory - if (!cbuf) - { - ret = -ENOMEM; - goto writev_out; - } - cbufptr = cbuf; - for (j = i; j < count; j++) - { - memcpy(cbufptr, vecs[j].iov_base, vecs[j].iov_len); - cbufptr += vecs[j].iov_len; - } - //rt_kprintf("direct_write: offset %d, size %d\n", to, sizetomalloc); - ret = jffs2_flash_write(c, to, sizetomalloc, &thislen, - (unsigned char *) cbuf); - if (thislen > totvecsize) // in case it was aligned up - thislen = totvecsize; - totlen += thislen; - rt_free(cbuf); - goto writev_out; - } - else - { - // otherwise optimize for the common case - int buf[256/sizeof(int)]; // int, so int aligned - size_t lentowrite; - - lentowrite = vecs[i].iov_len; - // pad up in case its unaligned - lentowrite += sizeof(int) - 1; - lentowrite &= ~(sizeof(int) - 1); - memcpy(buf, vecs[i].iov_base, lentowrite); - - //rt_kprintf("direct_write: offset %d, size %d\n", to, lentowrite); - ret = jffs2_flash_write(c, to, lentowrite, &thislen, - (unsigned char *) &buf); - if (thislen > vecs[i].iov_len) - thislen = vecs[i].iov_len; - } - } - else - { - //rt_kprintf("direct_writev: offset %d, size %d\n", to, vecs[i].iov_len); - ret = jffs2_flash_write(c, to, vecs[i].iov_len, &thislen, - vecs[i].iov_base); - } - totlen += thislen; - if (ret || thislen != vecs[i].iov_len) break; - to += vecs[i].iov_len; - } - -writev_out: - if (retlen) *retlen = totlen; - - return ret; -} diff --git a/components/dfs/filesystems/jffs2/src/fs-ecos.c b/components/dfs/filesystems/jffs2/src/fs-ecos.c deleted file mode 100644 index 814d2e3010..0000000000 --- a/components/dfs/filesystems/jffs2/src/fs-ecos.c +++ /dev/null @@ -1,2174 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Free Software Foundation, Inc. - * - * Created by Dominic Ostrowski <[email protected]> - * Contributors: David Woodhouse, Nick Garnett, Richard Panton. - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: fs-ecos.c,v 1.44 2005/07/24 15:29:57 dedekind Exp $ - * - */ - -#include <stdio.h> //prife for SEEK_SET SEEK_CUR SEEK_END -#include <linux/kernel.h> -#include "nodelist.h" -#include <linux/pagemap.h> -#include <linux/crc32.h> -#include "compr.h" -#include <string.h> - -#include <rtdevice.h> - -//-------------------------------------------- -cyg_mtab_entry *cyg_cdir_mtab_entry = NULL; -cyg_dir cyg_cdir_dir = CYG_DIR_NULL; -//========================================================================== -// Default functions - -__externC int cyg_fileio_enosys() { return ENOSYS; } -__externC int cyg_fileio_erofs() { return EROFS; } -__externC int cyg_fileio_enoerr() { return ENOERR; } -__externC int cyg_fileio_enotdir() { return ENOTDIR; } - -__externC cyg_bool cyg_fileio_seltrue (struct CYG_FILE_TAG *fp, int which, CYG_ADDRWORD info) -{ return 1; } - -//-------------------------------------------- -//========================================================================== -// Forward definitions - -// Filesystem operations -int jffs2_mount(cyg_fstab_entry * fste, cyg_mtab_entry * mte); -static int jffs2_umount(cyg_mtab_entry * mte); -int jffs2_open(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - int mode, cyg_file * fte); -#ifdef CYGOPT_FS_JFFS2_WRITE -static int jffs2_ops_unlink(cyg_mtab_entry * mte, cyg_dir dir, - const char *name); -static int jffs2_ops_mkdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name); -static int jffs2_ops_rmdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name); -static int jffs2_ops_rename(cyg_mtab_entry * mte, cyg_dir dir1, - const char *name1, cyg_dir dir2, const char *name2); -static int jffs2_ops_link(cyg_mtab_entry * mte, cyg_dir dir1, const char *name1, - cyg_dir dir2, const char *name2, int type); -#endif -static int jffs2_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - cyg_file * fte); -static int jffs2_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - cyg_dir * dir_out); -static int jffs2_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - struct stat *buf); -static int jffs2_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - int key, void *buf, int len); -static int jffs2_setinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - int key, void *buf, int len); - -// File operations -int jffs2_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio); -#ifdef CYGOPT_FS_JFFS2_WRITE -static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio); -#endif -static int jffs2_fo_lseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence); -static int jffs2_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com, - CYG_ADDRWORD data); -static int jffs2_fo_fsync(struct CYG_FILE_TAG *fp, int mode); -static int jffs2_fo_close(struct CYG_FILE_TAG *fp); -static int jffs2_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf); -static int jffs2_fo_getinfo(struct CYG_FILE_TAG *fp, int key, void *buf, - int len); -static int jffs2_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf, - int len); - -// Directory operations -static int jffs2_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio); -static int jffs2_fo_dirlseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence); - - -static int jffs2_read_inode (struct _inode *inode); -static void jffs2_clear_inode (struct _inode *inode); -static int jffs2_truncate_file (struct _inode *inode); - -//========================================================================== -// Filesystem table entries - -// ------------------------------------------------------------------------- -// Fstab entry. -// This defines the entry in the filesystem table. -// For simplicity we use _FILESYSTEM synchronization for all accesses since -// we should never block in any filesystem operations. - -#ifdef CYGOPT_FS_JFFS2_WRITE -FSTAB_ENTRY(jffs2_fste, "jffs2", 0, - CYG_SYNCMODE_FILE_FILESYSTEM | CYG_SYNCMODE_IO_FILESYSTEM, - jffs2_mount, - jffs2_umount, - jffs2_open, - jffs2_ops_unlink, - jffs2_ops_mkdir, - jffs2_ops_rmdir, - jffs2_ops_rename, - jffs2_ops_link, - jffs2_opendir, - jffs2_chdir, jffs2_stat, jffs2_getinfo, jffs2_setinfo); -#else -FSTAB_ENTRY(jffs2_fste, "jffs2", 0, - CYG_SYNCMODE_FILE_FILESYSTEM | CYG_SYNCMODE_IO_FILESYSTEM, - jffs2_mount, - jffs2_umount, - jffs2_open, - (cyg_fsop_unlink *)cyg_fileio_erofs, - (cyg_fsop_mkdir *)cyg_fileio_erofs, - (cyg_fsop_rmdir *)cyg_fileio_erofs, - (cyg_fsop_rename *)cyg_fileio_erofs, - (cyg_fsop_link *)cyg_fileio_erofs, - jffs2_opendir, - jffs2_chdir, jffs2_stat, jffs2_getinfo, jffs2_setinfo); -#endif - -// ------------------------------------------------------------------------- -// File operations. -// This set of file operations are used for normal open files. - -cyg_fileops jffs2_fileops = { - jffs2_fo_read, -#ifdef CYGOPT_FS_JFFS2_WRITE - jffs2_fo_write, -#else - (cyg_fileop_write *) cyg_fileio_erofs, -#endif - jffs2_fo_lseek, - jffs2_fo_ioctl, - cyg_fileio_seltrue, - jffs2_fo_fsync, - jffs2_fo_close, - jffs2_fo_fstat, - jffs2_fo_getinfo, - jffs2_fo_setinfo -}; - -// ------------------------------------------------------------------------- -// Directory file operations. -// This set of operations are used for open directories. Most entries -// point to error-returning stub functions. Only the read, lseek and -// close entries are functional. - -cyg_fileops jffs2_dirops = { - jffs2_fo_dirread, - (cyg_fileop_write *) cyg_fileio_enosys, - jffs2_fo_dirlseek, - (cyg_fileop_ioctl *) cyg_fileio_enosys, - cyg_fileio_seltrue, - (cyg_fileop_fsync *) cyg_fileio_enosys, - jffs2_fo_close, - (cyg_fileop_fstat *) cyg_fileio_enosys, - (cyg_fileop_getinfo *) cyg_fileio_enosys, - (cyg_fileop_setinfo *) cyg_fileio_enosys -}; - -//========================================================================== -// STATIC VARIABLES !!! - -static unsigned char gc_buffer[PAGE_CACHE_SIZE]; //avoids malloc when user may be under memory pressure -static unsigned char n_fs_mounted = 0; // a counter to track the number of jffs2 instances mounted - -//========================================================================== -// Directory operations - -struct jffs2_dirsearch { - struct _inode *dir; // directory to search - const unsigned char *path; // path to follow - struct _inode *node; // Node found - const unsigned char *name; // last name fragment used - int namelen; // name fragment length - cyg_bool last; // last name in path? -}; - -typedef struct jffs2_dirsearch jffs2_dirsearch; - -//========================================================================== -// Ref count and nlink management - - -// FIXME: This seems like real cruft. Wouldn't it be better just to do the -// right thing? -static void icache_evict(struct _inode *root_i, struct _inode *i) -{ - struct _inode *this = root_i, *next; - - restart: - D2(printf("icache_evict\n")); - // If this is an absolute search path from the root, - // remove all cached inodes with i_count of zero (these are only - // held where needed for dotdot filepaths) - while (this) { - next = this->i_cache_next; - if (this != i && this->i_count == 0) { - struct _inode *parent = this->i_parent; - if (this->i_cache_next) - this->i_cache_next->i_cache_prev = this->i_cache_prev; - if (this->i_cache_prev) - this->i_cache_prev->i_cache_next = this->i_cache_next; - jffs2_clear_inode(this); - memset(this, 0x5a, sizeof(*this)); - rt_free(this); - if (parent && parent != this) { - parent->i_count--; - this = root_i; - goto restart; - } - } - this = next; - } -} - -//========================================================================== -// Directory search - -// ------------------------------------------------------------------------- -// init_dirsearch() -// Initialize a dirsearch object to start a search - -static void init_dirsearch(jffs2_dirsearch * ds, - struct _inode *dir, const unsigned char *name) -{ - D2(printf("init_dirsearch name = %s\n", name)); - D2(printf("init_dirsearch dir = %x\n", dir)); - - dir->i_count++; - ds->dir = dir; - ds->path = name; - ds->node = dir; - ds->name = name; - ds->namelen = 0; - ds->last = false; -} - -// ------------------------------------------------------------------------- -// find_entry() -// Search a single directory for the next name in a path and update the -// dirsearch object appropriately. - -static int find_entry(jffs2_dirsearch * ds) -{ - struct _inode *dir = ds->dir; - const unsigned char *name = ds->path; - const unsigned char *n = name; - char namelen = 0; - struct _inode *d; - - D2(printf("find_entry\n")); - - // check that we really have a directory - if (!S_ISDIR(dir->i_mode)) - return ENOTDIR; - - // Isolate the next element of the path name. - while (*n != '\0' && *n != '/') - n++, namelen++; - - // Check if this is the last path element. - while( *n == '/') n++; - if (*n == '\0') - ds->last = true; - - // update name in dirsearch object - ds->name = name; - ds->namelen = namelen; - - if (name[0] == '.') - switch (namelen) { - default: - break; - case 2: - // Dot followed by not Dot, treat as any other name - if (name[1] != '.') - break; - // Dot Dot - // Move back up the search path - D2(printf("find_entry found ..\n")); - ds->dir = ds->node; - ds->node = ds->dir->i_parent; - ds->node->i_count++; - return ENOERR; - case 1: - // Dot is consumed - D2(printf("find_entry found .\n")); - ds->node = ds->dir; - ds->dir->i_count++; - return ENOERR; - } - - // Here we have the name and its length set up. - // Search the directory for a matching entry - - D2(printf("find_entry for name = %s\n", ds->path)); - d = jffs2_lookup(dir, name, namelen); - D2(printf("find_entry got dir = %x\n", d)); - - if (d == NULL) - return ENOENT; - if (IS_ERR(d)) - return -PTR_ERR(d); - - // If it's a new directory inode, increase refcount on its parent - if (S_ISDIR(d->i_mode) && !d->i_parent) { - d->i_parent = dir; - dir->i_count++; - } - - // pass back the node we have found - ds->node = d; - return ENOERR; - -} - -// ------------------------------------------------------------------------- -// jffs2_find() -// Main interface to directory search code. This is used in all file -// level operations to locate the object named by the pathname. - -// Returns with use count incremented on both the sought object and -// the directory it was found in -static int jffs2_find(jffs2_dirsearch * d) -{ - int err; - - D2(printf("jffs2_find for path =%s\n", d->path)); - - // Short circuit empty paths - if (*(d->path) == '\0') { - d->node->i_count++; - return ENOERR; - } - - // iterate down directory tree until we find the object - // we want. - for (;;) { - err = find_entry(d); - - if (err != ENOERR) - return err; - - if (d->last) - return ENOERR; - - /* We're done with it, although it we found a subdir that - will have caused the refcount to have been increased */ - jffs2_iput(d->dir); - - // Update dirsearch object to search next directory. - d->dir = d->node; - d->path += d->namelen; - while (*(d->path) == '/') - d->path++; // skip dirname separators - } -} - -//========================================================================== -// Pathconf support -// This function provides support for pathconf() and fpathconf(). - -static int jffs2_pathconf(struct _inode *node, struct cyg_pathconf_info *info) -{ - int err = ENOERR; - D2(printf("jffs2_pathconf\n")); - - switch (info->name) { - case _PC_LINK_MAX: - info->value = LINK_MAX; - break; - - case _PC_MAX_CANON: - info->value = -1; // not supported - err = EINVAL; - break; - - case _PC_MAX_INPUT: - info->value = -1; // not supported - err = EINVAL; - break; - - case _PC_NAME_MAX: - info->value = JFFS2_NAME_MAX; - break; - - case _PC_PATH_MAX: - info->value = JFFS2_PATH_MAX; - break; - - case _PC_PIPE_BUF: - info->value = -1; // not supported - err = EINVAL; - break; - - case _PC_ASYNC_IO: - info->value = -1; // not supported - err = EINVAL; - break; - - case _PC_CHOWN_RESTRICTED: - info->value = -1; // not supported - err = EINVAL; - break; - - case _PC_NO_TRUNC: - info->value = 0; - break; - - case _PC_PRIO_IO: - info->value = 0; - break; - - case _PC_SYNC_IO: - info->value = 0; - break; - - case _PC_VDISABLE: - info->value = -1; // not supported - err = EINVAL; - break; - - default: - err = EINVAL; - break; - } - - return err; -} - -//========================================================================== -// Filesystem operations -// ------------------------------------------------------------------------- -// jffs2_mount() -// Process a mount request. This mainly creates a root for the -// filesystem. -static int jffs2_read_super(struct super_block *sb) -{ - Cyg_ErrNo err; - struct jffs2_sb_info *c; - struct rt_mtd_nor_device *device; - - c = JFFS2_SB_INFO(sb); - device = RT_MTD_NOR_DEVICE(sb->s_dev); - - /* initialize mutex lock */ - init_MUTEX(&c->alloc_sem); - init_MUTEX(&c->erase_free_sem); - - /* sector size is the erase block size */ - c->sector_size = device->block_size; - c->flash_size = (device->block_end - device->block_start) * device->block_size; - c->cleanmarker_size = sizeof(struct jffs2_unknown_node); - - err = jffs2_do_mount_fs(c); - if (err) return -err; - - D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n")); - sb->s_root = jffs2_iget(sb, 1); - if (IS_ERR(sb->s_root)) { - D1(printk(KERN_WARNING "get root inode failed\n")); - err = PTR_ERR(sb->s_root); - sb->s_root = NULL; - goto out_nodes; - } - return 0; - -out_nodes: - jffs2_free_ino_caches(c); - jffs2_free_raw_node_refs(c); - rt_free(c->blocks); - - return err; -} - -int jffs2_mount(cyg_fstab_entry * fste, cyg_mtab_entry * mte) -{ -// extern cyg_mtab_entry cyg_mtab[], cyg_mtab_end; - struct super_block *jffs2_sb = NULL; - struct jffs2_sb_info *c; -// cyg_mtab_entry *m; - cyg_io_handle_t t; - Cyg_ErrNo err; - - D2(printf("jffs2_mount\n")); - -//prife -// err = cyg_io_lookup(mte->devname, &t); -// if (err != ENOERR) -// return -err; - -// // Iterate through the mount table to see if we're mounted -// // FIXME: this should be done better - perhaps if the superblock -// // can be stored as an inode in the icache. -// for (m = &cyg_mtab[0]; m != &cyg_mtab_end; m++) { -// // stop if there are more than the configured maximum -// if (m - &cyg_mtab[0] >= CYGNUM_FILEIO_MTAB_MAX) { -// m = &cyg_mtab_end; -// break; -// } -// if (m->valid && strcmp(m->fsname, "jffs2") == 0 && -// strcmp(m->devname, mte->devname) == 0) { -// jffs2_sb = (struct super_block *) m->data; -// } -// } - jffs2_sb = NULL; - t = (cyg_io_handle_t)mte->data; //get from dfs_jffs2; - if (jffs2_sb == NULL) { - jffs2_sb = rt_malloc(sizeof (struct super_block)); - - if (jffs2_sb == NULL) - return ENOMEM; - - c = JFFS2_SB_INFO(jffs2_sb); - memset(jffs2_sb, 0, sizeof (struct super_block)); - jffs2_sb->s_dev = t; - - c->inocache_list = rt_malloc(sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE); - if (!c->inocache_list) { - rt_free(jffs2_sb); - return ENOMEM; - } - memset(c->inocache_list, 0, sizeof(struct jffs2_inode_cache *) * INOCACHE_HASHSIZE); - if (n_fs_mounted++ == 0) { - jffs2_create_slab_caches(); // No error check, cannot fail - jffs2_compressors_init(); - } - - err = jffs2_read_super(jffs2_sb); - - if (err) { - if (--n_fs_mounted == 0) { - jffs2_destroy_slab_caches(); - jffs2_compressors_exit(); - } - - rt_free(jffs2_sb); - rt_free(c->inocache_list); - return err; - } - - jffs2_sb->s_root->i_parent = jffs2_sb->s_root; // points to itself, no dotdot paths above mountpoint - jffs2_sb->s_root->i_cache_prev = NULL; // root inode, so always null - jffs2_sb->s_root->i_cache_next = NULL; - jffs2_sb->s_root->i_count = 1; // Ensures the root inode is always in ram until umount - - D2(printf("jffs2_mount erasing pending blocks\n")); -#ifdef CYGOPT_FS_JFFS2_WRITE - if (!jffs2_is_readonly(c)) - jffs2_erase_pending_blocks(c,0); -#endif -#ifdef CYGOPT_FS_JFFS2_GCTHREAD - jffs2_start_garbage_collect_thread(c); -#endif - } - mte->data = (CYG_ADDRWORD) jffs2_sb; - - jffs2_sb->s_mount_count++; - mte->root = (cyg_dir) jffs2_sb->s_root; - D2(printf("jffs2_mounted superblock at %x\n", mte->root)); - - return ENOERR; -} - -extern cyg_dir cyg_cdir_dir; -extern cyg_mtab_entry *cyg_cdir_mtab_entry; - -// ------------------------------------------------------------------------- -// jffs2_umount() -// Unmount the filesystem. - -static int jffs2_umount(cyg_mtab_entry * mte) -{ - struct _inode *root = (struct _inode *) mte->root; - struct super_block *jffs2_sb = root->i_sb; - struct jffs2_sb_info *c = JFFS2_SB_INFO(jffs2_sb); - struct jffs2_full_dirent *fd, *next; - - D2(printf("jffs2_umount\n")); - - // Only really umount if this is the only mount - if (jffs2_sb->s_mount_count == 1) { - icache_evict(root, NULL); - if (root->i_cache_next != NULL) { - struct _inode *inode = root; - printf("Refuse to unmount.\n"); - while (inode) { - printf("Ino #%u has use count %d\n", - inode->i_ino, inode->i_count); - inode = inode->i_cache_next; - } - // root icount was set to 1 on mount - return EBUSY; - } - if (root->i_count == 2 && - cyg_cdir_mtab_entry == mte && - cyg_cdir_dir == (cyg_dir)root && - !strcmp(mte->name, "/")) { - /* If we were mounted on root, there's no - way for the cwd to change out and free - the file system for unmounting. So we hack - it -- if cwd is '/' we unset it. Perhaps - we should allow chdir(NULL) to unset - cyg_cdir_dir? */ - cyg_cdir_dir = CYG_DIR_NULL; - jffs2_iput(root); - } - /* Argh. The fileio code sets this; never clears it */ - if (cyg_cdir_mtab_entry == mte) - cyg_cdir_mtab_entry = NULL; - - if (root->i_count != 1) { - printf("Ino #1 has use count %d\n", - root->i_count); - return EBUSY; - } -#ifdef CYGOPT_FS_JFFS2_GCTHREAD - jffs2_stop_garbage_collect_thread(c); -#endif - jffs2_iput(root); // Time to free the root inode - - // free directory entries - for (fd = root->jffs2_i.dents; fd; fd = next) { - next=fd->next; - jffs2_free_full_dirent(fd); - } - - rt_free(root); - //Clear root inode - //root_i = NULL; - - // Clean up the super block and root inode - jffs2_free_ino_caches(c); - jffs2_free_raw_node_refs(c); - rt_free(c->blocks); - rt_free(c->inocache_list); - rt_free(jffs2_sb); - // Clear superblock & root pointer - mte->root = CYG_DIR_NULL; - mte->data = 0; - mte->fs->data = 0; // fstab entry, visible to all mounts. No current mount - // That's all folks. - D2(printf("jffs2_umount No current mounts\n")); - } else { - jffs2_sb->s_mount_count--; - } - if (--n_fs_mounted == 0) { - jffs2_destroy_slab_caches(); - jffs2_compressors_exit(); - } - return ENOERR; -} - -// ------------------------------------------------------------------------- -// jffs2_open() -// Open a file for reading or writing. - -int jffs2_open(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - int mode, cyg_file * file) -{ - - jffs2_dirsearch ds; - struct _inode *node = NULL; - int err; - - D2(printf("jffs2_open\n")); - - /* If no chdir has been called and we were the first file system - mounted, we get called with dir == NULL. Deal with it */ - if (!dir) - dir = mte->root; - -#ifndef CYGOPT_FS_JFFS2_WRITE - if (mode & (O_CREAT|O_TRUNC|O_WRONLY)) - return EROFS; -#endif - init_dirsearch(&ds, (struct _inode *) dir, - (const unsigned char *) name); - - err = jffs2_find(&ds); - - if (err == ENOENT) { -#ifdef CYGOPT_FS_JFFS2_WRITE - if (ds.last && (mode & O_CREAT)) { - - // No node there, if the O_CREAT bit is set then we must - // create a new one. The dir and name fields of the dirsearch - // object will have been updated so we know where to put it. - - err = jffs2_create(ds.dir, ds.name, S_IRUGO|S_IXUGO|S_IWUSR|S_IFREG, &node); - - if (err != 0) { - //Possible orphaned inode on the flash - but will be gc'd - jffs2_iput(ds.dir); - return -err; - } - - err = ENOERR; - } -#endif - } else if (err == ENOERR) { - // The node exists. If the O_CREAT and O_EXCL bits are set, we - // must fail the open. - - if ((mode & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL)) { - jffs2_iput(ds.node); - err = EEXIST; - } else - node = ds.node; - } - - // Finished with the directory now - jffs2_iput(ds.dir); - - if (err != ENOERR) - return err; - - // Check that we actually have a file here - if (S_ISDIR(node->i_mode)) { - jffs2_iput(node); - return EISDIR; - } - - // If the O_TRUNC bit is set we must clean out the file data. - if (mode & O_TRUNC) { -#ifdef CYGOPT_FS_JFFS2_WRITE - err = jffs2_truncate_file(node); - if (err) { - jffs2_iput(node); - return err; - } -#else - jffs2_iput(node); - return EROFS; -#endif - } - - // Initialise the file object - file->f_flag = mode & CYG_FILE_MODE_MASK; - file->f_type = CYG_FILE_TYPE_FILE; - file->f_ops = &jffs2_fileops; - file->f_offset = (mode & O_APPEND) ? node->i_size : 0; - file->f_data = (CYG_ADDRWORD) node; - file->f_xops = 0; - - return ENOERR; -} - -#ifdef CYGOPT_FS_JFFS2_WRITE -// ------------------------------------------------------------------------- -// jffs2_ops_unlink() -// Remove a file link from its directory. - -static int jffs2_ops_unlink(cyg_mtab_entry * mte, cyg_dir dir, const char *name) -{ - jffs2_dirsearch ds; - int err; - - D2(printf("jffs2_ops_unlink\n")); - - init_dirsearch(&ds, (struct _inode *) dir, - (const unsigned char *)name); - - err = jffs2_find(&ds); - - if (err != ENOERR) { - jffs2_iput(ds.dir); - return err; - } - - // Cannot unlink directories, use rmdir() instead - if (S_ISDIR(ds.node->i_mode)) { - jffs2_iput(ds.dir); - jffs2_iput(ds.node); - return EPERM; - } - - // Delete it from its directory - - err = jffs2_unlink(ds.dir, ds.node, ds.name); - jffs2_iput(ds.dir); - jffs2_iput(ds.node); - - return -err; -} - -// ------------------------------------------------------------------------- -// jffs2_ops_mkdir() -// Create a new directory. - -static int jffs2_ops_mkdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name) -{ - jffs2_dirsearch ds; - int err; - - D2(printf("jffs2_ops_mkdir\n")); - - init_dirsearch(&ds, (struct _inode *) dir, - (const unsigned char *)name); - - err = jffs2_find(&ds); - - if (err == ENOENT) { - if (ds.last) { - // The entry does not exist, and it is the last element in - // the pathname, so we can create it here. - - err = -jffs2_mkdir(ds.dir, ds.name, S_IRUGO|S_IXUGO|S_IWUSR); - } - // If this was not the last element, then an intermediate - // directory does not exist. - } else { - // If there we no error, something already exists with that - // name, so we cannot create another one. - if (err == ENOERR) { - jffs2_iput(ds.node); - err = EEXIST; - } - } - jffs2_iput(ds.dir); - return err; -} - -// ------------------------------------------------------------------------- -// jffs2_ops_rmdir() -// Remove a directory. - -static int jffs2_ops_rmdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name) -{ - jffs2_dirsearch ds; - int err; - - D2(printf("jffs2_ops_rmdir\n")); - - init_dirsearch(&ds, (struct _inode *) dir, - (const unsigned char *)name); - - err = jffs2_find(&ds); - - if (err != ENOERR) { - jffs2_iput(ds.dir); - return err; - } - - // Check that this is actually a directory. - if (!S_ISDIR(ds.node->i_mode)) { - jffs2_iput(ds.dir); - jffs2_iput(ds.node); - return EPERM; - } - - err = jffs2_rmdir(ds.dir, ds.node, ds.name); - - jffs2_iput(ds.dir); - jffs2_iput(ds.node); - return -err; -} - -// ------------------------------------------------------------------------- -// jffs2_ops_rename() -// Rename a file/dir. - -static int jffs2_ops_rename(cyg_mtab_entry * mte, cyg_dir dir1, - const char *name1, cyg_dir dir2, const char *name2) -{ - jffs2_dirsearch ds1, ds2; - int err; - - D2(printf("jffs2_ops_rename\n")); - - init_dirsearch(&ds1, (struct _inode *) dir1, - (const unsigned char *)name1); - - err = jffs2_find(&ds1); - - if (err != ENOERR) { - jffs2_iput(ds1.dir); - return err; - } - - init_dirsearch(&ds2, (struct _inode *) dir2, - (const unsigned char *)name2); - - err = jffs2_find(&ds2); - - // Allow through renames to non-existent objects. - if (ds2.last && err == ENOENT) { - ds2.node = NULL; - err = ENOERR; - } - - if (err != ENOERR) { - jffs2_iput(ds1.dir); - jffs2_iput(ds1.node); - jffs2_iput(ds2.dir); - return err; - } - - // Null rename, just return - if (ds1.node == ds2.node) { - err = ENOERR; - goto out; - } - - // First deal with any entry that is at the destination - if (ds2.node) { - // Check that we are renaming like-for-like - - if (!S_ISDIR(ds1.node->i_mode) && S_ISDIR(ds2.node->i_mode)) { - err = EISDIR; - goto out; - } - - if (S_ISDIR(ds1.node->i_mode) && !S_ISDIR(ds2.node->i_mode)) { - err = ENOTDIR; - goto out; - } - - // Now delete the destination directory entry - /* Er, what happened to atomicity of rename()? */ - err = -jffs2_unlink(ds2.dir, ds2.node, ds2.name); - - if (err != 0) - goto out; - - } - // Now we know that there is no clashing node at the destination, - // make a new direntry at the destination and delete the old entry - // at the source. - - err = -jffs2_rename(ds1.dir, ds1.node, ds1.name, ds2.dir, ds2.name); - - // Update directory times - if (!err) - ds1.dir->i_ctime = - ds1.dir->i_mtime = - ds2.dir->i_ctime = ds2.dir->i_mtime = jffs2_get_timestamp(); - out: - jffs2_iput(ds1.dir); - if (S_ISDIR(ds1.node->i_mode)) { - /* Renamed a directory to elsewhere... so fix up its - i_parent pointer and the i_counts of its old and - new parents. */ - jffs2_iput(ds1.node->i_parent); - ds1.node->i_parent = ds2.dir; - /* We effectively increase its use count by not... */ - } else { - jffs2_iput(ds2.dir); /* ... doing this */ - } - jffs2_iput(ds1.node); - if (ds2.node) - jffs2_iput(ds2.node); - - return err; -} - -// ------------------------------------------------------------------------- -// jffs2_ops_link() -// Make a new directory entry for a file. - -static int jffs2_ops_link(cyg_mtab_entry * mte, cyg_dir dir1, const char *name1, - cyg_dir dir2, const char *name2, int type) -{ - jffs2_dirsearch ds1, ds2; - int err; - - D2(printf("jffs2_ops_link\n")); - - // Only do hard links for now in this filesystem - if (type != CYG_FSLINK_HARD) - return EINVAL; - - init_dirsearch(&ds1, (struct _inode *) dir1, - (const unsigned char *) name1); - - err = jffs2_find(&ds1); - - if (err != ENOERR) { - jffs2_iput(ds1.dir); - return err; - } - - init_dirsearch(&ds2, (struct _inode *) dir2, - (const unsigned char *) name2); - - err = jffs2_find(&ds2); - - // Don't allow links to existing objects - if (err == ENOERR) { - jffs2_iput(ds1.dir); - jffs2_iput(ds1.node); - jffs2_iput(ds2.dir); - jffs2_iput(ds2.node); - return EEXIST; - } - - // Allow through links to non-existing terminal objects - if (ds2.last && err == ENOENT) { - ds2.node = NULL; - err = ENOERR; - } - - if (err != ENOERR) { - jffs2_iput(ds1.dir); - jffs2_iput(ds1.node); - jffs2_iput(ds2.dir); - return err; - } - - // Now we know that there is no existing node at the destination, - // make a new direntry at the destination. - - err = jffs2_link(ds1.node, ds2.dir, ds2.name); - - if (err == 0) - ds1.node->i_ctime = - ds2.dir->i_ctime = ds2.dir->i_mtime = jffs2_get_timestamp(); - - jffs2_iput(ds1.dir); - jffs2_iput(ds1.node); - jffs2_iput(ds2.dir); - - return -err; -} -#endif /* CYGOPT_FS_JFFS2_WRITE */ -// ------------------------------------------------------------------------- -// jffs2_opendir() -// Open a directory for reading. - -static int jffs2_opendir(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - cyg_file * file) -{ - jffs2_dirsearch ds; - int err; - - D2(printf("jffs2_opendir\n")); - - init_dirsearch(&ds, (struct _inode *) dir, - (const unsigned char *) name); - - err = jffs2_find(&ds); - - jffs2_iput(ds.dir); - - if (err != ENOERR) - return err; - - // check it is really a directory. - if (!S_ISDIR(ds.node->i_mode)) { - jffs2_iput(ds.node); - return ENOTDIR; - } - - // Initialize the file object, setting the f_ops field to a - // special set of file ops. - - file->f_flag = 0; - file->f_type = CYG_FILE_TYPE_FILE; - file->f_ops = &jffs2_dirops; - file->f_offset = 0; - file->f_data = (CYG_ADDRWORD) ds.node; - file->f_xops = 0; - - return ENOERR; - -} - -// ------------------------------------------------------------------------- -// jffs2_chdir() -// Change directory support. - -static int jffs2_chdir(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - cyg_dir * dir_out) -{ - D2(printf("jffs2_chdir\n")); - - if (dir_out != NULL) { - // This is a request to get a new directory pointer in - // *dir_out. - - jffs2_dirsearch ds; - int err; - - init_dirsearch(&ds, (struct _inode *) dir, - (const unsigned char *) name); - - err = jffs2_find(&ds); - jffs2_iput(ds.dir); - - if (err != ENOERR) - return err; - - // check it is a directory - if (!S_ISDIR(ds.node->i_mode)) { - jffs2_iput(ds.node); - return ENOTDIR; - } - - // Pass it out - *dir_out = (cyg_dir) ds.node; - } else { - // If no output dir is required, this means that the mte and - // dir arguments are the current cdir setting and we should - // forget this fact. - - struct _inode *node = (struct _inode *) dir; - - // Just decrement directory reference count. - jffs2_iput(node); - } - - return ENOERR; -} - -// ------------------------------------------------------------------------- -// jffs2_stat() -// Get struct stat info for named object. - -static int jffs2_stat(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - struct stat *buf) -{ - jffs2_dirsearch ds; - int err; - - D2(printf("jffs2_stat\n")); - - init_dirsearch(&ds, (struct _inode *) dir, - (const unsigned char *) name); - - err = jffs2_find(&ds); - jffs2_iput(ds.dir); - - if (err != ENOERR) - return err; - - // Fill in the status - buf->st_mode = ds.node->i_mode; - buf->st_ino = ds.node->i_ino; - buf->st_dev = 0; - buf->st_nlink = ds.node->i_nlink; - buf->st_uid = ds.node->i_uid; - buf->st_gid = ds.node->i_gid; - buf->st_size = ds.node->i_size; - buf->st_atime = ds.node->i_atime; - buf->st_mtime = ds.node->i_mtime; - buf->st_ctime = ds.node->i_ctime; - - jffs2_iput(ds.node); - - return ENOERR; -} - -// ------------------------------------------------------------------------- -// jffs2_getinfo() -// Getinfo. Currently only support pathconf(). - -static int jffs2_getinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - int key, void *buf, int len) -{ - jffs2_dirsearch ds; - int err; - - D2(printf("jffs2_getinfo\n")); - - init_dirsearch(&ds, (struct _inode *) dir, - (const unsigned char *) name); - - err = jffs2_find(&ds); - jffs2_iput(ds.dir); - - if (err != ENOERR) - return err; - - switch (key) { - case FS_INFO_CONF: - err = jffs2_pathconf(ds.node, (struct cyg_pathconf_info *) buf); - break; - - default: - err = EINVAL; - } - - jffs2_iput(ds.node); - return err; -} - -// ------------------------------------------------------------------------- -// jffs2_setinfo() -// Setinfo. Nothing to support here at present. - -static int jffs2_setinfo(cyg_mtab_entry * mte, cyg_dir dir, const char *name, - int key, void *buf, int len) -{ - // No setinfo keys supported at present - - D2(printf("jffs2_setinfo\n")); - - return EINVAL; -} - -//========================================================================== -// File operations - -// ------------------------------------------------------------------------- -// jffs2_fo_read() -// Read data from the file. - -int jffs2_fo_read(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio) -{ - struct _inode *inode = (struct _inode *) fp->f_data; - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); - int i; - ssize_t resid = uio->uio_resid; - off_t pos = fp->f_offset; - - down(&f->sem); - - // Loop over the io vectors until there are none left - for (i = 0; i < uio->uio_iovcnt && pos < inode->i_size; i++) { - int ret; - cyg_iovec *iov = &uio->uio_iov[i]; - off_t len = min(iov->iov_len, inode->i_size - pos); - - D2(printf("jffs2_fo_read inode size %d\n", inode->i_size)); - - ret = - jffs2_read_inode_range(c, f, - (unsigned char *) iov->iov_base, pos, - len); - if (ret) { - D1(printf - ("jffs2_fo_read(): read_inode_range failed %d\n", - ret)); - uio->uio_resid = resid; - up(&f->sem); - return -ret; - } - resid -= len; - pos += len; - } - - // We successfully read some data, update the node's access time - // and update the file offset and transfer residue. - - inode->i_atime = jffs2_get_timestamp(); - - uio->uio_resid = resid; - fp->f_offset = pos; - - up(&f->sem); - - return ENOERR; -} - - -#ifdef CYGOPT_FS_JFFS2_WRITE -// ------------------------------------------------------------------------- -// jffs2_fo_write() -// Write data to file. -static int jffs2_extend_file (struct _inode *inode, struct jffs2_raw_inode *ri, - unsigned long offset) -{ - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - struct jffs2_full_dnode *fn; - uint32_t phys_ofs, alloc_len; - int ret = 0; - - /* Make new hole frag from old EOF to new page */ - D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n", - (unsigned int)inode->i_size, offset)); - - ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloc_len, ALLOC_NORMAL); - if (ret) - return ret; - - down(&f->sem); - - ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); - ri->totlen = cpu_to_je32(sizeof(*ri)); - ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); - - ri->version = cpu_to_je32(++f->highest_version); - ri->isize = cpu_to_je32(max((uint32_t)inode->i_size, offset)); - - ri->offset = cpu_to_je32(inode->i_size); - ri->dsize = cpu_to_je32(offset - inode->i_size); - ri->csize = cpu_to_je32(0); - ri->compr = JFFS2_COMPR_ZERO; - ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); - ri->data_crc = cpu_to_je32(0); - - fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); - jffs2_complete_reservation(c); - if (IS_ERR(fn)) { - ret = PTR_ERR(fn); - up(&f->sem); - return ret; - } - ret = jffs2_add_full_dnode_to_inode(c, f, fn); - if (f->metadata) { - jffs2_mark_node_obsolete(c, f->metadata->raw); - jffs2_free_full_dnode(f->metadata); - f->metadata = NULL; - } - if (ret) { - D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret)); - jffs2_mark_node_obsolete(c, fn->raw); - jffs2_free_full_dnode(fn); - up(&f->sem); - return ret; - } - inode->i_size = offset; - up(&f->sem); - return 0; -} - -// jffs2_fo_open() -// Truncate a file -static int jffs2_truncate_file (struct _inode *inode) -{ - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); - struct jffs2_full_dnode *new_metadata, * old_metadata; - struct jffs2_raw_inode *ri; - uint32_t phys_ofs, alloclen; - int err; - - ri = jffs2_alloc_raw_inode(); - if (!ri) { - return ENOMEM; - } - err = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); - - if (err) { - jffs2_free_raw_inode(ri); - return err; - } - down(&f->sem); - ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); - ri->totlen = cpu_to_je32(sizeof(*ri)); - ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); - - ri->ino = cpu_to_je32(inode->i_ino); - ri->version = cpu_to_je32(++f->highest_version); - - ri->uid = cpu_to_je16(inode->i_uid); - ri->gid = cpu_to_je16(inode->i_gid); - ri->mode = cpu_to_jemode(inode->i_mode); - ri->isize = cpu_to_je32(0); - ri->atime = cpu_to_je32(inode->i_atime); - ri->mtime = cpu_to_je32(jffs2_get_timestamp()); - ri->offset = cpu_to_je32(0); - ri->csize = ri->dsize = cpu_to_je32(0); - ri->compr = JFFS2_COMPR_NONE; - ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); - ri->data_crc = cpu_to_je32(0); - new_metadata = jffs2_write_dnode(c, f, ri, NULL, 0, - phys_ofs, ALLOC_NORMAL); - if (IS_ERR(new_metadata)) { - jffs2_complete_reservation(c); - jffs2_free_raw_inode(ri); - up(&f->sem); - return PTR_ERR(new_metadata); - } - - /* It worked. Update the inode */ - inode->i_mtime = jffs2_get_timestamp(); - inode->i_size = 0; - old_metadata = f->metadata; - jffs2_truncate_fragtree (c, &f->fragtree, 0); - f->metadata = new_metadata; - if (old_metadata) { - jffs2_mark_node_obsolete(c, old_metadata->raw); - jffs2_free_full_dnode(old_metadata); - } - jffs2_free_raw_inode(ri); - - up(&f->sem); - jffs2_complete_reservation(c); - - return 0; -} - -static int jffs2_fo_write(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio) -{ - struct _inode *inode = (struct _inode *) fp->f_data; - off_t pos = fp->f_offset; - ssize_t resid = uio->uio_resid; - struct jffs2_raw_inode ri; - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); - int i; - - // If the APPEND mode bit was supplied, force all writes to - // the end of the file. - if (fp->f_flag & CYG_FAPPEND) - pos = fp->f_offset = inode->i_size; - - if (pos < 0) - return EINVAL; - - memset(&ri, 0, sizeof(ri)); - - ri.ino = cpu_to_je32(f->inocache->ino); - ri.mode = cpu_to_jemode(inode->i_mode); - ri.uid = cpu_to_je16(inode->i_uid); - ri.gid = cpu_to_je16(inode->i_gid); - ri.atime = ri.ctime = ri.mtime = cpu_to_je32(jffs2_get_timestamp()); - - if (pos > inode->i_size) { - int err; - ri.version = cpu_to_je32(++f->highest_version); - err = jffs2_extend_file(inode, &ri, pos); - if (err) - return -err; - } - ri.isize = cpu_to_je32(inode->i_size); - - // Now loop over the iovecs until they are all done, or - // we get an error. - for (i = 0; i < uio->uio_iovcnt; i++) { - cyg_iovec *iov = &uio->uio_iov[i]; - unsigned char *buf = iov->iov_base; - off_t len = iov->iov_len; - - uint32_t writtenlen; - int err; - - D2(printf("jffs2_fo_write page_start_pos %d\n", pos)); - D2(printf("jffs2_fo_write transfer size %d\n", len)); - - err = jffs2_write_inode_range(c, f, &ri, buf, - pos, len, &writtenlen); - if (err) - return -err; - - if (writtenlen != len) - return ENOSPC; - - pos += len; - resid -= len; - } - - // We wrote some data successfully, update the modified and access - // times of the inode, increase its size appropriately, and update - // the file offset and transfer residue. - inode->i_mtime = inode->i_ctime = je32_to_cpu(ri.mtime); - if (pos > inode->i_size) - inode->i_size = pos; - - uio->uio_resid = resid; - fp->f_offset = pos; - - return ENOERR; -} -#endif /* CYGOPT_FS_JFFS2_WRITE */ - -// ------------------------------------------------------------------------- -// jffs2_fo_lseek() -// Seek to a new file position. - -static int jffs2_fo_lseek(struct CYG_FILE_TAG *fp, off_t * apos, int whence) -{ - struct _inode *node = (struct _inode *) fp->f_data; - off_t pos = *apos; - - D2(printf("jffs2_fo_lseek\n")); - - switch (whence) { - case SEEK_SET: - // Pos is already where we want to be. - break; - - case SEEK_CUR: - // Add pos to current offset. - pos += fp->f_offset; - break; - - case SEEK_END: - // Add pos to file size. - pos += node->i_size; - break; - - default: - return EINVAL; - } - - if (pos < 0 ) - return EINVAL; - - // All OK, set fp offset and return new position. - *apos = fp->f_offset = pos; - - return ENOERR; -} - -// ------------------------------------------------------------------------- -// jffs2_fo_ioctl() -// Handle ioctls. Currently none are defined. - -static int jffs2_fo_ioctl(struct CYG_FILE_TAG *fp, CYG_ADDRWORD com, - CYG_ADDRWORD data) -{ - // No Ioctls currenly defined. - - D2(printf("jffs2_fo_ioctl\n")); - - return EINVAL; -} - -// ------------------------------------------------------------------------- -// jffs2_fo_fsync(). -// Force the file out to data storage. - -static int jffs2_fo_fsync(struct CYG_FILE_TAG *fp, int mode) -{ - // Data is always permanently where it belongs, nothing to do - // here. - - D2(printf("jffs2_fo_fsync\n")); - - return ENOERR; -} - -// ------------------------------------------------------------------------- -// jffs2_fo_close() -// Close a file. We just decrement the refcnt and let it go away if -// that is all that is keeping it here. - -static int jffs2_fo_close(struct CYG_FILE_TAG *fp) -{ - struct _inode *node = (struct _inode *) fp->f_data; - - D2(printf("jffs2_fo_close\n")); - - jffs2_iput(node); - - fp->f_data = 0; // zero data pointer - - return ENOERR; -} - -// ------------------------------------------------------------------------- -//jffs2_fo_fstat() -// Get file status. - -static int jffs2_fo_fstat(struct CYG_FILE_TAG *fp, struct stat *buf) -{ - struct _inode *node = (struct _inode *) fp->f_data; - - D2(printf("jffs2_fo_fstat\n")); - - // Fill in the status - buf->st_mode = node->i_mode; - buf->st_ino = node->i_ino; - buf->st_dev = 0; - buf->st_nlink = node->i_nlink; - buf->st_uid = node->i_uid; - buf->st_gid = node->i_gid; - buf->st_size = node->i_size; - buf->st_atime = node->i_atime; - buf->st_mtime = node->i_mtime; - buf->st_ctime = node->i_ctime; - - return ENOERR; -} - -// ------------------------------------------------------------------------- -// jffs2_fo_getinfo() -// Get info. Currently only supports fpathconf(). - -static int jffs2_fo_getinfo(struct CYG_FILE_TAG *fp, int key, void *buf, - int len) -{ - struct _inode *node = (struct _inode *) fp->f_data; - int err; - - D2(printf("jffs2_fo_getinfo\n")); - - switch (key) { - case FS_INFO_CONF: - err = jffs2_pathconf(node, (struct cyg_pathconf_info *) buf); - break; - - default: - err = EINVAL; - } - return err; -} - -// ------------------------------------------------------------------------- -// jffs2_fo_setinfo() -// Set info. Nothing supported here. - -static int jffs2_fo_setinfo(struct CYG_FILE_TAG *fp, int key, void *buf, - int len) -{ - // No setinfo key supported at present - - D2(printf("jffs2_fo_setinfo\n")); - - return ENOERR; -} - -//========================================================================== -// Directory operations - -// ------------------------------------------------------------------------- -// jffs2_fo_dirread() -// Read a single directory entry from a file. - -static __inline void filldir(char *nbuf, int nlen, const unsigned char *name, int namlen) -{ - int len = nlen < namlen ? nlen : namlen; - memcpy(nbuf, name, len); - nbuf[len] = '\0'; -} - -static int jffs2_fo_dirread(struct CYG_FILE_TAG *fp, struct CYG_UIO_TAG *uio) -{ - struct _inode *d_inode = (struct _inode *) fp->f_data; - struct dirent *ent = (struct dirent *) uio->uio_iov[0].iov_base; - char *nbuf = ent->d_name; -#ifdef CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE - struct _inode *c_ino; -#endif - int nlen = sizeof (ent->d_name) - 1; - off_t len = uio->uio_iov[0].iov_len; - struct jffs2_inode_info *f; - struct _inode *inode = d_inode; - struct jffs2_full_dirent *fd; - unsigned long offset, curofs; - int found = 1; - - if (len < sizeof (struct dirent)) - return EINVAL; - - D1(printk - (KERN_DEBUG "jffs2_readdir() for dir_i #%lu\n", d_inode->i_ino)); - - f = JFFS2_INODE_INFO(inode); - - offset = fp->f_offset; - - if (offset == 0) { - D1(printk - (KERN_DEBUG "Dirent 0: \".\", ino #%lu\n", inode->i_ino)); - filldir(nbuf, nlen, (const unsigned char *) ".", 1); -#ifdef CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE - // Flags here are the same as jffs2_mkdir. Make sure - // d_type is the same as st_mode of calling stat. - ent->d_type = - jemode_to_cpu(cpu_to_jemode(S_IRUGO|S_IXUGO|S_IWUSR|S_IFDIR)); -#endif - goto out; - } - if (offset == 1) { - filldir(nbuf, nlen, (const unsigned char *) "..", 2); -#ifdef CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE - // Flags here are the same as jffs2_mkdir. Make sure - // d_type is the same as st_mode of calling stat. - ent->d_type = - jemode_to_cpu(cpu_to_jemode(S_IRUGO|S_IXUGO|S_IWUSR|S_IFDIR)); -#endif - goto out; - } - - curofs = 1; - down(&f->sem); - for (fd = f->dents; fd; fd = fd->next) { - - curofs++; - /* First loop: curofs = 2; offset = 2 */ - if (curofs < offset) { - D2(printk - (KERN_DEBUG - "Skipping dirent: \"%s\", ino #%u, type %d, because curofs %ld < offset %ld\n", - fd->name, fd->ino, fd->type, curofs, offset)); - continue; - } - if (!fd->ino) { - D2(printk - (KERN_DEBUG "Skipping deletion dirent \"%s\"\n", - fd->name)); - offset++; - continue; - } - D2(printk - (KERN_DEBUG "Dirent %ld: \"%s\", ino #%u, type %d\n", offset, - fd->name, fd->ino, fd->type)); - filldir(nbuf, nlen, fd->name, strlen((char *)fd->name)); -#ifdef CYGPKG_FS_JFFS2_RET_DIRENT_DTYPE - c_ino = jffs2_iget(inode->i_sb, fd->ino); - if(IS_ERR(c_ino)) { - D1(printk(KERN_WARNING "get entry inode failed\n")); - // fileio already set it to zero, so not needed here - // ent->d_type = 0; - } - else { - ent->d_type = c_ino->i_mode; - jffs2_iput(c_ino); - } -#endif - goto out_sem; - } - /* Reached the end of the directory */ - found = 0; - out_sem: - up(&f->sem); - out: - fp->f_offset = ++offset; - if (found) { - uio->uio_resid -= sizeof (struct dirent); - } - return ENOERR; -} - -// ------------------------------------------------------------------------- -// jffs2_fo_dirlseek() -// Seek directory to start. - -static int jffs2_fo_dirlseek(struct CYG_FILE_TAG *fp, off_t * pos, int whence) -{ - // Only allow SEEK_SET to zero - - D2(printf("jffs2_fo_dirlseek\n")); - - if (whence != SEEK_SET || *pos != 0) - return EINVAL; - - *pos = fp->f_offset = 0; - - return ENOERR; -} - -//========================================================================== -// -// Called by JFFS2 -// =============== -// -// -//========================================================================== - -unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c, - struct jffs2_inode_info *f, - unsigned long offset, - unsigned long *priv) -{ - /* FIXME: This works only with one file system mounted at a time */ - int ret; - - ret = jffs2_read_inode_range(c, f, gc_buffer, - offset & ~(PAGE_CACHE_SIZE-1), PAGE_CACHE_SIZE); - if (ret) - return ERR_PTR(ret); - - return gc_buffer; -} - -void jffs2_gc_release_page(struct jffs2_sb_info *c, - unsigned char *ptr, - unsigned long *priv) -{ - /* Do nothing */ -} - -static struct _inode *new_inode(struct super_block *sb) -{ - struct _inode *inode; - struct _inode *cached_inode; - - inode = rt_malloc(sizeof (struct _inode)); - if (inode == NULL) - return 0; - - D2(printf("malloc new_inode %x ####################################\n", - inode)); - - memset(inode, 0, sizeof (struct _inode)); - inode->i_sb = sb; - inode->i_ino = 1; - inode->i_count = 1; - inode->i_nlink = 1; // Let JFFS2 manage the link count - inode->i_size = 0; - - inode->i_cache_next = NULL; // Newest inode, about to be cached - - // Add to the icache - for (cached_inode = sb->s_root; cached_inode != NULL; - cached_inode = cached_inode->i_cache_next) { - if (cached_inode->i_cache_next == NULL) { - cached_inode->i_cache_next = inode; // Current last in cache points to newcomer - inode->i_cache_prev = cached_inode; // Newcomer points back to last - break; - } - } - return inode; -} - -static struct _inode *ilookup(struct super_block *sb, cyg_uint32 ino) -{ - struct _inode *inode = NULL; - - D2(printf("ilookup\n")); - // Check for this inode in the cache - for (inode = sb->s_root; inode != NULL; inode = inode->i_cache_next) { - if (inode->i_ino == ino) { - inode->i_count++; - break; - } - } - return inode; -} - -struct _inode *jffs2_iget(struct super_block *sb, cyg_uint32 ino) -{ - // Called in super.c jffs2_read_super, dir.c jffs2_lookup, - // and gc.c jffs2_garbage_collect_pass - - // Must first check for cached inode - // If this fails let new_inode create one - - struct _inode *inode; - int err; - - D2(printf("jffs2_iget\n")); - - inode = ilookup(sb, ino); - if (inode) - return inode; - - // Not cached, so malloc it - inode = new_inode(sb); - if (inode == NULL) - return ERR_PTR(-ENOMEM); - - inode->i_ino = ino; - - err = jffs2_read_inode(inode); - if (err) { - printf("jffs2_read_inode() failed\n"); - inode->i_nlink = 0; // free _this_ bad inode right now - jffs2_iput(inode); - inode = NULL; - return ERR_PTR(err); - } - return inode; -} - -// ------------------------------------------------------------------------- -// Decrement the reference count on an inode. If this makes the ref count -// zero, then this inode can be freed. - -void jffs2_iput(struct _inode *i) -{ - // Called in jffs2_find - // (and jffs2_open and jffs2_ops_mkdir?) - // super.c jffs2_read_super, - // and gc.c jffs2_garbage_collect_pass - recurse: - if (!i) { - printf("jffs2_iput() called with NULL inode\n"); - // and let it fault... - } - - i->i_count--; - - if (i->i_count < 0) - BUG(); - - if (i->i_count) - return; - - if (!i->i_nlink) { - struct _inode *parent; - - // Remove from the icache linked list and free immediately - if (i->i_cache_prev) - i->i_cache_prev->i_cache_next = i->i_cache_next; - if (i->i_cache_next) - i->i_cache_next->i_cache_prev = i->i_cache_prev; - - parent = i->i_parent; - jffs2_clear_inode(i); - memset(i, 0x5a, sizeof(*i)); - rt_free(i); - - if (parent && parent != i) { - i = parent; - goto recurse; - } - - } else { - // Evict some _other_ inode with i_count zero, leaving - // this latest one in the cache for a while - icache_evict(i->i_sb->s_root, i); - } -} - - -// ------------------------------------------------------------------------- -// EOF jffs2.c - - -static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) -{ - memset(f, 0, sizeof(*f)); - init_MUTEX_LOCKED(&f->sem); -} - -static void jffs2_clear_inode (struct _inode *inode) -{ - /* We can forget about this inode for now - drop all - * the nodelists associated with it, etc. - */ - struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); - struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); - - D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); - - jffs2_do_clear_inode(c, f); -} - - -/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, - fill in the raw_inode while you're at it. */ -struct _inode *jffs2_new_inode (struct _inode *dir_i, int mode, struct jffs2_raw_inode *ri) -{ - struct _inode *inode; - struct super_block *sb = dir_i->i_sb; - struct jffs2_sb_info *c; - struct jffs2_inode_info *f; - int ret; - - D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode)); - - c = JFFS2_SB_INFO(sb); - - inode = new_inode(sb); - - if (!inode) - return ERR_PTR(-ENOMEM); - - f = JFFS2_INODE_INFO(inode); - jffs2_init_inode_info(f); - - memset(ri, 0, sizeof(*ri)); - /* Set OS-specific defaults for new inodes */ - ri->uid = ri->gid = cpu_to_je16(0); - ri->mode = cpu_to_jemode(mode); - ret = jffs2_do_new_inode (c, f, mode, ri); - if (ret) { - // forceful evict: f->sem is locked already, and the - // inode is bad. - if (inode->i_cache_prev) - inode->i_cache_prev->i_cache_next = inode->i_cache_next; - if (inode->i_cache_next) - inode->i_cache_next->i_cache_prev = inode->i_cache_prev; - up(&(f->sem)); - jffs2_clear_inode(inode); - memset(inode, 0x6a, sizeof(*inode)); - rt_free(inode); - return ERR_PTR(ret); - } - inode->i_nlink = 1; - inode->i_ino = je32_to_cpu(ri->ino); - inode->i_mode = jemode_to_cpu(ri->mode); - inode->i_gid = je16_to_cpu(ri->gid); - inode->i_uid = je16_to_cpu(ri->uid); - inode->i_atime = inode->i_ctime = inode->i_mtime = jffs2_get_timestamp(); - ri->atime = ri->mtime = ri->ctime = cpu_to_je32(inode->i_mtime); - - inode->i_size = 0; - - return inode; -} - - -static int jffs2_read_inode (struct _inode *inode) -{ - struct jffs2_inode_info *f; - struct jffs2_sb_info *c; - struct jffs2_raw_inode latest_node; - int ret; - - D1(printk(KERN_DEBUG "jffs2_read_inode(): inode->i_ino == %lu\n", inode->i_ino)); - - f = JFFS2_INODE_INFO(inode); - c = JFFS2_SB_INFO(inode->i_sb); - - jffs2_init_inode_info(f); - - ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node); - - if (ret) { - up(&f->sem); - return ret; - } - inode->i_mode = jemode_to_cpu(latest_node.mode); - inode->i_uid = je16_to_cpu(latest_node.uid); - inode->i_gid = je16_to_cpu(latest_node.gid); - inode->i_size = je32_to_cpu(latest_node.isize); - inode->i_atime = je32_to_cpu(latest_node.atime); - inode->i_mtime = je32_to_cpu(latest_node.mtime); - inode->i_ctime = je32_to_cpu(latest_node.ctime); - - inode->i_nlink = f->inocache->nlink; - up(&f->sem); - - D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n")); - return 0; -} - - -void jffs2_gc_release_inode(struct jffs2_sb_info *c, - struct jffs2_inode_info *f) -{ - jffs2_iput(OFNI_EDONI_2SFFJ(f)); -} - -struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c, - int inum, int nlink) -{ - struct _inode *inode; - struct jffs2_inode_cache *ic; - if (!nlink) { - /* The inode has zero nlink but its nodes weren't yet marked - obsolete. This has to be because we're still waiting for - the final (close() and) jffs2_iput() to happen. - - There's a possibility that the final jffs2_iput() could have - happened while we were contemplating. In order to ensure - that we don't cause a new read_inode() (which would fail) - for the inode in question, we use ilookup() in this case - instead of jffs2_iget(). - - The nlink can't _become_ zero at this point because we're - holding the alloc_sem, and jffs2_do_unlink() would also - need that while decrementing nlink on any inode. - */ - inode = ilookup(OFNI_BS_2SFFJ(c), inum); - if (!inode) { - D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n", - inum)); - - spin_lock(&c->inocache_lock); - ic = jffs2_get_ino_cache(c, inum); - if (!ic) { - D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum)); - spin_unlock(&c->inocache_lock); - return NULL; - } - if (ic->state != INO_STATE_CHECKEDABSENT) { - /* Wait for progress. Don't just loop */ - D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n", - ic->ino, ic->state)); - sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); - } else { - spin_unlock(&c->inocache_lock); - } - - return NULL; - } - } else { - /* Inode has links to it still; they're not going away because - jffs2_do_unlink() would need the alloc_sem and we have it. - Just jffs2_iget() it, and if read_inode() is necessary that's OK. - */ - inode = jffs2_iget(OFNI_BS_2SFFJ(c), inum); - if (IS_ERR(inode)) - return (void *)inode; - } - - return JFFS2_INODE_INFO(inode); -} - - - -uint32_t jffs2_from_os_mode(uint32_t osmode) -{ - uint32_t jmode = ((osmode & S_IRUSR)?00400:0) | - ((osmode & S_IWUSR)?00200:0) | - ((osmode & S_IXUSR)?00100:0) | - ((osmode & S_IRGRP)?00040:0) | - ((osmode & S_IWGRP)?00020:0) | - ((osmode & S_IXGRP)?00010:0) | - ((osmode & S_IROTH)?00004:0) | - ((osmode & S_IWOTH)?00002:0) | - ((osmode & S_IXOTH)?00001:0); - - switch (osmode & S_IFMT) { -// case S_IFSOCK: -// return jmode | 0140000; -// case S_IFLNK: -// return jmode | 0120000; - case S_IFREG: - return jmode | 0100000; - case S_IFBLK: - return jmode | 0060000; - case S_IFDIR: - return jmode | 0040000; - case S_IFCHR: - return jmode | 0020000; - case S_IFIFO: - return jmode | 0010000; - case S_ISUID: - return jmode | 0004000; - case S_ISGID: - return jmode | 0002000; -#ifdef S_ISVTX - case S_ISVTX: - return jmode | 0001000; -#endif - } - printf("os_to_jffs2_mode() cannot convert 0x%x\n", osmode); - BUG(); - return 0; -} - -uint32_t jffs2_to_os_mode (uint32_t jmode) -{ - uint32_t osmode = ((jmode & 00400)?S_IRUSR:0) | - ((jmode & 00200)?S_IWUSR:0) | - ((jmode & 00100)?S_IXUSR:0) | - ((jmode & 00040)?S_IRGRP:0) | - ((jmode & 00020)?S_IWGRP:0) | - ((jmode & 00010)?S_IXGRP:0) | - ((jmode & 00004)?S_IROTH:0) | - ((jmode & 00002)?S_IWOTH:0) | - ((jmode & 00001)?S_IXOTH:0); - - switch(jmode & 00170000) { -// case 0140000: prife -// return osmode | S_IFSOCK; prife -// case 0120000: prife -// return osmode | S_IFLNK; prife - case 0100000: - return osmode | S_IFREG; - case 0060000: - return osmode | S_IFBLK; - case 0040000: - return osmode | S_IFDIR; - case 0020000: - return osmode | S_IFCHR; - case 0010000: - return osmode | S_IFIFO; - case 0004000: - return osmode | S_ISUID; - case 0002000: - return osmode | S_ISGID; -#ifdef S_ISVTX - case 0001000: - return osmode | S_ISVTX; -#endif - } - printf("jffs2_to_os_mode() cannot convert 0x%x\n", osmode); - BUG(); - return 0; -} diff --git a/components/dfs/filesystems/jffs2/src/gc.c b/components/dfs/filesystems/jffs2/src/gc.c deleted file mode 100644 index 34ad6ca547..0000000000 --- a/components/dfs/filesystems/jffs2/src/gc.c +++ /dev/null @@ -1,1271 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: gc.c,v 1.152 2005/07/24 15:14:14 dedekind Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/mtd/mtd.h> -#include <linux/slab.h> -#include <linux/pagemap.h> -#include <linux/crc32.h> -#include <linux/compiler.h> -#include <linux/stat.h> -#include "nodelist.h" -#include "compr.h" - -static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, - struct jffs2_inode_cache *ic, - struct jffs2_raw_node_ref *raw); -static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dnode *fd); -static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); -static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dirent *fd); -static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, - uint32_t start, uint32_t end); -static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, - uint32_t start, uint32_t end); -static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f); - -/* Called with erase_completion_lock held */ -static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c) -{ - struct jffs2_eraseblock *ret; - struct list_head *nextlist = NULL; - int n = jiffies % 128; - - /* Pick an eraseblock to garbage collect next. This is where we'll - put the clever wear-levelling algorithms. Eventually. */ - /* We possibly want to favour the dirtier blocks more when the - number of free blocks is low. */ -again: - if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) { - D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n")); - nextlist = &c->bad_used_list; - } else if (n < 50 && !list_empty(&c->erasable_list)) { - /* Note that most of them will have gone directly to be erased. - So don't favour the erasable_list _too_ much. */ - D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next\n")); - nextlist = &c->erasable_list; - } else if (n < 110 && !list_empty(&c->very_dirty_list)) { - /* Most of the time, pick one off the very_dirty list */ - D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next\n")); - nextlist = &c->very_dirty_list; - } else if (n < 126 && !list_empty(&c->dirty_list)) { - D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next\n")); - nextlist = &c->dirty_list; - } else if (!list_empty(&c->clean_list)) { - D1(printk(KERN_DEBUG "Picking block from clean_list to GC next\n")); - nextlist = &c->clean_list; - } else if (!list_empty(&c->dirty_list)) { - D1(printk(KERN_DEBUG "Picking block from dirty_list to GC next (clean_list was empty)\n")); - - nextlist = &c->dirty_list; - } else if (!list_empty(&c->very_dirty_list)) { - D1(printk(KERN_DEBUG "Picking block from very_dirty_list to GC next (clean_list and dirty_list were empty)\n")); - nextlist = &c->very_dirty_list; - } else if (!list_empty(&c->erasable_list)) { - D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n")); - - nextlist = &c->erasable_list; - } else if (!list_empty(&c->erasable_pending_wbuf_list)) { - /* There are blocks are wating for the wbuf sync */ - D1(printk(KERN_DEBUG "Synching wbuf in order to reuse erasable_pending_wbuf_list blocks\n")); - spin_unlock(&c->erase_completion_lock); - jffs2_flush_wbuf_pad(c); - spin_lock(&c->erase_completion_lock); - goto again; - } else { - /* Eep. All were empty */ - D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n")); - return NULL; - } - - ret = list_entry(nextlist->next, struct jffs2_eraseblock, list); - list_del(&ret->list); - c->gcblock = ret; - ret->gc_node = ret->first_node; - if (!ret->gc_node) { - printk(KERN_WARNING "Eep. ret->gc_node for block at 0x%08x is NULL\n", ret->offset); - BUG(); - } - - /* Have we accidentally picked a clean block with wasted space ? */ - if (ret->wasted_size) { - D1(printk(KERN_DEBUG "Converting wasted_size %08x to dirty_size\n", ret->wasted_size)); - ret->dirty_size += ret->wasted_size; - c->wasted_size -= ret->wasted_size; - c->dirty_size += ret->wasted_size; - ret->wasted_size = 0; - } - - return ret; -} - -/* jffs2_garbage_collect_pass - * Make a single attempt to progress GC. Move one node, and possibly - * start erasing one eraseblock. - */ -int jffs2_garbage_collect_pass(struct jffs2_sb_info *c) -{ - struct jffs2_inode_info *f; - struct jffs2_inode_cache *ic; - struct jffs2_eraseblock *jeb; - struct jffs2_raw_node_ref *raw; - int ret = 0, inum, nlink; - - if (down_interruptible(&c->alloc_sem)) - return -EINTR; - - for (;;) { - spin_lock(&c->erase_completion_lock); - if (!c->unchecked_size) - break; - - /* We can't start doing GC yet. We haven't finished checking - the node CRCs etc. Do it now. */ - - /* checked_ino is protected by the alloc_sem */ - if (c->checked_ino > c->highest_ino) { - printk(KERN_CRIT "Checked all inodes but still 0x%x bytes of unchecked space?\n", - c->unchecked_size); - jffs2_dbg_dump_block_lists_nolock(c); - spin_unlock(&c->erase_completion_lock); - BUG(); - } - - spin_unlock(&c->erase_completion_lock); - - spin_lock(&c->inocache_lock); - - ic = jffs2_get_ino_cache(c, c->checked_ino++); - - if (!ic) { - spin_unlock(&c->inocache_lock); - continue; - } - - if (!ic->nlink) { - D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n", - ic->ino)); - spin_unlock(&c->inocache_lock); - continue; - } - switch(ic->state) { - case INO_STATE_CHECKEDABSENT: - case INO_STATE_PRESENT: - D1(printk(KERN_DEBUG "Skipping ino #%u already checked\n", ic->ino)); - spin_unlock(&c->inocache_lock); - continue; - - case INO_STATE_GC: - case INO_STATE_CHECKING: - printk(KERN_WARNING "Inode #%u is in state %d during CRC check phase!\n", ic->ino, ic->state); - spin_unlock(&c->inocache_lock); - BUG(); - - case INO_STATE_READING: - /* We need to wait for it to finish, lest we move on - and trigger the BUG() above while we haven't yet - finished checking all its nodes */ - D1(printk(KERN_DEBUG "Waiting for ino #%u to finish reading\n", ic->ino)); - up(&c->alloc_sem); - sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); - return 0; - - default: - BUG(); - - case INO_STATE_UNCHECKED: - ; - } - ic->state = INO_STATE_CHECKING; - spin_unlock(&c->inocache_lock); - - D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() triggering inode scan of ino#%u\n", ic->ino)); - - ret = jffs2_do_crccheck_inode(c, ic); - if (ret) - printk(KERN_WARNING "Returned error for crccheck of ino #%u. Expect badness...\n", ic->ino); - - jffs2_set_inocache_state(c, ic, INO_STATE_CHECKEDABSENT); - up(&c->alloc_sem); - return ret; - } - - /* First, work out which block we're garbage-collecting */ - jeb = c->gcblock; - - if (!jeb) - jeb = jffs2_find_gc_block(c); - - if (!jeb) { - D1 (printk(KERN_NOTICE "jffs2: Couldn't find erase block to garbage collect!\n")); - spin_unlock(&c->erase_completion_lock); - up(&c->alloc_sem); - return -EIO; - } - - D1(printk(KERN_DEBUG "GC from block %08x, used_size %08x, dirty_size %08x, free_size %08x\n", jeb->offset, jeb->used_size, jeb->dirty_size, jeb->free_size)); - D1(if (c->nextblock) - printk(KERN_DEBUG "Nextblock at %08x, used_size %08x, dirty_size %08x, wasted_size %08x, free_size %08x\n", c->nextblock->offset, c->nextblock->used_size, c->nextblock->dirty_size, c->nextblock->wasted_size, c->nextblock->free_size)); - - if (!jeb->used_size) { - up(&c->alloc_sem); - goto eraseit; - } - - raw = jeb->gc_node; - - while(ref_obsolete(raw)) { - D1(printk(KERN_DEBUG "Node at 0x%08x is obsolete... skipping\n", ref_offset(raw))); - raw = raw->next_phys; - if (unlikely(!raw)) { - printk(KERN_WARNING "eep. End of raw list while still supposedly nodes to GC\n"); - printk(KERN_WARNING "erase block at 0x%08x. free_size 0x%08x, dirty_size 0x%08x, used_size 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size); - jeb->gc_node = raw; - spin_unlock(&c->erase_completion_lock); - up(&c->alloc_sem); - BUG(); - } - } - jeb->gc_node = raw; - - D1(printk(KERN_DEBUG "Going to garbage collect node at 0x%08x\n", ref_offset(raw))); - - if (!raw->next_in_ino) { - /* Inode-less node. Clean marker, snapshot or something like that */ - /* FIXME: If it's something that needs to be copied, including something - we don't grok that has JFFS2_NODETYPE_RWCOMPAT_COPY, we should do so */ - spin_unlock(&c->erase_completion_lock); - jffs2_mark_node_obsolete(c, raw); - up(&c->alloc_sem); - goto eraseit_lock; - } - - ic = jffs2_raw_ref_to_ic(raw); - - /* We need to hold the inocache. Either the erase_completion_lock or - the inocache_lock are sufficient; we trade down since the inocache_lock - causes less contention. */ - spin_lock(&c->inocache_lock); - - spin_unlock(&c->erase_completion_lock); - - D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass collecting from block @0x%08x. Node @0x%08x(%d), ino #%u\n", jeb->offset, ref_offset(raw), ref_flags(raw), ic->ino)); - - /* Three possibilities: - 1. Inode is already in-core. We must iget it and do proper - updating to its fragtree, etc. - 2. Inode is not in-core, node is REF_PRISTINE. We lock the - inocache to prevent a read_inode(), copy the node intact. - 3. Inode is not in-core, node is not pristine. We must iget() - and take the slow path. - */ - - switch(ic->state) { - case INO_STATE_CHECKEDABSENT: - /* It's been checked, but it's not currently in-core. - We can just copy any pristine nodes, but have - to prevent anyone else from doing read_inode() while - we're at it, so we set the state accordingly */ - if (ref_flags(raw) == REF_PRISTINE) - ic->state = INO_STATE_GC; - else { - D1(printk(KERN_DEBUG "Ino #%u is absent but node not REF_PRISTINE. Reading.\n", - ic->ino)); - } - break; - - case INO_STATE_PRESENT: - /* It's in-core. GC must iget() it. */ - break; - - case INO_STATE_UNCHECKED: - case INO_STATE_CHECKING: - case INO_STATE_GC: - /* Should never happen. We should have finished checking - by the time we actually start doing any GC, and since - we're holding the alloc_sem, no other garbage collection - can happen. - */ - printk(KERN_CRIT "Inode #%u already in state %d in jffs2_garbage_collect_pass()!\n", - ic->ino, ic->state); - up(&c->alloc_sem); - spin_unlock(&c->inocache_lock); - BUG(); - - case INO_STATE_READING: - /* Someone's currently trying to read it. We must wait for - them to finish and then go through the full iget() route - to do the GC. However, sometimes read_inode() needs to get - the alloc_sem() (for marking nodes invalid) so we must - drop the alloc_sem before sleeping. */ - - up(&c->alloc_sem); - D1(printk(KERN_DEBUG "jffs2_garbage_collect_pass() waiting for ino #%u in state %d\n", - ic->ino, ic->state)); - sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); - /* And because we dropped the alloc_sem we must start again from the - beginning. Ponder chance of livelock here -- we're returning success - without actually making any progress. - - Q: What are the chances that the inode is back in INO_STATE_READING - again by the time we next enter this function? And that this happens - enough times to cause a real delay? - - A: Small enough that I don't care :) - */ - return 0; - } - - /* OK. Now if the inode is in state INO_STATE_GC, we are going to copy the - node intact, and we don't have to muck about with the fragtree etc. - because we know it's not in-core. If it _was_ in-core, we go through - all the iget() crap anyway */ - - if (ic->state == INO_STATE_GC) { - spin_unlock(&c->inocache_lock); - - ret = jffs2_garbage_collect_pristine(c, ic, raw); - - spin_lock(&c->inocache_lock); - ic->state = INO_STATE_CHECKEDABSENT; - wake_up(&c->inocache_wq); - - if (ret != -EBADFD) { - spin_unlock(&c->inocache_lock); - goto release_sem; - } - - /* Fall through if it wanted us to, with inocache_lock held */ - } - - /* Prevent the fairly unlikely race where the gcblock is - entirely obsoleted by the final close of a file which had - the only valid nodes in the block, followed by erasure, - followed by freeing of the ic because the erased block(s) - held _all_ the nodes of that inode.... never been seen but - it's vaguely possible. */ - - inum = ic->ino; - nlink = ic->nlink; - spin_unlock(&c->inocache_lock); - - f = jffs2_gc_fetch_inode(c, inum, nlink); - if (IS_ERR(f)) { - ret = PTR_ERR(f); - goto release_sem; - } - if (!f) { - ret = 0; - goto release_sem; - } - - ret = jffs2_garbage_collect_live(c, jeb, raw, f); - - jffs2_gc_release_inode(c, f); - - release_sem: - up(&c->alloc_sem); - - eraseit_lock: - /* If we've finished this block, start it erasing */ - spin_lock(&c->erase_completion_lock); - - eraseit: - if (c->gcblock && !c->gcblock->used_size) { - D1(printk(KERN_DEBUG "Block at 0x%08x completely obsoleted by GC. Moving to erase_pending_list\n", c->gcblock->offset)); - /* We're GC'ing an empty block? */ - list_add_tail(&c->gcblock->list, &c->erase_pending_list); - c->gcblock = NULL; - c->nr_erasing_blocks++; - jffs2_erase_pending_trigger(c); - } - spin_unlock(&c->erase_completion_lock); - - return ret; -} - -static int jffs2_garbage_collect_live(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_raw_node_ref *raw, struct jffs2_inode_info *f) -{ - struct jffs2_node_frag *frag; - struct jffs2_full_dnode *fn = NULL; - struct jffs2_full_dirent *fd; - uint32_t start = 0, end = 0, nrfrags = 0; - int ret = 0; - - down(&f->sem); - - /* Now we have the lock for this inode. Check that it's still the one at the head - of the list. */ - - spin_lock(&c->erase_completion_lock); - - if (c->gcblock != jeb) { - spin_unlock(&c->erase_completion_lock); - D1(printk(KERN_DEBUG "GC block is no longer gcblock. Restart\n")); - goto upnout; - } - if (ref_obsolete(raw)) { - spin_unlock(&c->erase_completion_lock); - D1(printk(KERN_DEBUG "node to be GC'd was obsoleted in the meantime.\n")); - /* They'll call again */ - goto upnout; - } - spin_unlock(&c->erase_completion_lock); - - /* OK. Looks safe. And nobody can get us now because we have the semaphore. Move the block */ - if (f->metadata && f->metadata->raw == raw) { - fn = f->metadata; - ret = jffs2_garbage_collect_metadata(c, jeb, f, fn); - goto upnout; - } - - /* FIXME. Read node and do lookup? */ - for (frag = frag_first(&f->fragtree); frag; frag = frag_next(frag)) { - if (frag->node && frag->node->raw == raw) { - fn = frag->node; - end = frag->ofs + frag->size; - if (!nrfrags++) - start = frag->ofs; - if (nrfrags == frag->node->frags) - break; /* We've found them all */ - } - } - if (fn) { - if (ref_flags(raw) == REF_PRISTINE) { - ret = jffs2_garbage_collect_pristine(c, f->inocache, raw); - if (!ret) { - /* Urgh. Return it sensibly. */ - frag->node->raw = f->inocache->nodes; - } - if (ret != -EBADFD) - goto upnout; - } - /* We found a datanode. Do the GC */ - if((start >> PAGE_CACHE_SHIFT) < ((end-1) >> PAGE_CACHE_SHIFT)) { - /* It crosses a page boundary. Therefore, it must be a hole. */ - ret = jffs2_garbage_collect_hole(c, jeb, f, fn, start, end); - } else { - /* It could still be a hole. But we GC the page this way anyway */ - ret = jffs2_garbage_collect_dnode(c, jeb, f, fn, start, end); - } - goto upnout; - } - - /* Wasn't a dnode. Try dirent */ - for (fd = f->dents; fd; fd=fd->next) { - if (fd->raw == raw) - break; - } - - if (fd && fd->ino) { - ret = jffs2_garbage_collect_dirent(c, jeb, f, fd); - } else if (fd) { - ret = jffs2_garbage_collect_deletion_dirent(c, jeb, f, fd); - } else { - printk(KERN_WARNING "Raw node at 0x%08x wasn't in node lists for ino #%u\n", - ref_offset(raw), f->inocache->ino); - if (ref_obsolete(raw)) { - printk(KERN_WARNING "But it's obsolete so we don't mind too much\n"); - } else { - jffs2_dbg_dump_node(c, ref_offset(raw)); - BUG(); - } - } - upnout: - up(&f->sem); - - return ret; -} - -static int jffs2_garbage_collect_pristine(struct jffs2_sb_info *c, - struct jffs2_inode_cache *ic, - struct jffs2_raw_node_ref *raw) -{ - union jffs2_node_union *node; - struct jffs2_raw_node_ref *nraw; - size_t retlen; - int ret; - uint32_t phys_ofs, alloclen; - uint32_t crc, rawlen; - int retried = 0; - - D1(printk(KERN_DEBUG "Going to GC REF_PRISTINE node at 0x%08x\n", ref_offset(raw))); - - rawlen = ref_totlen(c, c->gcblock, raw); - - /* Ask for a small amount of space (or the totlen if smaller) because we - don't want to force wastage of the end of a block if splitting would - work. */ - ret = jffs2_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN, - rawlen), &phys_ofs, &alloclen); - if (ret) - return ret; - - if (alloclen < rawlen) { - /* Doesn't fit untouched. We'll go the old route and split it */ - return -EBADFD; - } - - node = kmalloc(rawlen, GFP_KERNEL); - if (!node) - return -ENOMEM; - - ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (unsigned char *)node); - if (!ret && retlen != rawlen) - ret = -EIO; - if (ret) - goto out_node; - - crc = crc32(0, node, sizeof(struct jffs2_unknown_node)-4); - if (je32_to_cpu(node->u.hdr_crc) != crc) { - printk(KERN_WARNING "Header CRC failed on REF_PRISTINE node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), je32_to_cpu(node->u.hdr_crc), crc); - goto bail; - } - - switch(je16_to_cpu(node->u.nodetype)) { - case JFFS2_NODETYPE_INODE: - crc = crc32(0, node, sizeof(node->i)-8); - if (je32_to_cpu(node->i.node_crc) != crc) { - printk(KERN_WARNING "Node CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), je32_to_cpu(node->i.node_crc), crc); - goto bail; - } - - if (je32_to_cpu(node->i.dsize)) { - crc = crc32(0, node->i.data, je32_to_cpu(node->i.csize)); - if (je32_to_cpu(node->i.data_crc) != crc) { - printk(KERN_WARNING "Data CRC failed on REF_PRISTINE data node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), je32_to_cpu(node->i.data_crc), crc); - goto bail; - } - } - break; - - case JFFS2_NODETYPE_DIRENT: - crc = crc32(0, node, sizeof(node->d)-8); - if (je32_to_cpu(node->d.node_crc) != crc) { - printk(KERN_WARNING "Node CRC failed on REF_PRISTINE dirent node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), je32_to_cpu(node->d.node_crc), crc); - goto bail; - } - - if (node->d.nsize) { - crc = crc32(0, node->d.name, node->d.nsize); - if (je32_to_cpu(node->d.name_crc) != crc) { - printk(KERN_WARNING "Name CRC failed on REF_PRISTINE dirent ode at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ref_offset(raw), je32_to_cpu(node->d.name_crc), crc); - goto bail; - } - } - break; - default: - printk(KERN_WARNING "Unknown node type for REF_PRISTINE node at 0x%08x: 0x%04x\n", - ref_offset(raw), je16_to_cpu(node->u.nodetype)); - goto bail; - } - - nraw = jffs2_alloc_raw_node_ref(); - if (!nraw) { - ret = -ENOMEM; - goto out_node; - } - - /* OK, all the CRCs are good; this node can just be copied as-is. */ - retry: - nraw->flash_offset = phys_ofs; - nraw->__totlen = rawlen; - nraw->next_phys = NULL; - - ret = jffs2_flash_write(c, phys_ofs, rawlen, &retlen, (unsigned char *)node); - - if (ret || (retlen != rawlen)) { - printk(KERN_NOTICE "Write of %d bytes at 0x%08x failed. returned %d, retlen %zd\n", - rawlen, phys_ofs, ret, retlen); - if (retlen) { - /* Doesn't belong to any inode */ - nraw->next_in_ino = NULL; - - nraw->flash_offset |= REF_OBSOLETE; - jffs2_add_physical_node_ref(c, nraw); - jffs2_mark_node_obsolete(c, nraw); - } else { - printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", nraw->flash_offset); - jffs2_free_raw_node_ref(nraw); - } - if (!retried && (nraw = jffs2_alloc_raw_node_ref())) { - /* Try to reallocate space and retry */ - uint32_t dummy; - struct jffs2_eraseblock *jeb = &c->blocks[phys_ofs / c->sector_size]; - - retried = 1; - - D1(printk(KERN_DEBUG "Retrying failed write of REF_PRISTINE node.\n")); - - jffs2_dbg_acct_sanity_check(c,jeb); - jffs2_dbg_acct_paranoia_check(c, jeb); - - ret = jffs2_reserve_space_gc(c, rawlen, &phys_ofs, &dummy); - - if (!ret) { - D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", phys_ofs)); - - jffs2_dbg_acct_sanity_check(c,jeb); - jffs2_dbg_acct_paranoia_check(c, jeb); - - goto retry; - } - D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); - jffs2_free_raw_node_ref(nraw); - } - - jffs2_free_raw_node_ref(nraw); - if (!ret) - ret = -EIO; - goto out_node; - } - nraw->flash_offset |= REF_PRISTINE; - jffs2_add_physical_node_ref(c, nraw); - - /* Link into per-inode list. This is safe because of the ic - state being INO_STATE_GC. Note that if we're doing this - for an inode which is in-core, the 'nraw' pointer is then - going to be fetched from ic->nodes by our caller. */ - spin_lock(&c->erase_completion_lock); - nraw->next_in_ino = ic->nodes; - ic->nodes = nraw; - spin_unlock(&c->erase_completion_lock); - - jffs2_mark_node_obsolete(c, raw); - D1(printk(KERN_DEBUG "WHEEE! GC REF_PRISTINE node at 0x%08x succeeded\n", ref_offset(raw))); - - out_node: - kfree(node); - return ret; - bail: - ret = -EBADFD; - goto out_node; -} - -static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) -{ - struct jffs2_full_dnode *new_fn; - struct jffs2_raw_inode ri; - struct jffs2_node_frag *last_frag; - jint16_t dev; - char *mdata = NULL, mdatalen = 0; - uint32_t alloclen, phys_ofs, ilen; - int ret; - - if (S_ISBLK(JFFS2_F_I_MODE(f)) || - S_ISCHR(JFFS2_F_I_MODE(f)) ) { - /* For these, we don't actually need to read the old node */ - /* FIXME: for minor or major > 255. */ - dev = cpu_to_je16(((JFFS2_F_I_RDEV_MAJ(f) << 8) | - JFFS2_F_I_RDEV_MIN(f))); - mdata = (char *)&dev; - mdatalen = sizeof(dev); - D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bytes of kdev_t\n", mdatalen)); - } else if (S_ISLNK(JFFS2_F_I_MODE(f))) { - mdatalen = fn->size; - mdata = kmalloc(fn->size, GFP_KERNEL); - if (!mdata) { - printk(KERN_WARNING "kmalloc of mdata failed in jffs2_garbage_collect_metadata()\n"); - return -ENOMEM; - } - ret = jffs2_read_dnode(c, f, fn, (unsigned char *)mdata, 0, mdatalen); - if (ret) { - printk(KERN_WARNING "read of old metadata failed in jffs2_garbage_collect_metadata(): %d\n", ret); - kfree(mdata); - return ret; - } - D1(printk(KERN_DEBUG "jffs2_garbage_collect_metadata(): Writing %d bites of symlink target\n", mdatalen)); - - } - - ret = jffs2_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen); - if (ret) { - printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_metadata failed: %d\n", - sizeof(ri)+ mdatalen, ret); - goto out; - } - - last_frag = frag_last(&f->fragtree); - if (last_frag) - /* Fetch the inode length from the fragtree rather then - * from i_size since i_size may have not been updated yet */ - ilen = last_frag->ofs + last_frag->size; - else - ilen = JFFS2_F_I_SIZE(f); - - memset(&ri, 0, sizeof(ri)); - ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); - ri.totlen = cpu_to_je32(sizeof(ri) + mdatalen); - ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4)); - - ri.ino = cpu_to_je32(f->inocache->ino); - ri.version = cpu_to_je32(++f->highest_version); - ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); - ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); - ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); - ri.isize = cpu_to_je32(ilen); - ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); - ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); - ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); - ri.offset = cpu_to_je32(0); - ri.csize = cpu_to_je32(mdatalen); - ri.dsize = cpu_to_je32(mdatalen); - ri.compr = JFFS2_COMPR_NONE; - ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); - ri.data_crc = cpu_to_je32(crc32(0, mdata, mdatalen)); - - new_fn = jffs2_write_dnode(c, f, &ri, (const unsigned char *)mdata, mdatalen, phys_ofs, ALLOC_GC); - - if (IS_ERR(new_fn)) { - printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); - ret = PTR_ERR(new_fn); - goto out; - } - jffs2_mark_node_obsolete(c, fn->raw); - jffs2_free_full_dnode(fn); - f->metadata = new_fn; - out: - if (S_ISLNK(JFFS2_F_I_MODE(f))) - kfree(mdata); - return ret; -} - -static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) -{ - struct jffs2_full_dirent *new_fd; - struct jffs2_raw_dirent rd; - uint32_t alloclen, phys_ofs; - int ret; - - rd.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - rd.nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); - rd.nsize = strlen((const char *)fd->name); - rd.totlen = cpu_to_je32(sizeof(rd) + rd.nsize); - rd.hdr_crc = cpu_to_je32(crc32(0, &rd, sizeof(struct jffs2_unknown_node)-4)); - - rd.pino = cpu_to_je32(f->inocache->ino); - rd.version = cpu_to_je32(++f->highest_version); - rd.ino = cpu_to_je32(fd->ino); - rd.mctime = cpu_to_je32(max(JFFS2_F_I_MTIME(f), JFFS2_F_I_CTIME(f))); - rd.type = fd->type; - rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8)); - rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize)); - - ret = jffs2_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen); - if (ret) { - printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dirent failed: %d\n", - sizeof(rd)+rd.nsize, ret); - return ret; - } - new_fd = jffs2_write_dirent(c, f, &rd, fd->name, rd.nsize, phys_ofs, ALLOC_GC); - - if (IS_ERR(new_fd)) { - printk(KERN_WARNING "jffs2_write_dirent in garbage_collect_dirent failed: %ld\n", PTR_ERR(new_fd)); - return PTR_ERR(new_fd); - } - jffs2_add_fd_to_list(c, new_fd, &f->dents); - return 0; -} - -static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dirent *fd) -{ - struct jffs2_full_dirent **fdp = &f->dents; - int found = 0; - - /* On a medium where we can't actually mark nodes obsolete - pernamently, such as NAND flash, we need to work out - whether this deletion dirent is still needed to actively - delete a 'real' dirent with the same name that's still - somewhere else on the flash. */ - if (!jffs2_can_mark_obsolete(c)) { - struct jffs2_raw_dirent *rd; - struct jffs2_raw_node_ref *raw; - int ret; - size_t retlen; - int name_len = strlen((const char *)fd->name); - uint32_t name_crc = crc32(0, fd->name, name_len); - uint32_t rawlen = ref_totlen(c, jeb, fd->raw); - - rd = kmalloc(rawlen, GFP_KERNEL); - if (!rd) - return -ENOMEM; - - /* Prevent the erase code from nicking the obsolete node refs while - we're looking at them. I really don't like this extra lock but - can't see any alternative. Suggestions on a postcard to... */ - down(&c->erase_free_sem); - - for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) { - - /* We only care about obsolete ones */ - if (!(ref_obsolete(raw))) - continue; - - /* Any dirent with the same name is going to have the same length... */ - if (ref_totlen(c, NULL, raw) != rawlen) - continue; - - /* Doesn't matter if there's one in the same erase block. We're going to - delete it too at the same time. */ - if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset)) - continue; - - D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw))); - - /* This is an obsolete node belonging to the same directory, and it's of the right - length. We need to take a closer look...*/ - ret = jffs2_flash_read(c, ref_offset(raw), rawlen, &retlen, (unsigned char *)rd); - if (ret) { - printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Read error (%d) reading obsolete node at %08x\n", ret, ref_offset(raw)); - /* If we can't read it, we don't need to continue to obsolete it. Continue */ - continue; - } - if (retlen != rawlen) { - printk(KERN_WARNING "jffs2_g_c_deletion_dirent(): Short read (%zd not %u) reading header from obsolete node at %08x\n", - retlen, rawlen, ref_offset(raw)); - continue; - } - - if (je16_to_cpu(rd->nodetype) != JFFS2_NODETYPE_DIRENT) - continue; - - /* If the name CRC doesn't match, skip */ - if (je32_to_cpu(rd->name_crc) != name_crc) - continue; - - /* If the name length doesn't match, or it's another deletion dirent, skip */ - if (rd->nsize != name_len || !je32_to_cpu(rd->ino)) - continue; - - /* OK, check the actual name now */ - if (memcmp(rd->name, fd->name, name_len)) - continue; - - /* OK. The name really does match. There really is still an older node on - the flash which our deletion dirent obsoletes. So we have to write out - a new deletion dirent to replace it */ - up(&c->erase_free_sem); - - D1(printk(KERN_DEBUG "Deletion dirent at %08x still obsoletes real dirent \"%s\" at %08x for ino #%u\n", - ref_offset(fd->raw), fd->name, ref_offset(raw), je32_to_cpu(rd->ino))); - kfree(rd); - - return jffs2_garbage_collect_dirent(c, jeb, f, fd); - } - - up(&c->erase_free_sem); - kfree(rd); - } - - /* No need for it any more. Just mark it obsolete and remove it from the list */ - while (*fdp) { - if ((*fdp) == fd) { - found = 1; - *fdp = fd->next; - break; - } - fdp = &(*fdp)->next; - } - if (!found) { - printk(KERN_WARNING "Deletion dirent \"%s\" not found in list for ino #%u\n", fd->name, f->inocache->ino); - } - jffs2_mark_node_obsolete(c, fd->raw); - jffs2_free_full_dirent(fd); - return 0; -} - -static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, - uint32_t start, uint32_t end) -{ - struct jffs2_raw_inode ri; - struct jffs2_node_frag *frag; - struct jffs2_full_dnode *new_fn; - uint32_t alloclen, phys_ofs, ilen; - int ret; - - D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", - f->inocache->ino, start, end)); - - memset(&ri, 0, sizeof(ri)); - - if(fn->frags > 1) { - size_t readlen; - uint32_t crc; - /* It's partially obsoleted by a later write. So we have to - write it out again with the _same_ version as before */ - ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(ri), &readlen, (unsigned char *)&ri); - if (readlen != sizeof(ri) || ret) { - printk(KERN_WARNING "Node read failed in jffs2_garbage_collect_hole. Ret %d, retlen %zd. Data will be lost by writing new hole node\n", ret, readlen); - goto fill; - } - if (je16_to_cpu(ri.nodetype) != JFFS2_NODETYPE_INODE) { - printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had node type 0x%04x instead of JFFS2_NODETYPE_INODE(0x%04x)\n", - ref_offset(fn->raw), - je16_to_cpu(ri.nodetype), JFFS2_NODETYPE_INODE); - return -EIO; - } - if (je32_to_cpu(ri.totlen) != sizeof(ri)) { - printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had totlen 0x%x instead of expected 0x%zx\n", - ref_offset(fn->raw), - je32_to_cpu(ri.totlen), sizeof(ri)); - return -EIO; - } - crc = crc32(0, &ri, sizeof(ri)-8); - if (crc != je32_to_cpu(ri.node_crc)) { - printk(KERN_WARNING "jffs2_garbage_collect_hole: Node at 0x%08x had CRC 0x%08x which doesn't match calculated CRC 0x%08x\n", - ref_offset(fn->raw), - je32_to_cpu(ri.node_crc), crc); - /* FIXME: We could possibly deal with this by writing new holes for each frag */ - printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", - start, end, f->inocache->ino); - goto fill; - } - if (ri.compr != JFFS2_COMPR_ZERO) { - printk(KERN_WARNING "jffs2_garbage_collect_hole: Node 0x%08x wasn't a hole node!\n", ref_offset(fn->raw)); - printk(KERN_WARNING "Data in the range 0x%08x to 0x%08x of inode #%u will be lost\n", - start, end, f->inocache->ino); - goto fill; - } - } else { - fill: - ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); - ri.totlen = cpu_to_je32(sizeof(ri)); - ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4)); - - ri.ino = cpu_to_je32(f->inocache->ino); - ri.version = cpu_to_je32(++f->highest_version); - ri.offset = cpu_to_je32(start); - ri.dsize = cpu_to_je32(end - start); - ri.csize = cpu_to_je32(0); - ri.compr = JFFS2_COMPR_ZERO; - } - - frag = frag_last(&f->fragtree); - if (frag) - /* Fetch the inode length from the fragtree rather then - * from i_size since i_size may have not been updated yet */ - ilen = frag->ofs + frag->size; - else - ilen = JFFS2_F_I_SIZE(f); - - ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); - ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); - ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); - ri.isize = cpu_to_je32(ilen); - ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); - ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); - ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); - ri.data_crc = cpu_to_je32(0); - ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); - - ret = jffs2_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen); - if (ret) { - printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_hole failed: %d\n", - sizeof(ri), ret); - return ret; - } - new_fn = jffs2_write_dnode(c, f, &ri, NULL, 0, phys_ofs, ALLOC_GC); - - if (IS_ERR(new_fn)) { - printk(KERN_WARNING "Error writing new hole node: %ld\n", PTR_ERR(new_fn)); - return PTR_ERR(new_fn); - } - if (je32_to_cpu(ri.version) == f->highest_version) { - jffs2_add_full_dnode_to_inode(c, f, new_fn); - if (f->metadata) { - jffs2_mark_node_obsolete(c, f->metadata->raw); - jffs2_free_full_dnode(f->metadata); - f->metadata = NULL; - } - return 0; - } - - /* - * We should only get here in the case where the node we are - * replacing had more than one frag, so we kept the same version - * number as before. (Except in case of error -- see 'goto fill;' - * above.) - */ - D1(if(unlikely(fn->frags <= 1)) { - printk(KERN_WARNING "jffs2_garbage_collect_hole: Replacing fn with %d frag(s) but new ver %d != highest_version %d of ino #%d\n", - fn->frags, je32_to_cpu(ri.version), f->highest_version, - je32_to_cpu(ri.ino)); - }); - - /* This is a partially-overlapped hole node. Mark it REF_NORMAL not REF_PRISTINE */ - mark_ref_normal(new_fn->raw); - - for (frag = jffs2_lookup_node_frag(&f->fragtree, fn->ofs); - frag; frag = frag_next(frag)) { - if (frag->ofs > fn->size + fn->ofs) - break; - if (frag->node == fn) { - frag->node = new_fn; - new_fn->frags++; - fn->frags--; - } - } - if (fn->frags) { - printk(KERN_WARNING "jffs2_garbage_collect_hole: Old node still has frags!\n"); - BUG(); - } - if (!new_fn->frags) { - printk(KERN_WARNING "jffs2_garbage_collect_hole: New node has no frags!\n"); - BUG(); - } - - jffs2_mark_node_obsolete(c, fn->raw); - jffs2_free_full_dnode(fn); - - return 0; -} - -static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_inode_info *f, struct jffs2_full_dnode *fn, - uint32_t start, uint32_t end) -{ - struct jffs2_full_dnode *new_fn; - struct jffs2_raw_inode ri; - uint32_t alloclen, phys_ofs, offset, orig_end, orig_start; - int ret = 0; - unsigned char *comprbuf = NULL, *writebuf; - unsigned long pg; - unsigned char *pg_ptr; - - memset(&ri, 0, sizeof(ri)); - - D1(printk(KERN_DEBUG "Writing replacement dnode for ino #%u from offset 0x%x to 0x%x\n", - f->inocache->ino, start, end)); - - orig_end = end; - orig_start = start; - - if (c->nr_free_blocks + c->nr_erasing_blocks > c->resv_blocks_gcmerge) { - /* Attempt to do some merging. But only expand to cover logically - adjacent frags if the block containing them is already considered - to be dirty. Otherwise we end up with GC just going round in - circles dirtying the nodes it already wrote out, especially - on NAND where we have small eraseblocks and hence a much higher - chance of nodes having to be split to cross boundaries. */ - - struct jffs2_node_frag *frag; - uint32_t min, max; - - min = start & ~(PAGE_CACHE_SIZE-1); - max = min + PAGE_CACHE_SIZE; - - frag = jffs2_lookup_node_frag(&f->fragtree, start); - - /* BUG_ON(!frag) but that'll happen anyway... */ - - BUG_ON(frag->ofs != start); - - /* First grow down... */ - while((frag = frag_prev(frag)) && frag->ofs >= min) { - - /* If the previous frag doesn't even reach the beginning, there's - excessive fragmentation. Just merge. */ - if (frag->ofs > min) { - D1(printk(KERN_DEBUG "Expanding down to cover partial frag (0x%x-0x%x)\n", - frag->ofs, frag->ofs+frag->size)); - start = frag->ofs; - continue; - } - /* OK. This frag holds the first byte of the page. */ - if (!frag->node || !frag->node->raw) { - D1(printk(KERN_DEBUG "First frag in page is hole (0x%x-0x%x). Not expanding down.\n", - frag->ofs, frag->ofs+frag->size)); - break; - } else { - - /* OK, it's a frag which extends to the beginning of the page. Does it live - in a block which is still considered clean? If so, don't obsolete it. - If not, cover it anyway. */ - - struct jffs2_raw_node_ref *raw = frag->node->raw; - struct jffs2_eraseblock *jeb; - - jeb = &c->blocks[raw->flash_offset / c->sector_size]; - - if (jeb == c->gcblock) { - D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in gcblock at %08x\n", - frag->ofs, frag->ofs+frag->size, ref_offset(raw))); - start = frag->ofs; - break; - } - if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) { - D1(printk(KERN_DEBUG "Not expanding down to cover frag (0x%x-0x%x) in clean block %08x\n", - frag->ofs, frag->ofs+frag->size, jeb->offset)); - break; - } - - D1(printk(KERN_DEBUG "Expanding down to cover frag (0x%x-0x%x) in dirty block %08x\n", - frag->ofs, frag->ofs+frag->size, jeb->offset)); - start = frag->ofs; - break; - } - } - - /* ... then up */ - - /* Find last frag which is actually part of the node we're to GC. */ - frag = jffs2_lookup_node_frag(&f->fragtree, end-1); - - while((frag = frag_next(frag)) && frag->ofs+frag->size <= max) { - - /* If the previous frag doesn't even reach the beginning, there's lots - of fragmentation. Just merge. */ - if (frag->ofs+frag->size < max) { - D1(printk(KERN_DEBUG "Expanding up to cover partial frag (0x%x-0x%x)\n", - frag->ofs, frag->ofs+frag->size)); - end = frag->ofs + frag->size; - continue; - } - - if (!frag->node || !frag->node->raw) { - D1(printk(KERN_DEBUG "Last frag in page is hole (0x%x-0x%x). Not expanding up.\n", - frag->ofs, frag->ofs+frag->size)); - break; - } else { - - /* OK, it's a frag which extends to the beginning of the page. Does it live - in a block which is still considered clean? If so, don't obsolete it. - If not, cover it anyway. */ - - struct jffs2_raw_node_ref *raw = frag->node->raw; - struct jffs2_eraseblock *jeb; - - jeb = &c->blocks[raw->flash_offset / c->sector_size]; - - if (jeb == c->gcblock) { - D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in gcblock at %08x\n", - frag->ofs, frag->ofs+frag->size, ref_offset(raw))); - end = frag->ofs + frag->size; - break; - } - if (!ISDIRTY(jeb->dirty_size + jeb->wasted_size)) { - D1(printk(KERN_DEBUG "Not expanding up to cover frag (0x%x-0x%x) in clean block %08x\n", - frag->ofs, frag->ofs+frag->size, jeb->offset)); - break; - } - - D1(printk(KERN_DEBUG "Expanding up to cover frag (0x%x-0x%x) in dirty block %08x\n", - frag->ofs, frag->ofs+frag->size, jeb->offset)); - end = frag->ofs + frag->size; - break; - } - } - D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", - orig_start, orig_end, start, end)); - - D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size)); - BUG_ON(end < orig_end); - BUG_ON(start > orig_start); - } - - /* First, use readpage() to read the appropriate page into the page cache */ - /* Q: What happens if we actually try to GC the _same_ page for which commit_write() - * triggered garbage collection in the first place? - * A: I _think_ it's OK. read_cache_page shouldn't deadlock, we'll write out the - * page OK. We'll actually write it out again in commit_write, which is a little - * suboptimal, but at least we're correct. - */ - pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg); - - if (IS_ERR(pg_ptr)) { - printk(KERN_WARNING "read_cache_page() returned error: %ld\n", PTR_ERR(pg_ptr)); - return PTR_ERR(pg_ptr); - } - - offset = start; - while(offset < orig_end) { - uint32_t datalen; - uint32_t cdatalen; - uint16_t comprtype = JFFS2_COMPR_NONE; - - ret = jffs2_reserve_space_gc(c, sizeof(ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen); - - if (ret) { - printk(KERN_WARNING "jffs2_reserve_space_gc of %zd bytes for garbage_collect_dnode failed: %d\n", - sizeof(ri)+ JFFS2_MIN_DATA_LEN, ret); - break; - } - cdatalen = min_t(uint32_t, alloclen - sizeof(ri), end - offset); - datalen = end - offset; - - writebuf = pg_ptr + (offset & (PAGE_CACHE_SIZE -1)); - - comprtype = jffs2_compress(c, f, writebuf, &comprbuf, &datalen, &cdatalen); - - ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); - ri.totlen = cpu_to_je32(sizeof(ri) + cdatalen); - ri.hdr_crc = cpu_to_je32(crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4)); - - ri.ino = cpu_to_je32(f->inocache->ino); - ri.version = cpu_to_je32(++f->highest_version); - ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); - ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); - ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); - ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); - ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); - ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); - ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); - ri.offset = cpu_to_je32(offset); - ri.csize = cpu_to_je32(cdatalen); - ri.dsize = cpu_to_je32(datalen); - ri.compr = comprtype & 0xff; - ri.usercompr = (comprtype >> 8) & 0xff; - ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8)); - ri.data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); - - new_fn = jffs2_write_dnode(c, f, &ri, comprbuf, cdatalen, phys_ofs, ALLOC_GC); - - jffs2_free_comprbuf(comprbuf, writebuf); - - if (IS_ERR(new_fn)) { - printk(KERN_WARNING "Error writing new dnode: %ld\n", PTR_ERR(new_fn)); - ret = PTR_ERR(new_fn); - break; - } - ret = jffs2_add_full_dnode_to_inode(c, f, new_fn); - offset += datalen; - if (f->metadata) { - jffs2_mark_node_obsolete(c, f->metadata->raw); - jffs2_free_full_dnode(f->metadata); - f->metadata = NULL; - } - } - - jffs2_gc_release_page(c, pg_ptr, &pg); - return ret; -} - diff --git a/components/dfs/filesystems/jffs2/src/gcthread.c b/components/dfs/filesystems/jffs2/src/gcthread.c deleted file mode 100644 index ab66e1878e..0000000000 --- a/components/dfs/filesystems/jffs2/src/gcthread.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: gcthread.c,v 1.3 2005/01/22 16:01:12 lunn Exp $ - * - */ -#include <linux/kernel.h> -#include "nodelist.h" -//#include <cyg/kernel/kapi.h> prife - -#if defined(CYGOPT_FS_JFFS2_GCTHREAD) - -#define GC_THREAD_FLAG_TRIG 1 -#define GC_THREAD_FLAG_STOP 2 -#define GC_THREAD_FLAG_HAS_EXIT 4 - -#if 0 -static cyg_thread_entry_t jffs2_garbage_collect_thread; - -void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c) -{ - struct super_block *sb=OFNI_BS_2SFFJ(c); - - /* Wake up the thread */ - D1(printk("jffs2_garbage_collect_trigger\n")); - - cyg_flag_setbits(&sb->s_gc_thread_flags,GC_THREAD_FLAG_TRIG); -} - - -void -jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c) -{ - struct super_block *sb=OFNI_BS_2SFFJ(c); - - RT_ASSERT(c); - RT_ASSERT(!sb->s_gc_thread_handle); - - cyg_flag_init(&sb->s_gc_thread_flags); - cyg_mutex_init(&sb->s_lock); - - D1(printk("jffs2_start_garbage_collect_thread\n")); - /* Start the thread. Doesn't matter if it fails -- it's only an - * optimisation anyway */ - cyg_thread_create(CYGNUM_JFFS2_GC_THREAD_PRIORITY, - jffs2_garbage_collect_thread, - (unsigned long)c,"jffs2 gc thread", - (void*)sb->s_gc_thread_stack, - sizeof(sb->s_gc_thread_stack), - &sb->s_gc_thread_handle, - &sb->s_gc_thread); - - cyg_thread_resume(sb->s_gc_thread_handle); -} - -void -jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c) -{ - struct super_block *sb=OFNI_BS_2SFFJ(c); - - RT_ASSERT(sb->s_gc_thread_handle); - - D1(printk("jffs2_stop_garbage_collect_thread\n")); - /* Stop the thread and wait for it if necessary */ - - cyg_flag_setbits(&sb->s_gc_thread_flags,GC_THREAD_FLAG_STOP); - - D1(printk("jffs2_stop_garbage_collect_thread wait\n")); - - cyg_flag_wait(&sb->s_gc_thread_flags, - GC_THREAD_FLAG_HAS_EXIT, - CYG_FLAG_WAITMODE_OR| CYG_FLAG_WAITMODE_CLR); - - // Kill and free the resources ... this is safe due to the flag - // from the thread. - cyg_thread_kill(sb->s_gc_thread_handle); - cyg_thread_delete(sb->s_gc_thread_handle); - - cyg_mutex_destroy(&sb->s_lock); - cyg_flag_destroy(&sb->s_gc_thread_flags); -} - - -static void -jffs2_garbage_collect_thread(unsigned long data) -{ - struct jffs2_sb_info *c=(struct jffs2_sb_info *)data; - struct super_block *sb=OFNI_BS_2SFFJ(c); - cyg_flag_value_t flag; - cyg_mtab_entry *mte; - - D1(printk("jffs2_garbage_collect_thread START\n")); - - while(1) { - flag=cyg_flag_timed_wait(&sb->s_gc_thread_flags, - GC_THREAD_FLAG_TRIG|GC_THREAD_FLAG_STOP, - CYG_FLAG_WAITMODE_OR| CYG_FLAG_WAITMODE_CLR, - cyg_current_time()+ - CYGNUM_JFFS2_GS_THREAD_TICKS); - - if (flag & GC_THREAD_FLAG_STOP) - break; - - D1(printk("jffs2: GC THREAD GC BEGIN\n")); - - mte=cyg_fs_root_lookup((cyg_dir *) sb->s_root); - CYG_ASSERT(mte, "Bad mount point"); - cyg_fs_lock(mte, mte->fs->syncmode); - - if (jffs2_garbage_collect_pass(c) == -ENOSPC) { - printf("No space for garbage collection. " - "Aborting JFFS2 GC thread\n"); - break; - } - cyg_fs_unlock(mte, mte->fs->syncmode); - D1(printk("jffs2: GC THREAD GC END\n")); - } - - D1(printk("jffs2_garbage_collect_thread EXIT\n")); - cyg_flag_setbits(&sb->s_gc_thread_flags,GC_THREAD_FLAG_HAS_EXIT); -} -#endif - -rt_uint32_t cyg_current_time(void) -{ - return 0; -} - -static void -jffs2_garbage_collect_thread(unsigned long data); - -void jffs2_garbage_collect_trigger(struct jffs2_sb_info *c) -{ - struct super_block *sb=OFNI_BS_2SFFJ(c); - - /* Wake up the thread */ - D1(printk("jffs2_garbage_collect_trigger\n")); - - rt_event_send(&sb->s_gc_thread_flags,GC_THREAD_FLAG_TRIG); -} - -static struct rt_thread gc_thread; -void -jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c) -{ - struct super_block *sb=OFNI_BS_2SFFJ(c); - cyg_mtab_entry *mte; - int result; - - RT_ASSERT(c); - //RT_ASSERT(!sb->s_gc_thread_handle); - - mte=(cyg_dir *) sb->s_root; - RT_ASSERT(mte); - - rt_event_init(&sb->s_gc_thread_flags, "gc_event", RT_IPC_FLAG_FIFO); - rt_mutex_init(&sb->s_lock, "gc_mutex", RT_IPC_FLAG_FIFO); -// rt_mutex_init(&mte->fs->syncmode, "fs_lock", RT_IPC_FLAG_FIFO); - - D1(printk("jffs2_start_garbage_collect_thread\n")); - /* Start the thread. Doesn't matter if it fails -- it's only an - * optimisation anyway */ - result = rt_thread_init(&sb->s_gc_thread, - "jffs2_gc_thread", - jffs2_garbage_collect_thread, - (void *)c, - (void*)sb->s_gc_thread_stack, - sizeof(sb->s_gc_thread_stack), - CYGNUM_JFFS2_GC_THREAD_PRIORITY, - CYGNUM_JFFS2_GC_THREAD_TICKS - ); - if (result != RT_EOK) { - rt_thread_startup(&sb->s_gc_thread); - /* how to deal with the following filed? */ - /* sb->s_gc_thread_handle; */ - } -} - -void -jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c) -{ - struct super_block *sb=OFNI_BS_2SFFJ(c); - cyg_mtab_entry *mte; - rt_uint32_t e; - rt_err_t result; - - //RT_ASSERT(sb->s_gc_thread_handle); - - D1(printk("jffs2_stop_garbage_collect_thread\n")); - /* Stop the thread and wait for it if necessary */ - - rt_event_send(&sb->s_gc_thread_flags,GC_THREAD_FLAG_STOP); - - D1(printk("jffs2_stop_garbage_collect_thread wait\n")); - - result = rt_event_recv(&sb->s_gc_thread_flags, - GC_THREAD_FLAG_HAS_EXIT, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - RT_WAITING_FOREVER, &e); - if (result == -RT_ETIMEOUT) - { - LOG_E("wait completed timeout"); - return; - } - else if (result == -RT_ERROR) - { - LOG_E("event received error"); - return; - } - - // Kill and free the resources ... this is safe due to the flag - // from the thread. - rt_thread_detach(&sb->s_gc_thread); - rt_sem_detach(&sb->s_lock); - rt_event_detach(&sb->s_gc_thread_flags); -} - - -static void -jffs2_garbage_collect_thread(unsigned long data) -{ - struct jffs2_sb_info *c=(struct jffs2_sb_info *)data; - struct super_block *sb=OFNI_BS_2SFFJ(c); - cyg_mtab_entry *mte; - rt_uint32_t flag = 0; - rt_err_t result; - - D1(printk("jffs2_garbage_collect_thread START\n")); - - while(1) { - result = rt_event_recv(&sb->s_gc_thread_flags, - GC_THREAD_FLAG_TRIG | GC_THREAD_FLAG_STOP, - RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, - cyg_current_time() + CYGNUM_JFFS2_GS_THREAD_TICKS, - &flag); - if (result == -RT_ETIMEOUT) - { - LOG_E("wait completed timeout"); - continue; - } - else if (result == -RT_ERROR) - { - LOG_E("event received error"); - continue; - } - - if (flag & GC_THREAD_FLAG_STOP) - break; - - D1(printk("jffs2: GC THREAD GC BEGIN\n")); - - mte=(cyg_dir *) sb->s_root; - RT_ASSERT(mte != NULL); -// rt_mutex_take(&mte->fs->syncmode, RT_WAITING_FOREVER); - - if (jffs2_garbage_collect_pass(c) == -ENOSPC) { - printf("No space for garbage collection. " - "Aborting JFFS2 GC thread\n"); - break; - } -// rt_mutex_release(&mte->fs->syncmode); - D1(printk("jffs2: GC THREAD GC END\n")); - } - - D1(printk("jffs2_garbage_collect_thread EXIT\n")); - rt_event_send(&sb->s_gc_thread_flags,GC_THREAD_FLAG_HAS_EXIT); -} -#endif diff --git a/components/dfs/filesystems/jffs2/src/histo.h b/components/dfs/filesystems/jffs2/src/histo.h deleted file mode 100644 index 84f184f083..0000000000 --- a/components/dfs/filesystems/jffs2/src/histo.h +++ /dev/null @@ -1,3 +0,0 @@ -/* This file provides the bit-probabilities for the input file */ -#define BIT_DIVIDER 629 -static int bits[9] = { 179,167,183,165,159,198,178,119,}; /* ia32 .so files */ diff --git a/components/dfs/filesystems/jffs2/src/histo_mips.h b/components/dfs/filesystems/jffs2/src/histo_mips.h deleted file mode 100644 index 9a443268d8..0000000000 --- a/components/dfs/filesystems/jffs2/src/histo_mips.h +++ /dev/null @@ -1,2 +0,0 @@ -#define BIT_DIVIDER_MIPS 1043 -static int bits_mips[8] = { 277,249,290,267,229,341,212,241}; /* mips32 */ diff --git a/components/dfs/filesystems/jffs2/src/malloc-ecos.c b/components/dfs/filesystems/jffs2/src/malloc-ecos.c deleted file mode 100644 index df6e3c0f5d..0000000000 --- a/components/dfs/filesystems/jffs2/src/malloc-ecos.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Free Software Foundation, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: malloc-ecos.c,v 1.4 2003/11/26 15:55:35 dwmw2 Exp $ - * - */ - -#include <linux/kernel.h> -#include <cyg/hal/drv_api.h> -#include "nodelist.h" - -#if !defined(CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE) -# define CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE 0 -#endif - -struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize) -{ - return rt_malloc(sizeof(struct jffs2_full_dirent) + namesize); -} - -void jffs2_free_full_dirent(struct jffs2_full_dirent *x) -{ - rt_free(x); -} - -struct jffs2_full_dnode *jffs2_alloc_full_dnode(void) -{ - return rt_malloc(sizeof(struct jffs2_full_dnode)); -} - -void jffs2_free_full_dnode(struct jffs2_full_dnode *x) -{ - rt_free(x); -} - -struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void) -{ - return rt_malloc(sizeof(struct jffs2_raw_dirent)); -} - -void jffs2_free_raw_dirent(struct jffs2_raw_dirent *x) -{ - rt_free(x); -} - -struct jffs2_raw_inode *jffs2_alloc_raw_inode(void) -{ - return rt_malloc(sizeof(struct jffs2_raw_inode)); -} - -void jffs2_free_raw_inode(struct jffs2_raw_inode *x) -{ - rt_free(x); -} - -struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void) -{ - return rt_malloc(sizeof(struct jffs2_tmp_dnode_info)); -} - -void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x) -{ - rt_free(x); -} - -struct jffs2_node_frag *jffs2_alloc_node_frag(void) -{ - return rt_malloc(sizeof(struct jffs2_node_frag)); -} - -void jffs2_free_node_frag(struct jffs2_node_frag *x) -{ - rt_free(x); -} - -#if CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0 - -int jffs2_create_slab_caches(void) -{ - return 0; -} - -void jffs2_destroy_slab_caches(void) -{ -} - -struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void) -{ - return rt_malloc(sizeof(struct jffs2_raw_node_ref)); -} - -void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x) -{ - rt_free(x); -} - -#else // CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0 - -static struct jffs2_raw_node_ref - rnr_pool[CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE] __attribute__ ((aligned (4))), - * first = NULL; -static cyg_drv_mutex_t mutex; - -int jffs2_create_slab_caches(void) -{ - struct jffs2_raw_node_ref * p; - cyg_drv_mutex_init(&mutex); - for ( - p = rnr_pool; - p < rnr_pool + CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE - 1; - p++ - ) - p->next_phys = p + 1; - rnr_pool[CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE - 1].next_phys = NULL; - first = &rnr_pool[0]; - return 0; -} - -void jffs2_destroy_slab_caches(void) -{ -} - -struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void) -{ - struct jffs2_raw_node_ref * p; - - cyg_drv_mutex_lock(&mutex); - p = first; - if (p != NULL) - first = p->next_phys; - cyg_drv_mutex_unlock(&mutex); - return p; -} - -void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *x) -{ - cyg_drv_mutex_lock(&mutex); - x->next_phys = first; - first = x; - cyg_drv_mutex_unlock(&mutex); -} - -#endif // CYGNUM_FS_JFFS2_RAW_NODE_REF_CACHE_POOL_SIZE == 0 - -struct jffs2_inode_cache *jffs2_alloc_inode_cache(void) -{ - struct jffs2_inode_cache *ret = rt_malloc(sizeof(struct jffs2_inode_cache)); - D1(printk(KERN_DEBUG "Allocated inocache at %p\n", ret)); - return ret; -} - -void jffs2_free_inode_cache(struct jffs2_inode_cache *x) -{ - D1(printk(KERN_DEBUG "Freeing inocache at %p\n", x)); - rt_free(x); -} - diff --git a/components/dfs/filesystems/jffs2/src/nodelist.c b/components/dfs/filesystems/jffs2/src/nodelist.c deleted file mode 100644 index aee9d88cff..0000000000 --- a/components/dfs/filesystems/jffs2/src/nodelist.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: nodelist.c,v 1.102 2005/07/28 12:45:10 dedekind Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/mtd/mtd.h> -#include <linux/rbtree.h> -#include <linux/crc32.h> -#include <linux/slab.h> -#include <linux/pagemap.h> -#include "nodelist.h" - -void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list) -{ - struct jffs2_full_dirent **prev = list; - - JFFS2_DBG_DENTLIST("add dirent \"%s\", ino #%u\n", new->name, new->ino); - - while ((*prev) && (*prev)->nhash <= new->nhash) { - if ((*prev)->nhash == new->nhash && !strcmp((const char *)((*prev)->name), (const char *)new->name)) { - /* Duplicate. Free one */ - if (new->version < (*prev)->version) { - JFFS2_DBG_DENTLIST("Eep! Marking new dirent node is obsolete, old is \"%s\", ino #%u\n", - (*prev)->name, (*prev)->ino); - jffs2_mark_node_obsolete(c, new->raw); - jffs2_free_full_dirent(new); - } else { - JFFS2_DBG_DENTLIST("marking old dirent \"%s\", ino #%u bsolete\n", - (*prev)->name, (*prev)->ino); - new->next = (*prev)->next; - jffs2_mark_node_obsolete(c, ((*prev)->raw)); - jffs2_free_full_dirent(*prev); - *prev = new; - } - return; - } - prev = &((*prev)->next); - } - new->next = *prev; - *prev = new; -} - -void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this) -{ - if (this->node) { - this->node->frags--; - if (!this->node->frags) { - /* The node has no valid frags left. It's totally obsoleted */ - JFFS2_DBG_FRAGTREE2("marking old node @0x%08x (0x%04x-0x%04x) obsolete\n", - ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size); - jffs2_mark_node_obsolete(c, this->node->raw); - jffs2_free_full_dnode(this->node); - } else { - JFFS2_DBG_FRAGTREE2("marking old node @0x%08x (0x%04x-0x%04x) REF_NORMAL. frags is %d\n", - ref_offset(this->node->raw), this->node->ofs, this->node->ofs+this->node->size, this->node->frags); - mark_ref_normal(this->node->raw); - } - - } - jffs2_free_node_frag(this); -} - -static void jffs2_fragtree_insert(struct jffs2_node_frag *newfrag, struct jffs2_node_frag *base) -{ - struct rb_node *parent = &base->rb; - struct rb_node **link = &parent; - - JFFS2_DBG_FRAGTREE2("insert frag (0x%04x-0x%04x)\n", newfrag->ofs, newfrag->ofs + newfrag->size); - - while (*link) { - parent = *link; - base = rb_entry(parent, struct jffs2_node_frag, rb); - - JFFS2_DBG_FRAGTREE2("considering frag at 0x%08x\n", base->ofs); - if (newfrag->ofs > base->ofs) - link = &base->rb.rb_right; - else if (newfrag->ofs < base->ofs) - link = &base->rb.rb_left; - else { - JFFS2_ERROR("duplicate frag at %08x (%p,%p)\n", newfrag->ofs, newfrag, base); - BUG(); - } - } - - rb_link_node(&newfrag->rb, &base->rb, link); -} - -/* Doesn't set inode->i_size */ -static int jffs2_add_frag_to_fragtree(struct jffs2_sb_info *c, struct rb_root *list, struct jffs2_node_frag *newfrag) -{ - struct jffs2_node_frag *this; - uint32_t lastend; - - /* Skip all the nodes which are completed before this one starts */ - this = jffs2_lookup_node_frag(list, newfrag->node->ofs); - - if (this) { - JFFS2_DBG_FRAGTREE2("lookup gave frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n", - this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this); - lastend = this->ofs + this->size; - } else { - JFFS2_DBG_FRAGTREE2("lookup gave no frag\n"); - lastend = 0; - } - - /* See if we ran off the end of the list */ - if (lastend <= newfrag->ofs) { - /* We did */ - - /* Check if 'this' node was on the same page as the new node. - If so, both 'this' and the new node get marked REF_NORMAL so - the GC can take a look. - */ - if (lastend && (lastend-1) >> PAGE_CACHE_SHIFT == newfrag->ofs >> PAGE_CACHE_SHIFT) { - if (this->node) - mark_ref_normal(this->node->raw); - mark_ref_normal(newfrag->node->raw); - } - - if (lastend < newfrag->node->ofs) { - /* ... and we need to put a hole in before the new node */ - struct jffs2_node_frag *holefrag = jffs2_alloc_node_frag(); - if (!holefrag) { - jffs2_free_node_frag(newfrag); - return -ENOMEM; - } - holefrag->ofs = lastend; - holefrag->size = newfrag->node->ofs - lastend; - holefrag->node = NULL; - if (this) { - /* By definition, the 'this' node has no right-hand child, - because there are no frags with offset greater than it. - So that's where we want to put the hole */ - JFFS2_DBG_FRAGTREE2("adding hole frag (%p) on right of node at (%p)\n", holefrag, this); - rb_link_node(&holefrag->rb, &this->rb, &this->rb.rb_right); - } else { - JFFS2_DBG_FRAGTREE2("adding hole frag (%p) at root of tree\n", holefrag); - rb_link_node(&holefrag->rb, NULL, &list->rb_node); - } - rb_insert_color(&holefrag->rb, list); - this = holefrag; - } - if (this) { - /* By definition, the 'this' node has no right-hand child, - because there are no frags with offset greater than it. - So that's where we want to put new fragment */ - JFFS2_DBG_FRAGTREE2("adding new frag (%p) on right of node at (%p)\n", newfrag, this); - rb_link_node(&newfrag->rb, &this->rb, &this->rb.rb_right); - } else { - JFFS2_DBG_FRAGTREE2("adding new frag (%p) at root of tree\n", newfrag); - rb_link_node(&newfrag->rb, NULL, &list->rb_node); - } - rb_insert_color(&newfrag->rb, list); - return 0; - } - - JFFS2_DBG_FRAGTREE2("dealing with frag 0x%04x-0x%04x; phys 0x%08x (*%p)\n", - this->ofs, this->ofs+this->size, this->node?(ref_offset(this->node->raw)):0xffffffff, this); - - /* OK. 'this' is pointing at the first frag that newfrag->ofs at least partially obsoletes, - * - i.e. newfrag->ofs < this->ofs+this->size && newfrag->ofs >= this->ofs - */ - if (newfrag->ofs > this->ofs) { - /* This node isn't completely obsoleted. The start of it remains valid */ - - /* Mark the new node and the partially covered node REF_NORMAL -- let - the GC take a look at them */ - mark_ref_normal(newfrag->node->raw); - if (this->node) - mark_ref_normal(this->node->raw); - - if (this->ofs + this->size > newfrag->ofs + newfrag->size) { - /* The new node splits 'this' frag into two */ - struct jffs2_node_frag *newfrag2 = jffs2_alloc_node_frag(); - if (!newfrag2) { - jffs2_free_node_frag(newfrag); - return -ENOMEM; - } - if (this->node) - JFFS2_DBG_FRAGTREE2("split old frag 0x%04x-0x%04x, phys 0x%08x\n", - this->ofs, this->ofs+this->size, ref_offset(this->node->raw)); - else - JFFS2_DBG_FRAGTREE2("split old hole frag 0x%04x-0x%04x\n", - this->ofs, this->ofs+this->size, ref_offset(this->node->raw)); - - /* New second frag pointing to this's node */ - newfrag2->ofs = newfrag->ofs + newfrag->size; - newfrag2->size = (this->ofs+this->size) - newfrag2->ofs; - newfrag2->node = this->node; - if (this->node) - this->node->frags++; - - /* Adjust size of original 'this' */ - this->size = newfrag->ofs - this->ofs; - - /* Now, we know there's no node with offset - greater than this->ofs but smaller than - newfrag2->ofs or newfrag->ofs, for obvious - reasons. So we can do a tree insert from - 'this' to insert newfrag, and a tree insert - from newfrag to insert newfrag2. */ - jffs2_fragtree_insert(newfrag, this); - rb_insert_color(&newfrag->rb, list); - - jffs2_fragtree_insert(newfrag2, newfrag); - rb_insert_color(&newfrag2->rb, list); - - return 0; - } - /* New node just reduces 'this' frag in size, doesn't split it */ - this->size = newfrag->ofs - this->ofs; - - /* Again, we know it lives down here in the tree */ - jffs2_fragtree_insert(newfrag, this); - rb_insert_color(&newfrag->rb, list); - } else { - /* New frag starts at the same point as 'this' used to. Replace - it in the tree without doing a delete and insertion */ - JFFS2_DBG_FRAGTREE2("inserting newfrag (*%p),%d-%d in before 'this' (*%p),%d-%d\n", - newfrag, newfrag->ofs, newfrag->ofs+newfrag->size, this, this->ofs, this->ofs+this->size); - - rb_replace_node(&this->rb, &newfrag->rb, list); - - if (newfrag->ofs + newfrag->size >= this->ofs+this->size) { - JFFS2_DBG_FRAGTREE2("obsoleting node frag %p (%x-%x)\n", this, this->ofs, this->ofs+this->size); - jffs2_obsolete_node_frag(c, this); - } else { - this->ofs += newfrag->size; - this->size -= newfrag->size; - - jffs2_fragtree_insert(this, newfrag); - rb_insert_color(&this->rb, list); - return 0; - } - } - /* OK, now we have newfrag added in the correct place in the tree, but - frag_next(newfrag) may be a fragment which is overlapped by it - */ - while ((this = frag_next(newfrag)) && newfrag->ofs + newfrag->size >= this->ofs + this->size) { - /* 'this' frag is obsoleted completely. */ - JFFS2_DBG_FRAGTREE2("obsoleting node frag %p (%x-%x) and removing from tree\n", - this, this->ofs, this->ofs+this->size); - rb_erase(&this->rb, list); - jffs2_obsolete_node_frag(c, this); - } - /* Now we're pointing at the first frag which isn't totally obsoleted by - the new frag */ - - if (!this || newfrag->ofs + newfrag->size == this->ofs) { - return 0; - } - /* Still some overlap but we don't need to move it in the tree */ - this->size = (this->ofs + this->size) - (newfrag->ofs + newfrag->size); - this->ofs = newfrag->ofs + newfrag->size; - - /* And mark them REF_NORMAL so the GC takes a look at them */ - if (this->node) - mark_ref_normal(this->node->raw); - mark_ref_normal(newfrag->node->raw); - - return 0; -} - -/* Given an inode, probably with existing list of fragments, add the new node - * to the fragment list. - */ -int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn) -{ - int ret; - struct jffs2_node_frag *newfrag; - - if (unlikely(!fn->size)) - return 0; - - newfrag = jffs2_alloc_node_frag(); - if (unlikely(!newfrag)) - return -ENOMEM; - - JFFS2_DBG_FRAGTREE("adding node %#04x-%#04x @0x%08x on flash, newfrag *%p\n", - fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag); - - newfrag->ofs = fn->ofs; - newfrag->size = fn->size; - newfrag->node = fn; - newfrag->node->frags = 1; - - ret = jffs2_add_frag_to_fragtree(c, &f->fragtree, newfrag); - if (unlikely(ret)) - return ret; - - /* If we now share a page with other nodes, mark either previous - or next node REF_NORMAL, as appropriate. */ - if (newfrag->ofs & (PAGE_CACHE_SIZE-1)) { - struct jffs2_node_frag *prev = frag_prev(newfrag); - - mark_ref_normal(fn->raw); - /* If we don't start at zero there's _always_ a previous */ - if (prev->node) - mark_ref_normal(prev->node->raw); - } - - if ((newfrag->ofs+newfrag->size) & (PAGE_CACHE_SIZE-1)) { - struct jffs2_node_frag *next = frag_next(newfrag); - - if (next) { - mark_ref_normal(fn->raw); - if (next->node) - mark_ref_normal(next->node->raw); - } - } - jffs2_dbg_fragtree_paranoia_check_nolock(f); - jffs2_dbg_dump_fragtree_nolock(f); - return 0; -} - - -void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state) -{ - spin_lock(&c->inocache_lock); - ic->state = state; - wake_up(&c->inocache_wq); - spin_unlock(&c->inocache_lock); -} - -/* During mount, this needs no locking. During normal operation, its - callers want to do other stuff while still holding the inocache_lock. - Rather than introducing special case get_ino_cache functions or - callbacks, we just let the caller do the locking itself. */ - -struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino) -{ - struct jffs2_inode_cache *ret; - - ret = c->inocache_list[ino % INOCACHE_HASHSIZE]; - while (ret && ret->ino < ino) { - ret = ret->next; - } - - if (ret && ret->ino != ino) - ret = NULL; - - return ret; -} - -void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new) -{ - struct jffs2_inode_cache **prev; - - spin_lock(&c->inocache_lock); - if (!new->ino) - new->ino = ++c->highest_ino; - - JFFS2_DBG_INOCACHE("add %p (ino #%u)\n", new, new->ino); - - prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE]; - - while ((*prev) && (*prev)->ino < new->ino) { - prev = &(*prev)->next; - } - new->next = *prev; - *prev = new; - - spin_unlock(&c->inocache_lock); -} - -void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old) -{ - struct jffs2_inode_cache **prev; - - JFFS2_DBG_INOCACHE("del %p (ino #%u)\n", old, old->ino); - spin_lock(&c->inocache_lock); - - prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE]; - - while ((*prev) && (*prev)->ino < old->ino) { - prev = &(*prev)->next; - } - if ((*prev) == old) { - *prev = old->next; - } - - /* Free it now unless it's in READING or CLEARING state, which - are the transitions upon read_inode() and clear_inode(). The - rest of the time we know nobody else is looking at it, and - if it's held by read_inode() or clear_inode() they'll free it - for themselves. */ - if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING) - jffs2_free_inode_cache(old); - - spin_unlock(&c->inocache_lock); -} - -void jffs2_free_ino_caches(struct jffs2_sb_info *c) -{ - int i; - struct jffs2_inode_cache *this, *next; - - for (i=0; i<INOCACHE_HASHSIZE; i++) { - this = c->inocache_list[i]; - while (this) { - next = this->next; - jffs2_free_inode_cache(this); - this = next; - } - c->inocache_list[i] = NULL; - } -} - -void jffs2_free_raw_node_refs(struct jffs2_sb_info *c) -{ - int i; - struct jffs2_raw_node_ref *this, *next; - - for (i=0; i<c->nr_blocks; i++) { - this = c->blocks[i].first_node; - while(this) { - next = this->next_phys; - jffs2_free_raw_node_ref(this); - this = next; - } - c->blocks[i].first_node = c->blocks[i].last_node = NULL; - } -} - -struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset) -{ - /* The common case in lookup is that there will be a node - which precisely matches. So we go looking for that first */ - struct rb_node *next; - struct jffs2_node_frag *prev = NULL; - struct jffs2_node_frag *frag = NULL; - - JFFS2_DBG_FRAGTREE2("root %p, offset %d\n", fragtree, offset); - - next = fragtree->rb_node; - - while(next) { - frag = rb_entry(next, struct jffs2_node_frag, rb); - - JFFS2_DBG_FRAGTREE2("considering frag %#04x-%#04x (%p). left %p, right %p\n", - frag->ofs, frag->ofs+frag->size, frag, frag->rb.rb_left, frag->rb.rb_right); - if (frag->ofs + frag->size <= offset) { - JFFS2_DBG_FRAGTREE2("going right from frag %#04x-%#04x, before the region we care about\n", - frag->ofs, frag->ofs+frag->size); - /* Remember the closest smaller match on the way down */ - if (!prev || frag->ofs > prev->ofs) - prev = frag; - next = frag->rb.rb_right; - } else if (frag->ofs > offset) { - JFFS2_DBG_FRAGTREE2("going left from frag %#04x-%#04x, after the region we care about\n", - frag->ofs, frag->ofs+frag->size); - next = frag->rb.rb_left; - } else { - JFFS2_DBG_FRAGTREE2("returning frag %#04x-%#04x, matched\n", - frag->ofs, frag->ofs+frag->size); - return frag; - } - } - - /* Exact match not found. Go back up looking at each parent, - and return the closest smaller one */ - - if (prev) - JFFS2_DBG_FRAGTREE2("no match. Returning frag %#04x-%#04x, closest previous\n", - prev->ofs, prev->ofs+prev->size); - else - JFFS2_DBG_FRAGTREE2("returning NULL, empty fragtree\n"); - - return prev; -} - -/* Pass 'c' argument to indicate that nodes should be marked obsolete as - they're killed. */ -void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c) -{ - struct jffs2_node_frag *frag; - struct jffs2_node_frag *parent; - - if (!root->rb_node) - return; - - JFFS2_DBG_FRAGTREE("killing\n"); - - frag = (rb_entry(root->rb_node, struct jffs2_node_frag, rb)); - while(frag) { - if (frag->rb.rb_left) { - JFFS2_DBG_FRAGTREE2("going left from frag (%p) %#04x-%#04x\n", - frag, frag->ofs, frag->ofs+frag->size); - frag = frag_left(frag); - continue; - } - if (frag->rb.rb_right) { - JFFS2_DBG_FRAGTREE2("going right from frag (%p) %#04x-%#04x\n", - frag, frag->ofs, frag->ofs+frag->size); - frag = frag_right(frag); - continue; - } - - JFFS2_DBG_FRAGTREE2("frag %#04x-%#04x: node %p, frags %d\n", - frag->ofs, frag->ofs+frag->size, frag->node, frag->node?frag->node->frags:0); - - if (frag->node && !(--frag->node->frags)) { - /* Not a hole, and it's the final remaining frag - of this node. Free the node */ - if (c) - jffs2_mark_node_obsolete(c, frag->node->raw); - - jffs2_free_full_dnode(frag->node); - } - parent = frag_parent(frag); - if (parent) { - if (frag_left(parent) == frag) - parent->rb.rb_left = NULL; - else - parent->rb.rb_right = NULL; - } - - jffs2_free_node_frag(frag); - frag = parent; - - cond_resched(); - } -} diff --git a/components/dfs/filesystems/jffs2/src/nodelist.h b/components/dfs/filesystems/jffs2/src/nodelist.h deleted file mode 100644 index 53cdb49bbf..0000000000 --- a/components/dfs/filesystems/jffs2/src/nodelist.h +++ /dev/null @@ -1,415 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: nodelist.h,v 1.135 2005/07/27 14:46:11 dedekind Exp $ - * - */ - -#ifndef __JFFS2_NODELIST_H__ -#define __JFFS2_NODELIST_H__ - -#include "jffs2_config.h" -#include <linux/config.h> -#include <linux/fs.h> -#include <linux/types.h> -#include <linux/jffs2.h> -#include <linux/jffs2_fs_sb.h> -#include <linux/jffs2_fs_i.h> - -#ifdef __ECOS -#include "os-ecos.h" -#elif defined(RT_THREAD) -#include "os-rtthread.h" -#else -#include <linux/mtd/compatmac.h> /* For compatibility with older kernels */ -#include "os-linux.h" -#endif - -#define JFFS2_NATIVE_ENDIAN - -/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from - whatever OS we're actually running on here too. */ - -#if defined(JFFS2_NATIVE_ENDIAN) -#if defined (__GNUC__) -#define cpu_to_je16(x) ((jint16_t){x}) -#define cpu_to_je32(x) ((jint32_t){x}) -#define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)}) - -#define je16_to_cpu(x) ((x).v16) -#define je32_to_cpu(x) ((x).v32) -#define jemode_to_cpu(x) (jffs2_to_os_mode((x).m)) -#elif defined (MSVC) -#define cpu_to_je16(x) ((jint16_t)(x)) -#define cpu_to_je32(x) ((jint32_t)(x)) -static __inline jmode_t cpu_to_jemode(x) -{ - jmode_t _x; - _x.m = os_to_jffs2_mode(x); - return _x; -} - -#define je16_to_cpu(x) (x) -#define je32_to_cpu(x) (x) -#define jemode_to_cpu(x) (jffs2_to_os_mode((x).m)) -#else -#endif - - -#elif defined(JFFS2_BIG_ENDIAN) -#define cpu_to_je16(x) ((jint16_t){cpu_to_be16(x)}) -#define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)}) -#define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))}) - -#define je16_to_cpu(x) (be16_to_cpu(x.v16)) -#define je32_to_cpu(x) (be32_to_cpu(x.v32)) -#define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m))) -#elif defined(JFFS2_LITTLE_ENDIAN) -#define cpu_to_je16(x) ((jint16_t){cpu_to_le16(x)}) -#define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)}) -#define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))}) - -#define je16_to_cpu(x) (le16_to_cpu(x.v16)) -#define je32_to_cpu(x) (le32_to_cpu(x.v32)) -#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m))) -#else -#error wibble -#endif - -/* - This is all we need to keep in-core for each raw node during normal - operation. As and when we do read_inode on a particular inode, we can - scan the nodes which are listed for it and build up a proper map of - which nodes are currently valid. JFFSv1 always used to keep that whole - map in core for each inode. -*/ -struct jffs2_raw_node_ref -{ - struct jffs2_raw_node_ref *next_in_ino; /* Points to the next raw_node_ref - for this inode. If this is the last, it points to the inode_cache - for this inode instead. The inode_cache will have NULL in the first - word so you know when you've got there :) */ - struct jffs2_raw_node_ref *next_phys; - uint32_t flash_offset; - uint32_t __totlen; /* This may die; use ref_totlen(c, jeb, ) below */ -}; - - /* flash_offset & 3 always has to be zero, because nodes are - always aligned at 4 bytes. So we have a couple of extra bits - to play with, which indicate the node's status; see below: */ -#define REF_UNCHECKED 0 /* We haven't yet checked the CRC or built its inode */ -#define REF_OBSOLETE 1 /* Obsolete, can be completely ignored */ -#define REF_PRISTINE 2 /* Completely clean. GC without looking */ -#define REF_NORMAL 3 /* Possibly overlapped. Read the page and write again on GC */ -#define ref_flags(ref) ((ref)->flash_offset & 3) -#define ref_offset(ref) ((ref)->flash_offset & ~3) -#define ref_obsolete(ref) (((ref)->flash_offset & 3) == REF_OBSOLETE) -#define mark_ref_normal(ref) do { (ref)->flash_offset = ref_offset(ref) | REF_NORMAL; } while(0) - -/* For each inode in the filesystem, we need to keep a record of - nlink, because it would be a PITA to scan the whole directory tree - at read_inode() time to calculate it, and to keep sufficient information - in the raw_node_ref (basically both parent and child inode number for - dirent nodes) would take more space than this does. We also keep - a pointer to the first physical node which is part of this inode, too. -*/ -struct jffs2_inode_cache { - struct jffs2_full_dirent *scan_dents; /* Used during scan to hold - temporary lists of dirents, and later must be set to - NULL to mark the end of the raw_node_ref->next_in_ino - chain. */ - struct jffs2_inode_cache *next; - struct jffs2_raw_node_ref *nodes; - uint32_t ino; - int nlink; - int state; -}; - -/* Inode states for 'state' above. We need the 'GC' state to prevent - someone from doing a read_inode() while we're moving a 'REF_PRISTINE' - node without going through all the iget() nonsense */ -#define INO_STATE_UNCHECKED 0 /* CRC checks not yet done */ -#define INO_STATE_CHECKING 1 /* CRC checks in progress */ -#define INO_STATE_PRESENT 2 /* In core */ -#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */ -#define INO_STATE_GC 4 /* GCing a 'pristine' node */ -#define INO_STATE_READING 5 /* In read_inode() */ -#define INO_STATE_CLEARING 6 /* In clear_inode() */ - -#define INOCACHE_HASHSIZE 128 - -/* - Larger representation of a raw node, kept in-core only when the - struct inode for this particular ino is instantiated. -*/ - -struct jffs2_full_dnode -{ - struct jffs2_raw_node_ref *raw; - uint32_t ofs; /* The offset to which the data of this node belongs */ - uint32_t size; - uint32_t frags; /* Number of fragments which currently refer - to this node. When this reaches zero, - the node is obsolete. */ -}; - -/* - Even larger representation of a raw node, kept in-core only while - we're actually building up the original map of which nodes go where, - in read_inode() -*/ -struct jffs2_tmp_dnode_info -{ - struct rb_node rb; - struct jffs2_full_dnode *fn; - uint32_t version; -}; - -struct jffs2_full_dirent -{ - struct jffs2_raw_node_ref *raw; - struct jffs2_full_dirent *next; - uint32_t version; - uint32_t ino; /* == zero for unlink */ - unsigned int nhash; - unsigned char type; - unsigned char name[0]; -}; - -/* - Fragments - used to build a map of which raw node to obtain - data from for each part of the ino -*/ -struct jffs2_node_frag -{ - struct rb_node rb; - struct jffs2_full_dnode *node; /* NULL for holes */ - uint32_t size; - uint32_t ofs; /* The offset to which this fragment belongs */ -}; - -struct jffs2_eraseblock -{ - struct list_head list; - int bad_count; - uint32_t offset; /* of this block in the MTD */ - - uint32_t unchecked_size; - uint32_t used_size; - uint32_t dirty_size; - uint32_t wasted_size; - uint32_t free_size; /* Note that sector_size - free_size - is the address of the first free space */ - struct jffs2_raw_node_ref *first_node; - struct jffs2_raw_node_ref *last_node; - - struct jffs2_raw_node_ref *gc_node; /* Next node to be garbage collected */ -}; - -/* Calculate totlen from surrounding nodes or eraseblock */ -static inline uint32_t __ref_totlen(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb, - struct jffs2_raw_node_ref *ref) -{ - uint32_t ref_end; - - if (ref->next_phys) - ref_end = ref_offset(ref->next_phys); - else { - if (!jeb) - jeb = &c->blocks[ref->flash_offset / c->sector_size]; - - /* Last node in block. Use free_space */ - BUG_ON(ref != jeb->last_node); - ref_end = jeb->offset + c->sector_size - jeb->free_size; - } - return ref_end - ref_offset(ref); -} - -static inline uint32_t ref_totlen(struct jffs2_sb_info *c, - struct jffs2_eraseblock *jeb, - struct jffs2_raw_node_ref *ref) -{ - uint32_t ret; - -#if CONFIG_JFFS2_FS_DEBUG > 0 - if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) { - printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n", - jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref)); - BUG(); - } -#endif - -#if 1 - ret = ref->__totlen; -#else - /* This doesn't actually work yet */ - ret = __ref_totlen(c, jeb, ref); - if (ret != ref->__totlen) { - printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n", - ref, ref_offset(ref), ref_offset(ref)+ref->__totlen, - ret, ref->__totlen); - if (!jeb) - jeb = &c->blocks[ref->flash_offset / c->sector_size]; - jffs2_dbg_dump_node_refs_nolock(c, jeb); - BUG(); - } -#endif - return ret; -} - -#define ALLOC_NORMAL 0 /* Normal allocation */ -#define ALLOC_DELETION 1 /* Deletion node. Best to allow it */ -#define ALLOC_GC 2 /* Space requested for GC. Give it or die */ -#define ALLOC_NORETRY 3 /* For jffs2_write_dnode: On failure, return -EAGAIN instead of retrying */ - -/* How much dirty space before it goes on the very_dirty_list */ -#define VERYDIRTY(c, size) ((size) >= ((c)->sector_size / 2)) - -/* check if dirty space is more than 255 Byte */ -#define ISDIRTY(size) ((size) > sizeof (struct jffs2_raw_inode) + JFFS2_MIN_DATA_LEN) - -#define PAD(x) (((x)+3)&~3) - -static inline struct jffs2_inode_cache *jffs2_raw_ref_to_ic(struct jffs2_raw_node_ref *raw) -{ - while(raw->next_in_ino) { - raw = raw->next_in_ino; - } - - return ((struct jffs2_inode_cache *)raw); -} - -static inline struct jffs2_node_frag *frag_first(struct rb_root *root) -{ - struct rb_node *node = root->rb_node; - - if (!node) - return NULL; - while(node->rb_left) - node = node->rb_left; - return rb_entry(node, struct jffs2_node_frag, rb); -} - -static inline struct jffs2_node_frag *frag_last(struct rb_root *root) -{ - struct rb_node *node = root->rb_node; - - if (!node) - return NULL; - while(node->rb_right) - node = node->rb_right; - return rb_entry(node, struct jffs2_node_frag, rb); -} - -#define rb_parent(rb) ((rb)->rb_parent) -#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb) -#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb) -#define frag_parent(frag) rb_entry(rb_parent(&(frag)->rb), struct jffs2_node_frag, rb) -#define frag_left(frag) rb_entry((frag)->rb.rb_left, struct jffs2_node_frag, rb) -#define frag_right(frag) rb_entry((frag)->rb.rb_right, struct jffs2_node_frag, rb) -#define frag_erase(frag, list) rb_erase(&frag->rb, list); - -/* nodelist.c */ -void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list); -void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state); -struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t ino); -void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new); -void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old); -void jffs2_free_ino_caches(struct jffs2_sb_info *c); -void jffs2_free_raw_node_refs(struct jffs2_sb_info *c); -struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset); -void jffs2_kill_fragtree(struct rb_root *root, struct jffs2_sb_info *c_delete); -struct rb_node *rb_next(struct rb_node *); -struct rb_node *rb_prev(struct rb_node *); -void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root); -void jffs2_obsolete_node_frag(struct jffs2_sb_info *c, struct jffs2_node_frag *this); -int jffs2_add_full_dnode_to_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_full_dnode *fn); - -/* nodemgmt.c */ -int jffs2_thread_should_wake(struct jffs2_sb_info *c); -int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio); -int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len); -int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new); -void jffs2_complete_reservation(struct jffs2_sb_info *c); -void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *raw); - -/* write.c */ -int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri); - -struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode); -struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode); -int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - struct jffs2_raw_inode *ri, unsigned char *buf, - uint32_t offset, uint32_t writelen, uint32_t *retlen); -int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen); -int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f); -int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen); - - -/* readinode.c */ -void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size); -int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - uint32_t ino, struct jffs2_raw_inode *latest_node); -int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); -void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f); - -/* malloc.c */ -int jffs2_create_slab_caches(void); -void jffs2_destroy_slab_caches(void); - -struct jffs2_full_dirent *jffs2_alloc_full_dirent(int namesize); -void jffs2_free_full_dirent(struct jffs2_full_dirent *); -struct jffs2_full_dnode *jffs2_alloc_full_dnode(void); -void jffs2_free_full_dnode(struct jffs2_full_dnode *); -struct jffs2_raw_dirent *jffs2_alloc_raw_dirent(void); -void jffs2_free_raw_dirent(struct jffs2_raw_dirent *); -struct jffs2_raw_inode *jffs2_alloc_raw_inode(void); -void jffs2_free_raw_inode(struct jffs2_raw_inode *); -struct jffs2_tmp_dnode_info *jffs2_alloc_tmp_dnode_info(void); -void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *); -struct jffs2_raw_node_ref *jffs2_alloc_raw_node_ref(void); -void jffs2_free_raw_node_ref(struct jffs2_raw_node_ref *); -struct jffs2_node_frag *jffs2_alloc_node_frag(void); -void jffs2_free_node_frag(struct jffs2_node_frag *); -struct jffs2_inode_cache *jffs2_alloc_inode_cache(void); -void jffs2_free_inode_cache(struct jffs2_inode_cache *); - -/* gc.c */ -int jffs2_garbage_collect_pass(struct jffs2_sb_info *c); - -/* read.c */ -int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - struct jffs2_full_dnode *fd, unsigned char *buf, - int ofs, int len); -int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - unsigned char *buf, uint32_t offset, uint32_t len); -char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f); - -/* scan.c */ -int jffs2_scan_medium(struct jffs2_sb_info *c); -void jffs2_rotate_lists(struct jffs2_sb_info *c); - -/* build.c */ -int jffs2_do_mount_fs(struct jffs2_sb_info *c); - -/* erase.c */ -void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count); - -#ifdef CONFIG_JFFS2_FS_WRITEBUFFER -/* wbuf.c */ -int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino); -int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c); -int jffs2_check_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); -int jffs2_write_nand_cleanmarker(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); -#endif - -#include "debug.h" - -#endif /* __JFFS2_NODELIST_H__ */ diff --git a/components/dfs/filesystems/jffs2/src/nodemgmt.c b/components/dfs/filesystems/jffs2/src/nodemgmt.c deleted file mode 100644 index ef2167aadc..0000000000 --- a/components/dfs/filesystems/jffs2/src/nodemgmt.c +++ /dev/null @@ -1,680 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: nodemgmt.c,v 1.124 2005/07/20 15:32:28 dedekind Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/mtd/mtd.h> -#include <linux/compiler.h> -#include <linux/sched.h> /* For cond_resched() */ -#include "nodelist.h" - -/** - * jffs2_reserve_space - request physical space to write nodes to flash - * @c: superblock info - * @minsize: Minimum acceptable size of allocation - * @ofs: Returned value of node offset - * @len: Returned value of allocation length - * @prio: Allocation type - ALLOC_{NORMAL,DELETION} - * - * Requests a block of physical space on the flash. Returns zero for success - * and puts 'ofs' and 'len' into the appriopriate place, or returns -ENOSPC - * or other error if appropriate. - * - * If it returns zero, jffs2_reserve_space() also downs the per-filesystem - * allocation semaphore, to prevent more than one allocation from being - * active at any time. The semaphore is later released by jffs2_commit_allocation() - * - * jffs2_reserve_space() may trigger garbage collection in order to make room - * for the requested allocation. - */ - -static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len); - -int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio) -{ - int ret = -EAGAIN; - int blocksneeded = c->resv_blocks_write; - /* align it */ - minsize = PAD(minsize); - - D1(printk(KERN_DEBUG "jffs2_reserve_space(): Requested 0x%x bytes\n", minsize)); - down(&c->alloc_sem); - - D1(printk(KERN_DEBUG "jffs2_reserve_space(): alloc sem got\n")); - - spin_lock(&c->erase_completion_lock); - - /* this needs a little more thought (true <tglx> :)) */ - while(ret == -EAGAIN) { - while(c->nr_free_blocks + c->nr_erasing_blocks < blocksneeded) { - int ret; - uint32_t dirty, avail; - - /* calculate real dirty size - * dirty_size contains blocks on erase_pending_list - * those blocks are counted in c->nr_erasing_blocks. - * If one block is actually erased, it is not longer counted as dirty_space - * but it is counted in c->nr_erasing_blocks, so we add it and subtract it - * with c->nr_erasing_blocks * c->sector_size again. - * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks - * This helps us to force gc and pick eventually a clean block to spread the load. - * We add unchecked_size here, as we hopefully will find some space to use. - * This will affect the sum only once, as gc first finishes checking - * of nodes. - */ - dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size; - if (dirty < c->nospc_dirty_size) { - if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { - D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n")); - break; - } - D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n", - dirty, c->unchecked_size, c->sector_size)); - - spin_unlock(&c->erase_completion_lock); - up(&c->alloc_sem); - return -ENOSPC; - } - - /* Calc possibly available space. Possibly available means that we - * don't know, if unchecked size contains obsoleted nodes, which could give us some - * more usable space. This will affect the sum only once, as gc first finishes checking - * of nodes. - + Return -ENOSPC, if the maximum possibly available space is less or equal than - * blocksneeded * sector_size. - * This blocks endless gc looping on a filesystem, which is nearly full, even if - * the check above passes. - */ - avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size; - if ( (avail / c->sector_size) <= blocksneeded) { - if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { - D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n")); - break; - } - - D1(printk(KERN_DEBUG "max. available size 0x%08x < blocksneeded * sector_size 0x%08x, returning -ENOSPC\n", - avail, blocksneeded * c->sector_size)); - spin_unlock(&c->erase_completion_lock); - up(&c->alloc_sem); - return -ENOSPC; - } - - up(&c->alloc_sem); - - D1(printk(KERN_DEBUG "Triggering GC pass. nr_free_blocks %d, nr_erasing_blocks %d, free_size 0x%08x, dirty_size 0x%08x, wasted_size 0x%08x, used_size 0x%08x, erasing_size 0x%08x, bad_size 0x%08x (total 0x%08x of 0x%08x)\n", - c->nr_free_blocks, c->nr_erasing_blocks, c->free_size, c->dirty_size, c->wasted_size, c->used_size, c->erasing_size, c->bad_size, - c->free_size + c->dirty_size + c->wasted_size + c->used_size + c->erasing_size + c->bad_size, c->flash_size)); - spin_unlock(&c->erase_completion_lock); - - ret = jffs2_garbage_collect_pass(c); - if (ret) - return ret; - - cond_resched(); - - if (signal_pending(current)) - return -EINTR; - - down(&c->alloc_sem); - spin_lock(&c->erase_completion_lock); - } - - ret = jffs2_do_reserve_space(c, minsize, ofs, len); - if (ret) { - D1(printk(KERN_DEBUG "jffs2_reserve_space: ret is %d\n", ret)); - } - } - spin_unlock(&c->erase_completion_lock); - if (ret) - up(&c->alloc_sem); - return ret; -} - -int jffs2_reserve_space_gc(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len) -{ - int ret = -EAGAIN; - minsize = PAD(minsize); - - D1(printk(KERN_DEBUG "jffs2_reserve_space_gc(): Requested 0x%x bytes\n", minsize)); - - spin_lock(&c->erase_completion_lock); - while(ret == -EAGAIN) { - ret = jffs2_do_reserve_space(c, minsize, ofs, len); - if (ret) { - D1(printk(KERN_DEBUG "jffs2_reserve_space_gc: looping, ret is %d\n", ret)); - } - } - spin_unlock(&c->erase_completion_lock); - return ret; -} - -/* Called with alloc sem _and_ erase_completion_lock */ -static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len) -{ - struct jffs2_eraseblock *jeb = c->nextblock; - - restart: - if (jeb && minsize > jeb->free_size) { - /* Skip the end of this block and file it as having some dirty space */ - /* If there's a pending write to it, flush now */ - if (jffs2_wbuf_dirty(c)) { - spin_unlock(&c->erase_completion_lock); - D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n")); - jffs2_flush_wbuf_pad(c); - spin_lock(&c->erase_completion_lock); - jeb = c->nextblock; - goto restart; - } - c->wasted_size += jeb->free_size; - c->free_size -= jeb->free_size; - jeb->wasted_size += jeb->free_size; - jeb->free_size = 0; - - /* Check, if we have a dirty block now, or if it was dirty already */ - if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) { - c->dirty_size += jeb->wasted_size; - c->wasted_size -= jeb->wasted_size; - jeb->dirty_size += jeb->wasted_size; - jeb->wasted_size = 0; - if (VERYDIRTY(c, jeb->dirty_size)) { - D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); - list_add_tail(&jeb->list, &c->very_dirty_list); - } else { - D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); - list_add_tail(&jeb->list, &c->dirty_list); - } - } else { - D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); - list_add_tail(&jeb->list, &c->clean_list); - } - c->nextblock = jeb = NULL; - } - - if (!jeb) { - struct list_head *next; - /* Take the next block off the 'free' list */ - - if (list_empty(&c->free_list)) { - - if (!c->nr_erasing_blocks && - !list_empty(&c->erasable_list)) { - struct jffs2_eraseblock *ejeb; - - ejeb = list_entry(c->erasable_list.next, struct jffs2_eraseblock, list); - list_del(&ejeb->list); - list_add_tail(&ejeb->list, &c->erase_pending_list); - c->nr_erasing_blocks++; - jffs2_erase_pending_trigger(c); - D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Triggering erase of erasable block at 0x%08x\n", - ejeb->offset)); - } - - if (!c->nr_erasing_blocks && - !list_empty(&c->erasable_pending_wbuf_list)) { - D1(printk(KERN_DEBUG "jffs2_do_reserve_space: Flushing write buffer\n")); - /* c->nextblock is NULL, no update to c->nextblock allowed */ - spin_unlock(&c->erase_completion_lock); - jffs2_flush_wbuf_pad(c); - spin_lock(&c->erase_completion_lock); - /* Have another go. It'll be on the erasable_list now */ - return -EAGAIN; - } - - if (!c->nr_erasing_blocks) { - /* Ouch. We're in GC, or we wouldn't have got here. - And there's no space left. At all. */ - printk(KERN_CRIT "Argh. No free space left for GC. nr_erasing_blocks is %d. nr_free_blocks is %d. (erasableempty: %s, erasingempty: %s, erasependingempty: %s)\n", - c->nr_erasing_blocks, c->nr_free_blocks, list_empty(&c->erasable_list)?"yes":"no", - list_empty(&c->erasing_list)?"yes":"no", list_empty(&c->erase_pending_list)?"yes":"no"); - return -ENOSPC; - } - - spin_unlock(&c->erase_completion_lock); - /* Don't wait for it; just erase one right now */ - jffs2_erase_pending_blocks(c, 1); - spin_lock(&c->erase_completion_lock); - - /* An erase may have failed, decreasing the - amount of free space available. So we must - restart from the beginning */ - return -EAGAIN; - } - - next = c->free_list.next; - list_del(next); - c->nextblock = jeb = list_entry(next, struct jffs2_eraseblock, list); - c->nr_free_blocks--; - - if (jeb->free_size != c->sector_size - c->cleanmarker_size) { - printk(KERN_WARNING "Eep. Block 0x%08x taken from free_list had free_size of 0x%08x!!\n", jeb->offset, jeb->free_size); - goto restart; - } - } - /* OK, jeb (==c->nextblock) is now pointing at a block which definitely has - enough space */ - *ofs = jeb->offset + (c->sector_size - jeb->free_size); - *len = jeb->free_size; - - if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size && - !jeb->first_node->next_in_ino) { - /* Only node in it beforehand was a CLEANMARKER node (we think). - So mark it obsolete now that there's going to be another node - in the block. This will reduce used_size to zero but We've - already set c->nextblock so that jffs2_mark_node_obsolete() - won't try to refile it to the dirty_list. - */ - spin_unlock(&c->erase_completion_lock); - jffs2_mark_node_obsolete(c, jeb->first_node); - spin_lock(&c->erase_completion_lock); - } - - D1(printk(KERN_DEBUG "jffs2_do_reserve_space(): Giving 0x%x bytes at 0x%x\n", *len, *ofs)); - return 0; -} - -/** - * jffs2_add_physical_node_ref - add a physical node reference to the list - * @c: superblock info - * @new: new node reference to add - * @len: length of this physical node - * @dirty: dirty flag for new node - * - * Should only be used to report nodes for which space has been allocated - * by jffs2_reserve_space. - * - * Must be called with the alloc_sem held. - */ - -int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *new) -{ - struct jffs2_eraseblock *jeb; - uint32_t len; - - jeb = &c->blocks[new->flash_offset / c->sector_size]; - len = ref_totlen(c, jeb, new); - - D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len)); -#if 1 - /* we could get some obsolete nodes after nextblock was refiled - in wbuf.c */ - if ((c->nextblock || !ref_obsolete(new)) - &&(jeb != c->nextblock || ref_offset(new) != jeb->offset + (c->sector_size - jeb->free_size))) { - printk(KERN_WARNING "argh. node added in wrong place\n"); - jffs2_free_raw_node_ref(new); - return -EINVAL; - } -#endif - spin_lock(&c->erase_completion_lock); - - if (!jeb->first_node) - jeb->first_node = new; - if (jeb->last_node) - jeb->last_node->next_phys = new; - jeb->last_node = new; - - jeb->free_size -= len; - c->free_size -= len; - if (ref_obsolete(new)) { - jeb->dirty_size += len; - c->dirty_size += len; - } else { - jeb->used_size += len; - c->used_size += len; - } - - if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) { - /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ - D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", - jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); - if (jffs2_wbuf_dirty(c)) { - /* Flush the last write in the block if it's outstanding */ - spin_unlock(&c->erase_completion_lock); - jffs2_flush_wbuf_pad(c); - spin_lock(&c->erase_completion_lock); - } - - list_add_tail(&jeb->list, &c->clean_list); - c->nextblock = NULL; - } - jffs2_dbg_acct_sanity_check_nolock(c,jeb); - jffs2_dbg_acct_paranoia_check_nolock(c, jeb); - - spin_unlock(&c->erase_completion_lock); - - return 0; -} - - -void jffs2_complete_reservation(struct jffs2_sb_info *c) -{ - D1(printk(KERN_DEBUG "jffs2_complete_reservation()\n")); - jffs2_garbage_collect_trigger(c); - up(&c->alloc_sem); -} - -static inline int on_list(struct list_head *obj, struct list_head *head) -{ - struct list_head *this; - - list_for_each(this, head) { - if (this == obj) { - D1(printk("%p is on list at %p\n", obj, head)); - return 1; - - } - } - return 0; -} - -void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref) -{ - struct jffs2_eraseblock *jeb; - int blocknr; - struct jffs2_unknown_node n; - int ret, addedsize; - size_t retlen; - - if(!ref) { - printk(KERN_NOTICE "EEEEEK. jffs2_mark_node_obsolete called with NULL node\n"); - return; - } - if (ref_obsolete(ref)) { - D1(printk(KERN_DEBUG "jffs2_mark_node_obsolete called with already obsolete node at 0x%08x\n", ref_offset(ref))); - return; - } - blocknr = ref->flash_offset / c->sector_size; - if (blocknr >= c->nr_blocks) { - printk(KERN_NOTICE "raw node at 0x%08x is off the end of device!\n", ref->flash_offset); - BUG(); - } - jeb = &c->blocks[blocknr]; - - if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) && - !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) { - /* Hm. This may confuse static lock analysis. If any of the above - three conditions is false, we're going to return from this - function without actually obliterating any nodes or freeing - any jffs2_raw_node_refs. So we don't need to stop erases from - happening, or protect against people holding an obsolete - jffs2_raw_node_ref without the erase_completion_lock. */ - down(&c->erase_free_sem); - } - - spin_lock(&c->erase_completion_lock); - - if (ref_flags(ref) == REF_UNCHECKED) { - D1(if (unlikely(jeb->unchecked_size < ref_totlen(c, jeb, ref))) { - printk(KERN_NOTICE "raw unchecked node of size 0x%08x freed from erase block %d at 0x%08x, but unchecked_size was already 0x%08x\n", - ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); - BUG(); - }) - D1(printk(KERN_DEBUG "Obsoleting previously unchecked node at 0x%08x of len %x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); - jeb->unchecked_size -= ref_totlen(c, jeb, ref); - c->unchecked_size -= ref_totlen(c, jeb, ref); - } else { - D1(if (unlikely(jeb->used_size < ref_totlen(c, jeb, ref))) { - printk(KERN_NOTICE "raw node of size 0x%08x freed from erase block %d at 0x%08x, but used_size was already 0x%08x\n", - ref_totlen(c, jeb, ref), blocknr, ref->flash_offset, jeb->used_size); - BUG(); - }) - D1(printk(KERN_DEBUG "Obsoleting node at 0x%08x of len %#x: ", ref_offset(ref), ref_totlen(c, jeb, ref))); - jeb->used_size -= ref_totlen(c, jeb, ref); - c->used_size -= ref_totlen(c, jeb, ref); - } - - // Take care, that wasted size is taken into concern - if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) { - D1(printk(KERN_DEBUG "Dirtying\n")); - addedsize = ref_totlen(c, jeb, ref); - jeb->dirty_size += ref_totlen(c, jeb, ref); - c->dirty_size += ref_totlen(c, jeb, ref); - - /* Convert wasted space to dirty, if not a bad block */ - if (jeb->wasted_size) { - if (on_list(&jeb->list, &c->bad_used_list)) { - D1(printk(KERN_DEBUG "Leaving block at %08x on the bad_used_list\n", - jeb->offset)); - addedsize = 0; /* To fool the refiling code later */ - } else { - D1(printk(KERN_DEBUG "Converting %d bytes of wasted space to dirty in block at %08x\n", - jeb->wasted_size, jeb->offset)); - addedsize += jeb->wasted_size; - jeb->dirty_size += jeb->wasted_size; - c->dirty_size += jeb->wasted_size; - c->wasted_size -= jeb->wasted_size; - jeb->wasted_size = 0; - } - } - } else { - D1(printk(KERN_DEBUG "Wasting\n")); - addedsize = 0; - jeb->wasted_size += ref_totlen(c, jeb, ref); - c->wasted_size += ref_totlen(c, jeb, ref); - } - ref->flash_offset = ref_offset(ref) | REF_OBSOLETE; - - jffs2_dbg_acct_sanity_check_nolock(c, jeb); - jffs2_dbg_acct_paranoia_check_nolock(c, jeb); - - if (c->flags & JFFS2_SB_FLAG_SCANNING) { - /* Flash scanning is in progress. Don't muck about with the block - lists because they're not ready yet, and don't actually - obliterate nodes that look obsolete. If they weren't - marked obsolete on the flash at the time they _became_ - obsolete, there was probably a reason for that. */ - spin_unlock(&c->erase_completion_lock); - /* We didn't lock the erase_free_sem */ - return; - } - - if (jeb == c->nextblock) { - D2(printk(KERN_DEBUG "Not moving nextblock 0x%08x to dirty/erase_pending list\n", jeb->offset)); - } else if (!jeb->used_size && !jeb->unchecked_size) { - if (jeb == c->gcblock) { - D1(printk(KERN_DEBUG "gcblock at 0x%08x completely dirtied. Clearing gcblock...\n", jeb->offset)); - c->gcblock = NULL; - } else { - D1(printk(KERN_DEBUG "Eraseblock at 0x%08x completely dirtied. Removing from (dirty?) list...\n", jeb->offset)); - list_del(&jeb->list); - } - if (jffs2_wbuf_dirty(c)) { - D1(printk(KERN_DEBUG "...and adding to erasable_pending_wbuf_list\n")); - list_add_tail(&jeb->list, &c->erasable_pending_wbuf_list); - } else { - if (jiffies & 127) { - /* Most of the time, we just erase it immediately. Otherwise we - spend ages scanning it on mount, etc. */ - D1(printk(KERN_DEBUG "...and adding to erase_pending_list\n")); - list_add_tail(&jeb->list, &c->erase_pending_list); - c->nr_erasing_blocks++; - jffs2_erase_pending_trigger(c); - } else { - /* Sometimes, however, we leave it elsewhere so it doesn't get - immediately reused, and we spread the load a bit. */ - D1(printk(KERN_DEBUG "...and adding to erasable_list\n")); - list_add_tail(&jeb->list, &c->erasable_list); - } - } - D1(printk(KERN_DEBUG "Done OK\n")); - } else if (jeb == c->gcblock) { - D2(printk(KERN_DEBUG "Not moving gcblock 0x%08x to dirty_list\n", jeb->offset)); - } else if (ISDIRTY(jeb->dirty_size) && !ISDIRTY(jeb->dirty_size - addedsize)) { - D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is freshly dirtied. Removing from clean list...\n", jeb->offset)); - list_del(&jeb->list); - D1(printk(KERN_DEBUG "...and adding to dirty_list\n")); - list_add_tail(&jeb->list, &c->dirty_list); - } else if (VERYDIRTY(c, jeb->dirty_size) && - !VERYDIRTY(c, jeb->dirty_size - addedsize)) { - D1(printk(KERN_DEBUG "Eraseblock at 0x%08x is now very dirty. Removing from dirty list...\n", jeb->offset)); - list_del(&jeb->list); - D1(printk(KERN_DEBUG "...and adding to very_dirty_list\n")); - list_add_tail(&jeb->list, &c->very_dirty_list); - } else { - D1(printk(KERN_DEBUG "Eraseblock at 0x%08x not moved anywhere. (free 0x%08x, dirty 0x%08x, used 0x%08x)\n", - jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); - } - - spin_unlock(&c->erase_completion_lock); - - if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c) || - (c->flags & JFFS2_SB_FLAG_BUILDING)) { - /* We didn't lock the erase_free_sem */ - return; - } - - /* The erase_free_sem is locked, and has been since before we marked the node obsolete - and potentially put its eraseblock onto the erase_pending_list. Thus, we know that - the block hasn't _already_ been erased, and that 'ref' itself hasn't been freed yet - by jffs2_free_all_node_refs() in erase.c. Which is nice. */ - - D1(printk(KERN_DEBUG "obliterating obsoleted node at 0x%08x\n", ref_offset(ref))); - ret = jffs2_flash_read(c, ref_offset(ref), sizeof(n), &retlen, (unsigned char *)&n); - if (ret) { - printk(KERN_WARNING "Read error reading from obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret); - goto out_erase_sem; - } - if (retlen != sizeof(n)) { - printk(KERN_WARNING "Short read from obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); - goto out_erase_sem; - } - if (PAD(je32_to_cpu(n.totlen)) != PAD(ref_totlen(c, jeb, ref))) { - printk(KERN_WARNING "Node totlen on flash (0x%08x) != totlen from node ref (0x%08x)\n", je32_to_cpu(n.totlen), ref_totlen(c, jeb, ref)); - goto out_erase_sem; - } - if (!(je16_to_cpu(n.nodetype) & JFFS2_NODE_ACCURATE)) { - D1(printk(KERN_DEBUG "Node at 0x%08x was already marked obsolete (nodetype 0x%04x)\n", ref_offset(ref), je16_to_cpu(n.nodetype))); - goto out_erase_sem; - } - /* XXX FIXME: This is ugly now */ - n.nodetype = cpu_to_je16(je16_to_cpu(n.nodetype) & ~JFFS2_NODE_ACCURATE); - ret = jffs2_flash_write(c, ref_offset(ref), sizeof(n), &retlen, (unsigned char *)&n); - if (ret) { - printk(KERN_WARNING "Write error in obliterating obsoleted node at 0x%08x: %d\n", ref_offset(ref), ret); - goto out_erase_sem; - } - if (retlen != sizeof(n)) { - printk(KERN_WARNING "Short write in obliterating obsoleted node at 0x%08x: %zd\n", ref_offset(ref), retlen); - goto out_erase_sem; - } - - /* Nodes which have been marked obsolete no longer need to be - associated with any inode. Remove them from the per-inode list. - - Note we can't do this for NAND at the moment because we need - obsolete dirent nodes to stay on the lists, because of the - horridness in jffs2_garbage_collect_deletion_dirent(). Also - because we delete the inocache, and on NAND we need that to - stay around until all the nodes are actually erased, in order - to stop us from giving the same inode number to another newly - created inode. */ - if (ref->next_in_ino) { - struct jffs2_inode_cache *ic; - struct jffs2_raw_node_ref **p; - - spin_lock(&c->erase_completion_lock); - - ic = jffs2_raw_ref_to_ic(ref); - for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino)) - ; - - *p = ref->next_in_ino; - ref->next_in_ino = NULL; - - if (ic->nodes == (void *)ic && ic->nlink == 0) - jffs2_del_ino_cache(c, ic); - - spin_unlock(&c->erase_completion_lock); - } - - - /* Merge with the next node in the physical list, if there is one - and if it's also obsolete and if it doesn't belong to any inode */ - if (ref->next_phys && ref_obsolete(ref->next_phys) && - !ref->next_phys->next_in_ino) { - struct jffs2_raw_node_ref *n = ref->next_phys; - - spin_lock(&c->erase_completion_lock); - - ref->__totlen += n->__totlen; - ref->next_phys = n->next_phys; - if (jeb->last_node == n) jeb->last_node = ref; - if (jeb->gc_node == n) { - /* gc will be happy continuing gc on this node */ - jeb->gc_node=ref; - } - spin_unlock(&c->erase_completion_lock); - - jffs2_free_raw_node_ref(n); - } - - /* Also merge with the previous node in the list, if there is one - and that one is obsolete */ - if (ref != jeb->first_node ) { - struct jffs2_raw_node_ref *p = jeb->first_node; - - spin_lock(&c->erase_completion_lock); - - while (p->next_phys != ref) - p = p->next_phys; - - if (ref_obsolete(p) && !ref->next_in_ino) { - p->__totlen += ref->__totlen; - if (jeb->last_node == ref) { - jeb->last_node = p; - } - if (jeb->gc_node == ref) { - /* gc will be happy continuing gc on this node */ - jeb->gc_node=p; - } - p->next_phys = ref->next_phys; - jffs2_free_raw_node_ref(ref); - } - spin_unlock(&c->erase_completion_lock); - } - out_erase_sem: - up(&c->erase_free_sem); -} - -int jffs2_thread_should_wake(struct jffs2_sb_info *c) -{ - int ret = 0; - uint32_t dirty; - - if (c->unchecked_size) { - D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): unchecked_size %d, checked_ino #%d\n", - c->unchecked_size, c->checked_ino)); - return 1; - } - - /* dirty_size contains blocks on erase_pending_list - * those blocks are counted in c->nr_erasing_blocks. - * If one block is actually erased, it is not longer counted as dirty_space - * but it is counted in c->nr_erasing_blocks, so we add it and subtract it - * with c->nr_erasing_blocks * c->sector_size again. - * Blocks on erasable_list are counted as dirty_size, but not in c->nr_erasing_blocks - * This helps us to force gc and pick eventually a clean block to spread the load. - */ - dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size; - - if (c->nr_free_blocks + c->nr_erasing_blocks < c->resv_blocks_gctrigger && - (dirty > c->nospc_dirty_size)) - ret = 1; - - D1(printk(KERN_DEBUG "jffs2_thread_should_wake(): nr_free_blocks %d, nr_erasing_blocks %d, dirty_size 0x%x: %s\n", - c->nr_free_blocks, c->nr_erasing_blocks, c->dirty_size, ret?"yes":"no")); - - return ret; -} diff --git a/components/dfs/filesystems/jffs2/src/os-ecos.h b/components/dfs/filesystems/jffs2/src/os-ecos.h deleted file mode 100644 index b6d2a0e8c8..0000000000 --- a/components/dfs/filesystems/jffs2/src/os-ecos.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2002-2003 Free Software Foundation, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * 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_ECOS_H__ -#define __JFFS2_OS_ECOS_H__ -#include "jffs2_config.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 "port/sys/stat.h"//#include <sys/types.h> -//#include <fcntl.h> -//#include <sys/stat.h> -//#include <errno.h> //fixme - -//#include <dirent.h> - -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[JFFS2_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 jffs2_get_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 */ -int 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); -int 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); -int 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__ */ diff --git a/components/dfs/filesystems/jffs2/src/os-rtthread.h b/components/dfs/filesystems/jffs2/src/os-rtthread.h deleted file mode 100644 index 95496c2e73..0000000000 --- a/components/dfs/filesystems/jffs2/src/os-rtthread.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2002-2003 Free Software Foundation, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * 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 "jffs2_config.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 <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 jffs2_get_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 */ -int 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); -int 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); -int 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__ */ diff --git a/components/dfs/filesystems/jffs2/src/pushpull.h b/components/dfs/filesystems/jffs2/src/pushpull.h deleted file mode 100644 index 4e84ee38a8..0000000000 --- a/components/dfs/filesystems/jffs2/src/pushpull.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001, 2002 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: pushpull.h,v 1.10 2004/11/16 20:36:11 dwmw2 Exp $ - * - */ - -#ifndef __PUSHPULL_H__ -#define __PUSHPULL_H__ - -#include <linux/errno.h> - -struct pushpull { - unsigned char *buf; - unsigned int buflen; - unsigned int ofs; - unsigned int reserve; -}; - - -static inline void init_pushpull(struct pushpull *pp, char *buf, unsigned buflen, unsigned ofs, unsigned reserve) -{ - pp->buf = (unsigned char *)buf; - pp->buflen = buflen; - pp->ofs = ofs; - pp->reserve = reserve; -} - -static inline int pushbit(struct pushpull *pp, int bit, int use_reserved) -{ - if (pp->ofs >= pp->buflen - (use_reserved?0:pp->reserve)) { - return -ENOSPC; - } - - if (bit) { - pp->buf[pp->ofs >> 3] |= (1<<(7-(pp->ofs &7))); - } - else { - pp->buf[pp->ofs >> 3] &= ~(1<<(7-(pp->ofs &7))); - } - pp->ofs++; - - return 0; -} - -static inline int pushedbits(struct pushpull *pp) -{ - return pp->ofs; -} - -static inline int pullbit(struct pushpull *pp) -{ - int bit; - - bit = (pp->buf[pp->ofs >> 3] >> (7-(pp->ofs & 7))) & 1; - - pp->ofs++; - return bit; -} - -static inline int pulledbits(struct pushpull *pp) -{ - return pp->ofs; -} - -#endif /* __PUSHPULL_H__ */ diff --git a/components/dfs/filesystems/jffs2/src/read.c b/components/dfs/filesystems/jffs2/src/read.c deleted file mode 100644 index a70edd9bc0..0000000000 --- a/components/dfs/filesystems/jffs2/src/read.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: read.c,v 1.41 2005/07/22 10:32:08 dedekind Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/crc32.h> -#include <linux/pagemap.h> -#include <linux/mtd/mtd.h> -#include <linux/compiler.h> -#include "nodelist.h" -#include "compr.h" - -int jffs2_read_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - struct jffs2_full_dnode *fd, unsigned char *buf, - int ofs, int len) -{ - struct jffs2_raw_inode *ri; - size_t readlen; - uint32_t crc; - unsigned char *decomprbuf = NULL; - unsigned char *readbuf = NULL; - int ret = 0,i=0; - - ri = jffs2_alloc_raw_inode(); - if (!ri) - return -ENOMEM; - - ret = jffs2_flash_read(c, ref_offset(fd->raw), sizeof(*ri), &readlen, (unsigned char *)ri); - if (ret) { - jffs2_free_raw_inode(ri); - printk(KERN_WARNING "Error reading node from 0x%08x: %d\n", ref_offset(fd->raw), ret); - return ret; - } - if (readlen != sizeof(*ri)) { - jffs2_free_raw_inode(ri); - printk(KERN_WARNING "Short read from 0x%08x: wanted 0x%zx bytes, got 0x%zx\n", - ref_offset(fd->raw), sizeof(*ri), readlen); - return -EIO; - } - crc = crc32(0, ri, sizeof(*ri)-8); - - D1(printk(KERN_DEBUG "Node read from %08x: node_crc %08x, calculated CRC %08x. dsize %x, csize %x, offset %x, buf %p\n", - ref_offset(fd->raw), je32_to_cpu(ri->node_crc), - crc, je32_to_cpu(ri->dsize), je32_to_cpu(ri->csize), - je32_to_cpu(ri->offset), buf)); - if (crc != je32_to_cpu(ri->node_crc)) { - printk(KERN_WARNING "Node CRC %08x != calculated CRC %08x for node at %08x\n", - je32_to_cpu(ri->node_crc), crc, ref_offset(fd->raw)); - ret = -EIO; - goto out_ri; - } - /* There was a bug where we wrote hole nodes out with csize/dsize - swapped. Deal with it */ - if (ri->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(ri->dsize) && - je32_to_cpu(ri->csize)) { - ri->dsize = ri->csize; - ri->csize = cpu_to_je32(0); - } - - D1(if(ofs + len > je32_to_cpu(ri->dsize)) { - printk(KERN_WARNING "jffs2_read_dnode() asked for %d bytes at %d from %d-byte node\n", - len, ofs, je32_to_cpu(ri->dsize)); - ret = -EINVAL; - goto out_ri; - }); - - - if (ri->compr == JFFS2_COMPR_ZERO) { - memset(buf, 0, len); - goto out_ri; - } - - /* Cases: - Reading whole node and it's uncompressed - read directly to buffer provided, check CRC. - Reading whole node and it's compressed - read into comprbuf, check CRC and decompress to buffer provided - Reading partial node and it's uncompressed - read into readbuf, check CRC, and copy - Reading partial node and it's compressed - read into readbuf, check checksum, decompress to decomprbuf and copy - */ - if (ri->compr == JFFS2_COMPR_NONE && len == je32_to_cpu(ri->dsize)) { - readbuf = buf; - } else { - readbuf = kmalloc(je32_to_cpu(ri->csize), GFP_KERNEL); - if (!readbuf) { - ret = -ENOMEM; - goto out_ri; - } - } - if (ri->compr != JFFS2_COMPR_NONE) { - if (len < je32_to_cpu(ri->dsize)) { - decomprbuf = kmalloc(je32_to_cpu(ri->dsize), GFP_KERNEL); - if (!decomprbuf) { - ret = -ENOMEM; - goto out_readbuf; - } - } else { - decomprbuf = buf; - } - } else { - decomprbuf = readbuf; - } - - D2(printk(KERN_DEBUG "Read %d bytes to %p\n", je32_to_cpu(ri->csize), - readbuf)); - ret = jffs2_flash_read(c, (ref_offset(fd->raw)) + sizeof(*ri), - je32_to_cpu(ri->csize), &readlen, readbuf); - - if (!ret && readlen != je32_to_cpu(ri->csize)) - ret = -EIO; - if (ret) - goto out_decomprbuf; - - crc = crc32(0, readbuf, je32_to_cpu(ri->csize)); - if (crc != je32_to_cpu(ri->data_crc)) { - printk(KERN_WARNING "Data CRC %08x != calculated CRC %08x for node at %08x\n", - je32_to_cpu(ri->data_crc), crc, ref_offset(fd->raw)); - ret = -EIO; - goto out_decomprbuf; - } - D2(printk(KERN_DEBUG "Data CRC matches calculated CRC %08x\n", crc)); - if (ri->compr != JFFS2_COMPR_NONE) { - D2(printk(KERN_DEBUG "Decompress %d bytes from %p to %d bytes at %p\n", - je32_to_cpu(ri->csize), readbuf, je32_to_cpu(ri->dsize), decomprbuf)); - //add for debug -// for (i=0; i<je32_to_cpu(ri->csize); i++) -// { -// printf("%02x ", readbuf[i]); -// if( (i+1) % 16 == 0) -// printf("\n"); -// } - //end debug - ret = jffs2_decompress(c, f, ri->compr | (ri->usercompr << 8), readbuf, decomprbuf, je32_to_cpu(ri->csize), je32_to_cpu(ri->dsize)); - if (ret) { - printk(KERN_WARNING "Error: jffs2_decompress returned %d\n", ret); - goto out_decomprbuf; - } - } - - if (len < je32_to_cpu(ri->dsize)) { - memcpy(buf, decomprbuf+ofs, len); - } - out_decomprbuf: - if(decomprbuf != buf && decomprbuf != readbuf) - kfree(decomprbuf); - out_readbuf: - if(readbuf != buf) - kfree(readbuf); - out_ri: - jffs2_free_raw_inode(ri); - - return ret; -} - -int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - unsigned char *buf, uint32_t offset, uint32_t len) -{ - uint32_t end = offset + len; - struct jffs2_node_frag *frag; - int ret; - - D1(printk(KERN_DEBUG "jffs2_read_inode_range: ino #%u, range 0x%08x-0x%08x\n", - f->inocache->ino, offset, offset+len)); - - frag = jffs2_lookup_node_frag(&f->fragtree, offset); - - /* XXX FIXME: Where a single physical node actually shows up in two - frags, we read it twice. Don't do that. */ - /* Now we're pointing at the first frag which overlaps our page */ - while(offset < end) { - D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end)); - if (unlikely(!frag || frag->ofs > offset)) { - uint32_t holesize = end - offset; - if (frag) { - D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); - holesize = min(holesize, frag->ofs - offset); - } - D1(printk(KERN_DEBUG "Filling non-frag hole from %d-%d\n", offset, offset+holesize)); - memset(buf, 0, holesize); - buf += holesize; - offset += holesize; - continue; - } else if (unlikely(!frag->node)) { - uint32_t holeend = min(end, frag->ofs + frag->size); - D1(printk(KERN_DEBUG "Filling frag hole from %d-%d (frag 0x%x 0x%x)\n", offset, holeend, frag->ofs, frag->ofs + frag->size)); - memset(buf, 0, holeend - offset); - buf += holeend - offset; - offset = holeend; - frag = frag_next(frag); - continue; - } else { - uint32_t readlen; - uint32_t fragofs; /* offset within the frag to start reading */ - - fragofs = offset - frag->ofs; - readlen = min(frag->size - fragofs, end - offset); - D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%08x (%d)\n", - frag->ofs+fragofs, frag->ofs+fragofs+readlen, - ref_offset(frag->node->raw), ref_flags(frag->node->raw))); - ret = jffs2_read_dnode(c, f, frag->node, buf, fragofs + frag->ofs - frag->node->ofs, readlen); - D2(printk(KERN_DEBUG "node read done\n")); - if (ret) { - D1(printk(KERN_DEBUG"jffs2_read_inode_range error %d\n",ret)); - memset(buf, 0, readlen); - return ret; - } - buf += readlen; - offset += readlen; - frag = frag_next(frag); - D2(printk(KERN_DEBUG "node read was OK. Looping\n")); - } - } - return 0; -} - diff --git a/components/dfs/filesystems/jffs2/src/readinode.c b/components/dfs/filesystems/jffs2/src/readinode.c deleted file mode 100644 index ae1481fd23..0000000000 --- a/components/dfs/filesystems/jffs2/src/readinode.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: readinode.c,v 1.132 2005/07/28 14:46:40 dedekind Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/fs.h> -#include <linux/crc32.h> -#include <linux/pagemap.h> -#include <linux/mtd/mtd.h> -#include <linux/compiler.h> -#include "nodelist.h" - -void jffs2_truncate_fragtree (struct jffs2_sb_info *c, struct rb_root *list, uint32_t size) -{ - struct jffs2_node_frag *frag = jffs2_lookup_node_frag(list, size); - - JFFS2_DBG_FRAGTREE("truncating fragtree to 0x%08x bytes\n", size); - - /* We know frag->ofs <= size. That's what lookup does for us */ - if (frag && frag->ofs != size) { - if (frag->ofs+frag->size >= size) { - JFFS2_DBG_FRAGTREE2("truncating frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size); - frag->size = size - frag->ofs; - } - frag = frag_next(frag); - } - while (frag && frag->ofs >= size) { - struct jffs2_node_frag *next = frag_next(frag); - - JFFS2_DBG_FRAGTREE("removing frag 0x%08x-0x%08x\n", frag->ofs, frag->ofs+frag->size); - frag_erase(frag, list); - jffs2_obsolete_node_frag(c, frag); - frag = next; - } -} - -/* - * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in - * order of increasing version. - */ -static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list) -{ - struct rb_node **p = &list->rb_node; - struct rb_node * parent = NULL; - struct jffs2_tmp_dnode_info *this; - - while (*p) { - parent = *p; - this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb); - - /* There may actually be a collision here, but it doesn't - actually matter. As long as the two nodes with the same - version are together, it's all fine. */ - if (tn->version < this->version) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } - - rb_link_node(&tn->rb, parent, p); - rb_insert_color(&tn->rb, list); -} - -static void jffs2_free_tmp_dnode_info_list(struct rb_root *list) -{ - struct rb_node *this; - struct jffs2_tmp_dnode_info *tn; - - this = list->rb_node; - - /* Now at bottom of tree */ - while (this) { - if (this->rb_left) - this = this->rb_left; - else if (this->rb_right) - this = this->rb_right; - else { - tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb); - jffs2_free_full_dnode(tn->fn); - jffs2_free_tmp_dnode_info(tn); - - this = this->rb_parent; - if (!this) - break; - - if (this->rb_left == &tn->rb) - this->rb_left = NULL; - else if (this->rb_right == &tn->rb) - this->rb_right = NULL; - else BUG(); - } - } - list->rb_node = NULL; -} - -static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) -{ - struct jffs2_full_dirent *next; - - while (fd) { - next = fd->next; - jffs2_free_full_dirent(fd); - fd = next; - } -} - -/* Returns first valid node after 'ref'. May return 'ref' */ -static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_ref *ref) -{ - while (ref && ref->next_in_ino) { - if (!ref_obsolete(ref)) - return ref; - JFFS2_DBG_NODEREF("node at 0x%08x is obsoleted. Ignoring.\n", ref_offset(ref)); - ref = ref->next_in_ino; - } - return NULL; -} - -/* - * Helper function for jffs2_get_inode_nodes(). - * It is called every time an directory entry node is found. - * - * Returns: 0 on succes; - * 1 if the node should be marked obsolete; - * negative error code on failure. - */ -static inline int -read_direntry(struct jffs2_sb_info *c, - struct jffs2_raw_node_ref *ref, - struct jffs2_raw_dirent *rd, - uint32_t read, - struct jffs2_full_dirent **fdp, - int32_t *latest_mctime, - uint32_t *mctime_ver) -{ - struct jffs2_full_dirent *fd; - - /* The direntry nodes are checked during the flash scanning */ - BUG_ON(ref_flags(ref) == REF_UNCHECKED); - /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ - BUG_ON(ref_obsolete(ref)); - - /* Sanity check */ - if (unlikely(PAD((rd->nsize + sizeof(*rd))) != PAD(je32_to_cpu(rd->totlen)))) { - JFFS2_ERROR("illegal nsize in node at %#08x: nsize %#02x, totlen %#04x\n", - ref_offset(ref), rd->nsize, je32_to_cpu(rd->totlen)); - return 1; - } - - fd = jffs2_alloc_full_dirent(rd->nsize + 1); - if (unlikely(!fd)) - return -ENOMEM; - - fd->raw = ref; - fd->version = je32_to_cpu(rd->version); - fd->ino = je32_to_cpu(rd->ino); - fd->type = rd->type; - - /* Pick out the mctime of the latest dirent */ - if(fd->version > *mctime_ver) { - *mctime_ver = fd->version; - *latest_mctime = je32_to_cpu(rd->mctime); - } - - /* - * Copy as much of the name as possible from the raw - * dirent we've already read from the flash. - */ - if (read > sizeof(*rd)) - memcpy(&fd->name[0], &rd->name[0], - min_t(uint32_t, rd->nsize, (read - sizeof(*rd)) )); - - /* Do we need to copy any more of the name directly from the flash? */ - if (rd->nsize + sizeof(*rd) > read) { - /* FIXME: point() */ - int err; - int already = read - sizeof(*rd); - - err = jffs2_flash_read(c, (ref_offset(ref)) + read, - rd->nsize - already, (size_t*)&read, &fd->name[already]); - if (unlikely(read != rd->nsize - already) && likely(!err)) - return -EIO; - - if (unlikely(err)) { - JFFS2_ERROR("read remainder of name: error %d\n", err); - jffs2_free_full_dirent(fd); - return -EIO; - } - } - - fd->nhash = full_name_hash(fd->name, rd->nsize); - fd->next = NULL; - fd->name[rd->nsize] = '\0'; - - /* - * Wheee. We now have a complete jffs2_full_dirent structure, with - * the name in it and everything. Link it into the list - */ - jffs2_add_fd_to_list(c, fd, fdp); - - return 0; -} - -/* - * Helper function for jffs2_get_inode_nodes(). - * It is called every time an inode node is found. - * - * Returns: 0 on succes; - * 1 if the node should be marked obsolete; - * negative error code on failure. - */ -static inline int -read_dnode(struct jffs2_sb_info *c, - struct jffs2_raw_node_ref *ref, - struct jffs2_raw_inode *rd, - uint32_t read, - struct rb_root *tnp, - int32_t *latest_mctime, - uint32_t *mctime_ver) -{ - struct jffs2_eraseblock *jeb; - struct jffs2_tmp_dnode_info *tn; - - /* Obsoleted. This cannot happen, surely? dwmw2 20020308 */ - BUG_ON(ref_obsolete(ref)); - - /* If we've never checked the CRCs on this node, check them now */ - if (ref_flags(ref) == REF_UNCHECKED) { - uint32_t crc, len; - - crc = crc32(0, rd, sizeof(*rd) - 8); - if (unlikely(crc != je32_to_cpu(rd->node_crc))) { - JFFS2_NOTICE("header CRC failed on node at %#08x: read %#08x, calculated %#08x\n", - ref_offset(ref), je32_to_cpu(rd->node_crc), crc); - return 1; - } - - /* Sanity checks */ - if (unlikely(je32_to_cpu(rd->offset) > je32_to_cpu(rd->isize)) || - unlikely(PAD(je32_to_cpu(rd->csize) + sizeof(*rd)) != PAD(je32_to_cpu(rd->totlen)))) { - JFFS2_WARNING("inode node header CRC is corrupted at %#08x\n", ref_offset(ref)); - jffs2_dbg_dump_node(c, ref_offset(ref)); - return 1; - } - - if (rd->compr != JFFS2_COMPR_ZERO && je32_to_cpu(rd->csize)) { - unsigned char *buf = NULL; - uint32_t pointed = 0; - int err; -#ifndef __ECOS - if (c->mtd->point) { - err = c->mtd->point (c->mtd, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize), - &read, &buf); - if (unlikely(read < je32_to_cpu(rd->csize)) && likely(!err)) { - JFFS2_ERROR("MTD point returned len too short: 0x%zx\n", read); - c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(*rd), - je32_to_cpu(rd->csize)); - } else if (unlikely(err)){ - JFFS2_ERROR("MTD point failed %d\n", err); - } else - pointed = 1; /* succefully pointed to device */ - } -#endif - if(!pointed){ - buf = kmalloc(je32_to_cpu(rd->csize), GFP_KERNEL); - if (!buf) - return -ENOMEM; - - err = jffs2_flash_read(c, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize), - (size_t*)&read, buf); - if (unlikely(read != je32_to_cpu(rd->csize)) && likely(!err)) - err = -EIO; - if (err) { - kfree(buf); - return err; - } - } - crc = crc32(0, buf, je32_to_cpu(rd->csize)); - if(!pointed) - kfree(buf); -#ifndef __ECOS - else - c->mtd->unpoint(c->mtd, buf, ref_offset(ref) + sizeof(*rd), je32_to_cpu(rd->csize)); -#endif - - if (crc != je32_to_cpu(rd->data_crc)) { - JFFS2_NOTICE("data CRC failed on node at %#08x: read %#08x, calculated %#08x\n", - ref_offset(ref), je32_to_cpu(rd->data_crc), crc); - return 1; - } - - } - - /* Mark the node as having been checked and fix the accounting accordingly */ - jeb = &c->blocks[ref->flash_offset / c->sector_size]; - len = ref_totlen(c, jeb, ref); - - spin_lock(&c->erase_completion_lock); - jeb->used_size += len; - jeb->unchecked_size -= len; - c->used_size += len; - c->unchecked_size -= len; - - /* If node covers at least a whole page, or if it starts at the - beginning of a page and runs to the end of the file, or if - it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. - - If it's actually overlapped, it'll get made NORMAL (or OBSOLETE) - when the overlapping node(s) get added to the tree anyway. - */ - if ((je32_to_cpu(rd->dsize) >= PAGE_CACHE_SIZE) || - ( ((je32_to_cpu(rd->offset) & (PAGE_CACHE_SIZE-1))==0) && - (je32_to_cpu(rd->dsize) + je32_to_cpu(rd->offset) == je32_to_cpu(rd->isize)))) { - JFFS2_DBG_READINODE("marking node at %#08x REF_PRISTINE\n", ref_offset(ref)); - ref->flash_offset = ref_offset(ref) | REF_PRISTINE; - } else { - JFFS2_DBG_READINODE("marking node at %#08x REF_NORMAL\n", ref_offset(ref)); - ref->flash_offset = ref_offset(ref) | REF_NORMAL; - } - spin_unlock(&c->erase_completion_lock); - } - - tn = jffs2_alloc_tmp_dnode_info(); - if (!tn) { - JFFS2_ERROR("alloc tn failed\n"); - return -ENOMEM; - } - - tn->fn = jffs2_alloc_full_dnode(); - if (!tn->fn) { - JFFS2_ERROR("alloc fn failed\n"); - jffs2_free_tmp_dnode_info(tn); - return -ENOMEM; - } - - tn->version = je32_to_cpu(rd->version); - tn->fn->ofs = je32_to_cpu(rd->offset); - tn->fn->raw = ref; - - /* There was a bug where we wrote hole nodes out with - csize/dsize swapped. Deal with it */ - if (rd->compr == JFFS2_COMPR_ZERO && !je32_to_cpu(rd->dsize) && je32_to_cpu(rd->csize)) - tn->fn->size = je32_to_cpu(rd->csize); - else // normal case... - tn->fn->size = je32_to_cpu(rd->dsize); - - JFFS2_DBG_READINODE("dnode @%08x: ver %u, offset %#04x, dsize %#04x\n", - ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize)); - - jffs2_add_tn_to_tree(tn, tnp); - - return 0; -} - -/* - * Helper function for jffs2_get_inode_nodes(). - * It is called every time an unknown node is found. - * - * Returns: 0 on succes; - * 1 if the node should be marked obsolete; - * negative error code on failure. - */ -static inline int -read_unknown(struct jffs2_sb_info *c, - struct jffs2_raw_node_ref *ref, - struct jffs2_unknown_node *un, - uint32_t read) -{ - /* We don't mark unknown nodes as REF_UNCHECKED */ - BUG_ON(ref_flags(ref) == REF_UNCHECKED); - - un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); - - if (crc32(0, un, sizeof(struct jffs2_unknown_node) - 4) != je32_to_cpu(un->hdr_crc)) { - /* Hmmm. This should have been caught at scan time. */ - JFFS2_NOTICE("node header CRC failed at %#08x. But it must have been OK earlier.\n", ref_offset(ref)); - jffs2_dbg_dump_node(c, ref_offset(ref)); - return 1; - } else { - switch(je16_to_cpu(un->nodetype) & JFFS2_COMPAT_MASK) { - - case JFFS2_FEATURE_INCOMPAT: - JFFS2_ERROR("unknown INCOMPAT nodetype %#04X at %#08x\n", - je16_to_cpu(un->nodetype), ref_offset(ref)); - /* EEP */ - BUG(); - break; - - case JFFS2_FEATURE_ROCOMPAT: - JFFS2_ERROR("unknown ROCOMPAT nodetype %#04X at %#08x\n", - je16_to_cpu(un->nodetype), ref_offset(ref)); - BUG_ON(!(c->flags & JFFS2_SB_FLAG_RO)); - break; - - case JFFS2_FEATURE_RWCOMPAT_COPY: - JFFS2_NOTICE("unknown RWCOMPAT_COPY nodetype %#04X at %#08x\n", - je16_to_cpu(un->nodetype), ref_offset(ref)); - break; - - case JFFS2_FEATURE_RWCOMPAT_DELETE: - JFFS2_NOTICE("unknown RWCOMPAT_DELETE nodetype %#04X at %#08x\n", - je16_to_cpu(un->nodetype), ref_offset(ref)); - return 1; - } - } - - return 0; -} - -/* Get tmp_dnode_info and full_dirent for all non-obsolete nodes associated - with this ino, returning the former in order of version */ - -static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - struct rb_root *tnp, struct jffs2_full_dirent **fdp, - uint32_t *highest_version, uint32_t *latest_mctime, - uint32_t *mctime_ver) -{ - struct jffs2_raw_node_ref *ref, *valid_ref; - struct rb_root ret_tn = RB_ROOT; - struct jffs2_full_dirent *ret_fd = NULL; - union jffs2_node_union node; - size_t retlen; - int err; - - *mctime_ver = 0; - - JFFS2_DBG_READINODE("ino #%u\n", f->inocache->ino); - - spin_lock(&c->erase_completion_lock); - - valid_ref = jffs2_first_valid_node(f->inocache->nodes); - - if (!valid_ref && (f->inocache->ino != 1)) - JFFS2_WARNING("no valid nodes for ino #%u\n", f->inocache->ino); - - while (valid_ref) { - /* We can hold a pointer to a non-obsolete node without the spinlock, - but _obsolete_ nodes may disappear at any time, if the block - they're in gets erased. So if we mark 'ref' obsolete while we're - not holding the lock, it can go away immediately. For that reason, - we find the next valid node first, before processing 'ref'. - */ - ref = valid_ref; - valid_ref = jffs2_first_valid_node(ref->next_in_ino); - spin_unlock(&c->erase_completion_lock); - - cond_resched(); - - /* FIXME: point() */ - err = jffs2_flash_read(c, (ref_offset(ref)), - min_t(uint32_t, ref_totlen(c, NULL, ref), sizeof(node)), - &retlen, (void *)&node); - if (err) { - JFFS2_ERROR("error %d reading node at 0x%08x in get_inode_nodes()\n", err, ref_offset(ref)); - goto free_out; - } - - switch (je16_to_cpu(node.u.nodetype)) { - - case JFFS2_NODETYPE_DIRENT: - JFFS2_DBG_READINODE("node at %08x (%d) is a dirent node\n", ref_offset(ref), ref_flags(ref)); - - if (retlen < sizeof(node.d)) { - JFFS2_ERROR("short read dirent at %#08x\n", ref_offset(ref)); - err = -EIO; - goto free_out; - } - - err = read_direntry(c, ref, &node.d, retlen, &ret_fd, (int32_t *)latest_mctime, mctime_ver); - if (err == 1) { - jffs2_mark_node_obsolete(c, ref); - break; - } else if (unlikely(err)) - goto free_out; - - if (je32_to_cpu(node.d.version) > *highest_version) - *highest_version = je32_to_cpu(node.d.version); - - break; - - case JFFS2_NODETYPE_INODE: - JFFS2_DBG_READINODE("node at %08x (%d) is a data node\n", ref_offset(ref), ref_flags(ref)); - - if (retlen < sizeof(node.i)) { - JFFS2_ERROR("short read dnode at %#08x\n", ref_offset(ref)); - err = -EIO; - goto free_out; - } - - err = read_dnode(c, ref, &node.i, retlen, &ret_tn, (int32_t *)latest_mctime, mctime_ver); - if (err == 1) { - jffs2_mark_node_obsolete(c, ref); - break; - } else if (unlikely(err)) - goto free_out; - - if (je32_to_cpu(node.i.version) > *highest_version) - *highest_version = je32_to_cpu(node.i.version); - - JFFS2_DBG_READINODE("version %d, highest_version now %d\n", - je32_to_cpu(node.i.version), *highest_version); - - break; - - default: - /* Check we've managed to read at least the common node header */ - if (retlen < sizeof(struct jffs2_unknown_node)) { - JFFS2_ERROR("short read unknown node at %#08x\n", ref_offset(ref)); - return -EIO; - } - - err = read_unknown(c, ref, &node.u, retlen); - if (err == 1) { - jffs2_mark_node_obsolete(c, ref); - break; - } else if (unlikely(err)) - goto free_out; - - } - spin_lock(&c->erase_completion_lock); - - } - spin_unlock(&c->erase_completion_lock); - *tnp = ret_tn; - *fdp = ret_fd; - - return 0; - - free_out: - jffs2_free_tmp_dnode_info_list(&ret_tn); - jffs2_free_full_dirent_list(ret_fd); - return err; -} - -static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c, - struct jffs2_inode_info *f, - struct jffs2_raw_inode *latest_node) -{ - struct jffs2_tmp_dnode_info *tn = NULL; - struct rb_root tn_list; - struct rb_node *rb, *repl_rb; - struct jffs2_full_dirent *fd_list; - struct jffs2_full_dnode *fn = NULL; - uint32_t crc; - uint32_t latest_mctime, mctime_ver; - uint32_t mdata_ver = 0; - size_t retlen; - int ret; - - JFFS2_DBG_READINODE("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink); - - /* Grab all nodes relevant to this ino */ - ret = jffs2_get_inode_nodes(c, f, &tn_list, &fd_list, &f->highest_version, &latest_mctime, &mctime_ver); - - if (ret) { - JFFS2_ERROR("cannot read nodes for ino %u, returned error is %d\n", f->inocache->ino, ret); - if (f->inocache->state == INO_STATE_READING) - jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); - return ret; - } - f->dents = fd_list; - - rb = rb_first(&tn_list); - - while (rb) { - tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb); - fn = tn->fn; - - if (f->metadata) { - if (likely(tn->version >= mdata_ver)) { - JFFS2_DBG_READINODE("obsoleting old metadata at 0x%08x\n", ref_offset(f->metadata->raw)); - jffs2_mark_node_obsolete(c, f->metadata->raw); - jffs2_free_full_dnode(f->metadata); - f->metadata = NULL; - - mdata_ver = 0; - } else { - /* This should never happen. */ - JFFS2_ERROR("Er. New metadata at 0x%08x with ver %d is actually older than previous ver %d at 0x%08x\n", - ref_offset(fn->raw), tn->version, mdata_ver, ref_offset(f->metadata->raw)); - jffs2_mark_node_obsolete(c, fn->raw); - jffs2_free_full_dnode(fn); - /* Fill in latest_node from the metadata, not this one we're about to free... */ - fn = f->metadata; - goto next_tn; - } - } - - if (fn->size) { - jffs2_add_full_dnode_to_inode(c, f, fn); - } else { - /* Zero-sized node at end of version list. Just a metadata update */ - JFFS2_DBG_READINODE("metadata @%08x: ver %d\n", ref_offset(fn->raw), tn->version); - f->metadata = fn; - mdata_ver = tn->version; - } - next_tn: - BUG_ON(rb->rb_left); - if (rb->rb_parent && rb->rb_parent->rb_left == rb) { - /* We were then left-hand child of our parent. We need - to move our own right-hand child into our place. */ - repl_rb = rb->rb_right; - if (repl_rb) - repl_rb->rb_parent = rb->rb_parent; - } else - repl_rb = NULL; - - rb = rb_next(rb); - - /* Remove the spent tn from the tree; don't bother rebalancing - but put our right-hand child in our own place. */ - if (tn->rb.rb_parent) { - if (tn->rb.rb_parent->rb_left == &tn->rb) - tn->rb.rb_parent->rb_left = repl_rb; - else if (tn->rb.rb_parent->rb_right == &tn->rb) - tn->rb.rb_parent->rb_right = repl_rb; - else BUG(); - } else if (tn->rb.rb_right) - tn->rb.rb_right->rb_parent = NULL; - - jffs2_free_tmp_dnode_info(tn); - } - jffs2_dbg_fragtree_paranoia_check_nolock(f); - - if (!fn) { - /* No data nodes for this inode. */ - if (f->inocache->ino != 1) { - JFFS2_WARNING("no data nodes found for ino #%u\n", f->inocache->ino); - if (!fd_list) { - if (f->inocache->state == INO_STATE_READING) - jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); - return -EIO; - } - JFFS2_NOTICE("but it has children so we fake some modes for it\n"); - } - latest_node->mode = cpu_to_jemode(S_IFDIR|S_IRUGO|S_IWUSR|S_IXUGO); - latest_node->version = cpu_to_je32(0); - latest_node->atime = latest_node->ctime = latest_node->mtime = cpu_to_je32(0); - latest_node->isize = cpu_to_je32(0); - latest_node->gid = cpu_to_je16(0); - latest_node->uid = cpu_to_je16(0); - if (f->inocache->state == INO_STATE_READING) - jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); - return 0; - } - - ret = jffs2_flash_read(c, ref_offset(fn->raw), sizeof(*latest_node), &retlen, (void *)latest_node); - if (ret || retlen != sizeof(*latest_node)) { - JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n", - ret, retlen, sizeof(*latest_node)); - /* FIXME: If this fails, there seems to be a memory leak. Find it. */ - up(&f->sem); - jffs2_do_clear_inode(c, f); - return ret?ret:-EIO; - } - - crc = crc32(0, latest_node, sizeof(*latest_node)-8); - if (crc != je32_to_cpu(latest_node->node_crc)) { - JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n", - f->inocache->ino, ref_offset(fn->raw)); - up(&f->sem); - jffs2_do_clear_inode(c, f); - return -EIO; - } - - switch(jemode_to_cpu(latest_node->mode) & S_IFMT) { - case S_IFDIR: - if (mctime_ver > je32_to_cpu(latest_node->version)) { - /* The times in the latest_node are actually older than - mctime in the latest dirent. Cheat. */ - latest_node->ctime = latest_node->mtime = cpu_to_je32(latest_mctime); - } - break; - - - case S_IFREG: - /* If it was a regular file, truncate it to the latest node's isize */ - jffs2_truncate_fragtree(c, &f->fragtree, je32_to_cpu(latest_node->isize)); - break; - -// case S_IFLNK: prife -// /* Hack to work around broken isize in old symlink code. -// Remove this when dwmw2 comes to his senses and stops -// symlinks from being an entirely gratuitous special -// case. */ -// if (!je32_to_cpu(latest_node->isize)) -// latest_node->isize = latest_node->dsize; -// -// if (f->inocache->state != INO_STATE_CHECKING) { -// /* Symlink's inode data is the target path. Read it and -// * keep in RAM to facilitate quick follow symlink -// * operation. */ -// f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL); -// if (!f->target) { -// JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize)); -// up(&f->sem); -// jffs2_do_clear_inode(c, f); -// return -ENOMEM; -// } -// -// ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node), -// je32_to_cpu(latest_node->csize), &retlen, (char *)f->target); -// -// if (ret || retlen != je32_to_cpu(latest_node->csize)) { -// if (retlen != je32_to_cpu(latest_node->csize)) -// ret = -EIO; -// kfree(f->target); -// f->target = NULL; -// up(&f->sem); -// jffs2_do_clear_inode(c, f); -// return -ret; -// } -// -// f->target[je32_to_cpu(latest_node->csize)] = '\0'; -// JFFS2_DBG_READINODE("symlink's target '%s' cached\n", f->target); -// } -// -// /* fall through... */ - - case S_IFBLK: - case S_IFCHR: - /* Certain inode types should have only one data node, and it's - kept as the metadata node */ - if (f->metadata) { - JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n", - f->inocache->ino, jemode_to_cpu(latest_node->mode)); - up(&f->sem); - jffs2_do_clear_inode(c, f); - return -EIO; - } - if (!frag_first(&f->fragtree)) { - JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n", - f->inocache->ino, jemode_to_cpu(latest_node->mode)); - up(&f->sem); - jffs2_do_clear_inode(c, f); - return -EIO; - } - /* ASSERT: f->fraglist != NULL */ - if (frag_next(frag_first(&f->fragtree))) { - JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n", - f->inocache->ino, jemode_to_cpu(latest_node->mode)); - /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */ - up(&f->sem); - jffs2_do_clear_inode(c, f); - return -EIO; - } - /* OK. We're happy */ - f->metadata = frag_first(&f->fragtree)->node; - jffs2_free_node_frag(frag_first(&f->fragtree)); - f->fragtree.rb_node = NULL;//f->fragtree = RB_ROOT; // modify it for vs - break; - } - if (f->inocache->state == INO_STATE_READING) - jffs2_set_inocache_state(c, f->inocache, INO_STATE_PRESENT); - - return 0; -} - -/* Scan the list of all nodes present for this ino, build map of versions, etc. */ -int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - uint32_t ino, struct jffs2_raw_inode *latest_node) -{ - JFFS2_DBG_READINODE("read inode #%u\n", ino); - - retry_inocache: - spin_lock(&c->inocache_lock); - f->inocache = jffs2_get_ino_cache(c, ino); - - if (f->inocache) { - /* Check its state. We may need to wait before we can use it */ - switch(f->inocache->state) { - case INO_STATE_UNCHECKED: - case INO_STATE_CHECKEDABSENT: - f->inocache->state = INO_STATE_READING; - break; - - case INO_STATE_CHECKING: - case INO_STATE_GC: - /* If it's in either of these states, we need - to wait for whoever's got it to finish and - put it back. */ - JFFS2_DBG_READINODE("waiting for ino #%u in state %d\n", ino, f->inocache->state); - sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); - goto retry_inocache; - - case INO_STATE_READING: - case INO_STATE_PRESENT: - /* Eep. This should never happen. It can - happen if Linux calls read_inode() again - before clear_inode() has finished though. */ - JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state); - /* Fail. That's probably better than allowing it to succeed */ - f->inocache = NULL; - break; - - default: - BUG(); - } - } - spin_unlock(&c->inocache_lock); - - if (!f->inocache && ino == 1) { - /* Special case - no root inode on medium */ - f->inocache = jffs2_alloc_inode_cache(); - if (!f->inocache) { - JFFS2_ERROR("cannot allocate inocache for root inode\n"); - return -ENOMEM; - } - JFFS2_DBG_READINODE("creating inocache for root inode\n"); - memset(f->inocache, 0, sizeof(struct jffs2_inode_cache)); - f->inocache->ino = f->inocache->nlink = 1; - f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; - f->inocache->state = INO_STATE_READING; - jffs2_add_ino_cache(c, f->inocache); - } - if (!f->inocache) { - JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino); - return -ENOENT; - } - - return jffs2_do_read_inode_internal(c, f, latest_node); -} - -int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) -{ - struct jffs2_raw_inode n; - struct jffs2_inode_info *f = kmalloc(sizeof(*f), GFP_KERNEL); - int ret; - - if (!f) - return -ENOMEM; - - memset(f, 0, sizeof(*f)); - init_MUTEX_LOCKED(&f->sem); - f->inocache = ic; - - ret = jffs2_do_read_inode_internal(c, f, &n); - if (!ret) { - up(&f->sem); - jffs2_do_clear_inode(c, f); - } - kfree (f); - return ret; -} - -void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f) -{ - struct jffs2_full_dirent *fd, *fds; - int deleted; - - down(&f->sem); - deleted = f->inocache && !f->inocache->nlink; - - if (f->inocache && f->inocache->state != INO_STATE_CHECKING) - jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING); - - if (f->metadata) { - if (deleted) - jffs2_mark_node_obsolete(c, f->metadata->raw); - jffs2_free_full_dnode(f->metadata); - } - - jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); - - if (f->target) { - kfree(f->target); - f->target = NULL; - } - - fds = f->dents; - while(fds) { - fd = fds; - fds = fd->next; - jffs2_free_full_dirent(fd); - } - - if (f->inocache && f->inocache->state != INO_STATE_CHECKING) { - jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); - if (f->inocache->nodes == (void *)f->inocache) - jffs2_del_ino_cache(c, f->inocache); - } - - up(&f->sem); -} diff --git a/components/dfs/filesystems/jffs2/src/scan.c b/components/dfs/filesystems/jffs2/src/scan.c deleted file mode 100644 index f67d122a12..0000000000 --- a/components/dfs/filesystems/jffs2/src/scan.c +++ /dev/null @@ -1,946 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: scan.c,v 1.121 2005/07/20 15:32:28 dedekind Exp $ - * - */ -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/mtd/mtd.h> -#include <linux/pagemap.h> -#include <linux/crc32.h> -#include <linux/compiler.h> -#include "nodelist.h" - -#define DEFAULT_EMPTY_SCAN_SIZE 1024 - -#if defined (__GNUC__) -#elif defined (MSVC) -#define typeof(x) uint32_t -#else -#endif - -#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \ - c->free_size -= _x; c->dirty_size += _x; \ - jeb->free_size -= _x ; jeb->dirty_size += _x; \ - }while(0) -#define USED_SPACE(x) do { typeof(x) _x = (x); \ - c->free_size -= _x; c->used_size += _x; \ - jeb->free_size -= _x ; jeb->used_size += _x; \ - }while(0) -#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \ - c->free_size -= _x; c->unchecked_size += _x; \ - jeb->free_size -= _x ; jeb->unchecked_size += _x; \ - }while(0) - -#if defined (__GNUC__) -#define noisy_printk(noise, args...) do { \ - if (*(noise)) { \ - printk(KERN_NOTICE args); \ - (*(noise))--; \ - if (!(*(noise))) { \ - printk(KERN_NOTICE "Further such events for this erase block will not be printed\n"); \ - } \ - } \ -} while(0) -#elif defined (MSVC) -#define noisy_printk(noise, ...) do { \ - if (*(noise)) { \ - printk(KERN_NOTICE ##__VA_ARGS__); \ - (*(noise))--; \ - if (!(*(noise))) { \ - printk(KERN_NOTICE "Further such events for this erase block will not be printed\n"); \ - } \ - } \ -} while(0) -#else -#endif - -static uint32_t pseudo_random; - -static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - unsigned char *buf, uint32_t buf_size); - -/* These helper functions _must_ increase ofs and also do the dirty/used space accounting. - * Returning an error will abort the mount - bad checksums etc. should just mark the space - * as dirty. - */ -static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_raw_inode *ri, uint32_t ofs); -static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_raw_dirent *rd, uint32_t ofs); - -#define BLK_STATE_ALLFF 0 -#define BLK_STATE_CLEAN 1 -#define BLK_STATE_PARTDIRTY 2 -#define BLK_STATE_CLEANMARKER 3 -#define BLK_STATE_ALLDIRTY 4 -#define BLK_STATE_BADBLOCK 5 - -static inline int min_free(struct jffs2_sb_info *c) -{ - uint32_t min = 2 * sizeof(struct jffs2_raw_inode); -#ifdef CONFIG_JFFS2_FS_WRITEBUFFER - if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize) - return c->wbuf_pagesize; -#endif - return min; - -} - -static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) { - if (sector_size < DEFAULT_EMPTY_SCAN_SIZE) - return sector_size; - else - return DEFAULT_EMPTY_SCAN_SIZE; -} - -int jffs2_scan_medium(struct jffs2_sb_info *c) -{ - int i, ret; - uint32_t empty_blocks = 0, bad_blocks = 0; - unsigned char *flashbuf = NULL; - uint32_t buf_size = 0; -#ifndef __ECOS - size_t pointlen; - - if (c->mtd->point) { - ret = c->mtd->point (c->mtd, 0, c->mtd->size, &pointlen, &flashbuf); - if (!ret && pointlen < c->mtd->size) { - /* Don't muck about if it won't let us point to the whole flash */ - D1(printk(KERN_DEBUG "MTD point returned len too short: 0x%zx\n", pointlen)); - c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); - flashbuf = NULL; - } - if (ret) - D1(printk(KERN_DEBUG "MTD point failed %d\n", ret)); - } -#endif - if (!flashbuf) { - /* For NAND it's quicker to read a whole eraseblock at a time, - apparently */ - if (jffs2_cleanmarker_oob(c)) - buf_size = c->sector_size; - else - buf_size = PAGE_SIZE; - - /* Respect kmalloc limitations */ - if (buf_size > 128*1024) - buf_size = 128*1024; - - D1(printk(KERN_DEBUG "Allocating readbuf of %d bytes\n", buf_size)); - flashbuf = kmalloc(buf_size, GFP_KERNEL); - if (!flashbuf) - return -ENOMEM; - } - - for (i=0; i<c->nr_blocks; i++) { - struct jffs2_eraseblock *jeb = &c->blocks[i]; - - ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset), buf_size); - - if (ret < 0) - goto out; - - jffs2_dbg_acct_paranoia_check_nolock(c, jeb); - - /* Now decide which list to put it on */ - switch(ret) { - case BLK_STATE_ALLFF: - /* - * Empty block. Since we can't be sure it - * was entirely erased, we just queue it for erase - * again. It will be marked as such when the erase - * is complete. Meanwhile we still count it as empty - * for later checks. - */ - empty_blocks++; - list_add(&jeb->list, &c->erase_pending_list); - c->nr_erasing_blocks++; - break; - - case BLK_STATE_CLEANMARKER: - /* Only a CLEANMARKER node is valid */ - if (!jeb->dirty_size) { - /* It's actually free */ - list_add(&jeb->list, &c->free_list); - c->nr_free_blocks++; - } else { - /* Dirt */ - D1(printk(KERN_DEBUG "Adding all-dirty block at 0x%08x to erase_pending_list\n", jeb->offset)); - list_add(&jeb->list, &c->erase_pending_list); - c->nr_erasing_blocks++; - } - break; - - case BLK_STATE_CLEAN: - /* Full (or almost full) of clean data. Clean list */ - list_add(&jeb->list, &c->clean_list); - break; - - case BLK_STATE_PARTDIRTY: - /* Some data, but not full. Dirty list. */ - /* We want to remember the block with most free space - and stick it in the 'nextblock' position to start writing to it. */ - if (jeb->free_size > min_free(c) && - (!c->nextblock || c->nextblock->free_size < jeb->free_size)) { - /* Better candidate for the next writes to go to */ - if (c->nextblock) { - c->nextblock->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; - c->dirty_size += c->nextblock->free_size + c->nextblock->wasted_size; - c->free_size -= c->nextblock->free_size; - c->wasted_size -= c->nextblock->wasted_size; - c->nextblock->free_size = c->nextblock->wasted_size = 0; - if (VERYDIRTY(c, c->nextblock->dirty_size)) { - list_add(&c->nextblock->list, &c->very_dirty_list); - } else { - list_add(&c->nextblock->list, &c->dirty_list); - } - } - c->nextblock = jeb; - } else { - jeb->dirty_size += jeb->free_size + jeb->wasted_size; - c->dirty_size += jeb->free_size + jeb->wasted_size; - c->free_size -= jeb->free_size; - c->wasted_size -= jeb->wasted_size; - jeb->free_size = jeb->wasted_size = 0; - if (VERYDIRTY(c, jeb->dirty_size)) { - list_add(&jeb->list, &c->very_dirty_list); - } else { - list_add(&jeb->list, &c->dirty_list); - } - } - break; - - case BLK_STATE_ALLDIRTY: - /* Nothing valid - not even a clean marker. Needs erasing. */ - /* For now we just put it on the erasing list. We'll start the erases later */ - D1(printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset)); - list_add(&jeb->list, &c->erase_pending_list); - c->nr_erasing_blocks++; - break; - - case BLK_STATE_BADBLOCK: - D1(printk(KERN_NOTICE "JFFS2: Block at 0x%08x is bad\n", jeb->offset)); - list_add(&jeb->list, &c->bad_list); - c->bad_size += c->sector_size; - c->free_size -= c->sector_size; - bad_blocks++; - break; - default: - printk(KERN_WARNING "jffs2_scan_medium(): unknown block state\n"); - BUG(); - } - } - - /* Nextblock dirty is always seen as wasted, because we cannot recycle it now */ - if (c->nextblock && (c->nextblock->dirty_size)) { - c->nextblock->wasted_size += c->nextblock->dirty_size; - c->wasted_size += c->nextblock->dirty_size; - c->dirty_size -= c->nextblock->dirty_size; - c->nextblock->dirty_size = 0; - } -#ifdef CONFIG_JFFS2_FS_WRITEBUFFER - if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { - /* If we're going to start writing into a block which already - contains data, and the end of the data isn't page-aligned, - skip a little and align it. */ - - uint32_t skip = c->nextblock->free_size & (c->wbuf_pagesize-1); - - D1(printk(KERN_DEBUG "jffs2_scan_medium(): Skipping %d bytes in nextblock to ensure page alignment\n", - skip)); - c->nextblock->wasted_size += skip; - c->wasted_size += skip; - - c->nextblock->free_size -= skip; - c->free_size -= skip; - } -#endif - if (c->nr_erasing_blocks) { - if ( !c->used_size && ((c->nr_free_blocks+empty_blocks+bad_blocks)!= c->nr_blocks || bad_blocks == c->nr_blocks) ) { - printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n"); - printk(KERN_NOTICE "empty_blocks %d, bad_blocks %d, c->nr_blocks %d\n",empty_blocks,bad_blocks,c->nr_blocks); - ret = -EIO; - goto out; - } - jffs2_erase_pending_trigger(c); - } - ret = 0; - out: - if (buf_size) - kfree(flashbuf); -#ifndef __ECOS - else - c->mtd->unpoint(c->mtd, flashbuf, 0, c->mtd->size); -#endif - return ret; -} - -static int jffs2_fill_scan_buf (struct jffs2_sb_info *c, unsigned char *buf, - uint32_t ofs, uint32_t len) -{ - int ret; - size_t retlen; - - ret = jffs2_flash_read(c, ofs, len, &retlen, buf); - if (ret) { - D1(printk(KERN_WARNING "mtd->read(0x%x bytes from 0x%x) returned %d\n", len, ofs, ret)); - return ret; - } - if (retlen < len) { - D1(printk(KERN_WARNING "Read at 0x%x gave only 0x%zx bytes\n", ofs, retlen)); - return -EIO; - } - D2(printk(KERN_DEBUG "Read 0x%x bytes from 0x%08x into buf\n", len, ofs)); - D2(printk(KERN_DEBUG "000: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", - buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15])); - return 0; -} - -static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - unsigned char *buf, uint32_t buf_size) { - struct jffs2_unknown_node *node; - struct jffs2_unknown_node crcnode; - uint32_t ofs, prevofs; - uint32_t hdr_crc, buf_ofs, buf_len; - int err; - int noise = 0; -#ifdef CONFIG_JFFS2_FS_WRITEBUFFER - int cleanmarkerfound = 0; -#endif - - ofs = jeb->offset; - prevofs = jeb->offset - 1; - - D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); - -#ifdef CONFIG_JFFS2_FS_WRITEBUFFER - if (jffs2_cleanmarker_oob(c)) { - int ret = jffs2_check_nand_cleanmarker(c, jeb); - D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); - /* Even if it's not found, we still scan to see - if the block is empty. We use this information - to decide whether to erase it or not. */ - switch (ret) { - case 0: cleanmarkerfound = 1; break; - case 1: break; - case 2: return BLK_STATE_BADBLOCK; - case 3: return BLK_STATE_ALLDIRTY; /* Block has failed to erase min. once */ - default: return ret; - } - } -#endif - buf_ofs = jeb->offset; - - if (!buf_size) { - buf_len = c->sector_size; - } else { - buf_len = EMPTY_SCAN_SIZE(c->sector_size); - err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); - if (err) - return err; - } - - /* We temporarily use 'ofs' as a pointer into the buffer/jeb */ - ofs = 0; - - /* Scan only 4KiB of 0xFF before declaring it's empty */ - while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) - ofs += 4; - - if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) { -#ifdef CONFIG_JFFS2_FS_WRITEBUFFER - if (jffs2_cleanmarker_oob(c)) { - /* scan oob, take care of cleanmarker */ - int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); - D2(printk(KERN_NOTICE "jffs2_check_oob_empty returned %d\n",ret)); - switch (ret) { - case 0: return cleanmarkerfound ? BLK_STATE_CLEANMARKER : BLK_STATE_ALLFF; - case 1: return BLK_STATE_ALLDIRTY; - default: return ret; - } - } -#endif - D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); - if (c->cleanmarker_size == 0) - return BLK_STATE_CLEANMARKER; /* don't bother with re-erase */ - else - return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ - } - if (ofs) { - D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, - jeb->offset + ofs)); - DIRTY_SPACE(ofs); - } - - /* Now ofs is a complete physical flash offset as it always was... */ - ofs += jeb->offset; - - noise = 10; - -scan_more: - while(ofs < jeb->offset + c->sector_size) { - - jffs2_dbg_acct_paranoia_check_nolock(c, jeb); - - cond_resched(); - - if (ofs & 3) { - printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs); - ofs = PAD(ofs); - continue; - } - if (ofs == prevofs) { - printk(KERN_WARNING "ofs 0x%08x has already been seen. Skipping\n", ofs); - DIRTY_SPACE(4); - ofs += 4; - continue; - } - prevofs = ofs; - - if (jeb->offset + c->sector_size < ofs + sizeof(*node)) { - D1(printk(KERN_DEBUG "Fewer than %zd bytes left to end of block. (%x+%x<%x+%zx) Not reading\n", sizeof(struct jffs2_unknown_node), - jeb->offset, c->sector_size, ofs, sizeof(*node))); - DIRTY_SPACE((jeb->offset + c->sector_size)-ofs); - break; - } - - if (buf_ofs + buf_len < ofs + sizeof(*node)) { - buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - D1(printk(KERN_DEBUG "Fewer than %zd bytes (node header) left to end of buf. Reading 0x%x at 0x%08x\n", - sizeof(struct jffs2_unknown_node), buf_len, ofs)); - err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); - if (err) - return err; - buf_ofs = ofs; - } - - node = (struct jffs2_unknown_node *)&buf[ofs-buf_ofs]; - - if (*(uint32_t *)(&buf[ofs-buf_ofs]) == 0xffffffff) { - uint32_t inbuf_ofs; - uint32_t empty_start; - - empty_start = ofs; - ofs += 4; - - D1(printk(KERN_DEBUG "Found empty flash at 0x%08x\n", ofs)); - more_empty: - inbuf_ofs = ofs - buf_ofs; - while (inbuf_ofs < buf_len) { - if (*(uint32_t *)(&buf[inbuf_ofs]) != 0xffffffff) { - printk(KERN_WARNING "Empty flash at 0x%08x ends at 0x%08x\n", - empty_start, ofs); - DIRTY_SPACE(ofs-empty_start); - goto scan_more; - } - - inbuf_ofs+=4; - ofs += 4; - } - /* Ran off end. */ - D1(printk(KERN_DEBUG "Empty flash to end of buffer at 0x%08x\n", ofs)); - - /* If we're only checking the beginning of a block with a cleanmarker, - bail now */ - if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && - c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) { - D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size))); - return BLK_STATE_CLEANMARKER; - } - - /* See how much more there is to read in this eraseblock... */ - buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - if (!buf_len) { - /* No more to read. Break out of main loop without marking - this range of empty space as dirty (because it's not) */ - D1(printk(KERN_DEBUG "Empty flash at %08x runs to end of block. Treating as free_space\n", - empty_start)); - break; - } - D1(printk(KERN_DEBUG "Reading another 0x%x at 0x%08x\n", buf_len, ofs)); - err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); - if (err) - return err; - buf_ofs = ofs; - goto more_empty; - } - - if (ofs == jeb->offset && je16_to_cpu(node->magic) == KSAMTIB_CIGAM_2SFFJ) { - printk(KERN_WARNING "Magic bitmask is backwards at offset 0x%08x. Wrong endian filesystem?\n", ofs); - DIRTY_SPACE(4); - ofs += 4; - continue; - } - if (je16_to_cpu(node->magic) == JFFS2_DIRTY_BITMASK) { - D1(printk(KERN_DEBUG "Dirty bitmask at 0x%08x\n", ofs)); - DIRTY_SPACE(4); - ofs += 4; - continue; - } - if (je16_to_cpu(node->magic) == JFFS2_OLD_MAGIC_BITMASK) { - printk(KERN_WARNING "Old JFFS2 bitmask found at 0x%08x\n", ofs); - printk(KERN_WARNING "You cannot use older JFFS2 filesystems with newer kernels\n"); - DIRTY_SPACE(4); - ofs += 4; - continue; - } - if (je16_to_cpu(node->magic) != JFFS2_MAGIC_BITMASK) { - /* OK. We're out of possibilities. Whinge and move on */ - noisy_printk(&noise, "jffs2_scan_eraseblock(): Magic bitmask 0x%04x not found at 0x%08x: 0x%04x instead\n", - JFFS2_MAGIC_BITMASK, ofs, - je16_to_cpu(node->magic)); - DIRTY_SPACE(4); - ofs += 4; - continue; - } - /* We seem to have a node of sorts. Check the CRC */ - crcnode.magic = node->magic; - crcnode.nodetype = cpu_to_je16( je16_to_cpu(node->nodetype) | JFFS2_NODE_ACCURATE); - crcnode.totlen = node->totlen; - hdr_crc = crc32(0, &crcnode, sizeof(crcnode)-4); - - if (hdr_crc != je32_to_cpu(node->hdr_crc)) { - noisy_printk(&noise, "jffs2_scan_eraseblock(): Node at 0x%08x {0x%04x, 0x%04x, 0x%08x) has invalid CRC 0x%08x (calculated 0x%08x)\n", - ofs, je16_to_cpu(node->magic), - je16_to_cpu(node->nodetype), - je32_to_cpu(node->totlen), - je32_to_cpu(node->hdr_crc), - hdr_crc); - DIRTY_SPACE(4); - ofs += 4; - continue; - } - - if (ofs + je32_to_cpu(node->totlen) > - jeb->offset + c->sector_size) { - /* Eep. Node goes over the end of the erase block. */ - printk(KERN_WARNING "Node at 0x%08x with length 0x%08x would run over the end of the erase block\n", - ofs, je32_to_cpu(node->totlen)); - printk(KERN_WARNING "Perhaps the file system was created with the wrong erase size?\n"); - DIRTY_SPACE(4); - ofs += 4; - continue; - } - - if (!(je16_to_cpu(node->nodetype) & JFFS2_NODE_ACCURATE)) { - /* Wheee. This is an obsoleted node */ - D2(printk(KERN_DEBUG "Node at 0x%08x is obsolete. Skipping\n", ofs)); - DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); - ofs += PAD(je32_to_cpu(node->totlen)); - continue; - } - - switch(je16_to_cpu(node->nodetype)) { - case JFFS2_NODETYPE_INODE: - if (buf_ofs + buf_len < ofs + sizeof(struct jffs2_raw_inode)) { - buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - D1(printk(KERN_DEBUG "Fewer than %zd bytes (inode node) left to end of buf. Reading 0x%x at 0x%08x\n", - sizeof(struct jffs2_raw_inode), buf_len, ofs)); - err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); - if (err) - return err; - buf_ofs = ofs; - node = (void *)buf; - } - err = jffs2_scan_inode_node(c, jeb, (void *)node, ofs); - if (err) return err; - ofs += PAD(je32_to_cpu(node->totlen)); - break; - - case JFFS2_NODETYPE_DIRENT: - if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { - buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); - D1(printk(KERN_DEBUG "Fewer than %d bytes (dirent node) left to end of buf. Reading 0x%x at 0x%08x\n", - je32_to_cpu(node->totlen), buf_len, ofs)); - err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); - if (err) - return err; - buf_ofs = ofs; - node = (void *)buf; - } - err = jffs2_scan_dirent_node(c, jeb, (void *)node, ofs); - if (err) return err; - ofs += PAD(je32_to_cpu(node->totlen)); - break; - - case JFFS2_NODETYPE_CLEANMARKER: - D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); - if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { - printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x has totlen 0x%x != normal 0x%x\n", - ofs, je32_to_cpu(node->totlen), c->cleanmarker_size); - DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); - ofs += PAD(sizeof(struct jffs2_unknown_node)); - } else if (jeb->first_node) { - printk(KERN_NOTICE "CLEANMARKER node found at 0x%08x, not first node in block (0x%08x)\n", ofs, jeb->offset); - DIRTY_SPACE(PAD(sizeof(struct jffs2_unknown_node))); - ofs += PAD(sizeof(struct jffs2_unknown_node)); - } else { - struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); - if (!marker_ref) { - printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n"); - return -ENOMEM; - } - marker_ref->next_in_ino = NULL; - marker_ref->next_phys = NULL; - marker_ref->flash_offset = ofs | REF_NORMAL; - marker_ref->__totlen = c->cleanmarker_size; - jeb->first_node = jeb->last_node = marker_ref; - - USED_SPACE(PAD(c->cleanmarker_size)); - ofs += PAD(c->cleanmarker_size); - } - break; - - case JFFS2_NODETYPE_PADDING: - DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); - ofs += PAD(je32_to_cpu(node->totlen)); - break; - - default: - switch (je16_to_cpu(node->nodetype) & JFFS2_COMPAT_MASK) { - case JFFS2_FEATURE_ROCOMPAT: - printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); - c->flags |= JFFS2_SB_FLAG_RO; - if (!(jffs2_is_readonly(c))) - return -EROFS; - DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); - ofs += PAD(je32_to_cpu(node->totlen)); - break; - - case JFFS2_FEATURE_INCOMPAT: - printk(KERN_NOTICE "Incompatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs); - return -EINVAL; - - case JFFS2_FEATURE_RWCOMPAT_DELETE: - D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); - DIRTY_SPACE(PAD(je32_to_cpu(node->totlen))); - ofs += PAD(je32_to_cpu(node->totlen)); - break; - - case JFFS2_FEATURE_RWCOMPAT_COPY: - D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); - USED_SPACE(PAD(je32_to_cpu(node->totlen))); - ofs += PAD(je32_to_cpu(node->totlen)); - break; - } - } - } - - - D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x\n", jeb->offset, - jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size)); - - /* mark_node_obsolete can add to wasted !! */ - if (jeb->wasted_size) { - jeb->dirty_size += jeb->wasted_size; - c->dirty_size += jeb->wasted_size; - c->wasted_size -= jeb->wasted_size; - jeb->wasted_size = 0; - } - - if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size - && (!jeb->first_node || !jeb->first_node->next_phys) ) - return BLK_STATE_CLEANMARKER; - - /* move blocks with max 4 byte dirty space to cleanlist */ - else if (!ISDIRTY(c->sector_size - (jeb->used_size + jeb->unchecked_size))) { - c->dirty_size -= jeb->dirty_size; - c->wasted_size += jeb->dirty_size; - jeb->wasted_size += jeb->dirty_size; - jeb->dirty_size = 0; - return BLK_STATE_CLEAN; - } else if (jeb->used_size || jeb->unchecked_size) - return BLK_STATE_PARTDIRTY; - else - return BLK_STATE_ALLDIRTY; -} - -static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino) -{ - struct jffs2_inode_cache *ic; - - ic = jffs2_get_ino_cache(c, ino); - if (ic) - return ic; - - if (ino > c->highest_ino) - c->highest_ino = ino; - - ic = jffs2_alloc_inode_cache(); - if (!ic) { - printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n"); - return NULL; - } - memset(ic, 0, sizeof(*ic)); - - ic->ino = ino; - ic->nodes = (void *)ic; - jffs2_add_ino_cache(c, ic); - if (ino == 1) - ic->nlink = 1; - return ic; -} - -static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_raw_inode *ri, uint32_t ofs) -{ - struct jffs2_raw_node_ref *raw; - struct jffs2_inode_cache *ic; - uint32_t ino = je32_to_cpu(ri->ino); - - D1(printk(KERN_DEBUG "jffs2_scan_inode_node(): Node at 0x%08x\n", ofs)); - - /* We do very little here now. Just check the ino# to which we should attribute - this node; we can do all the CRC checking etc. later. There's a tradeoff here -- - we used to scan the flash once only, reading everything we want from it into - memory, then building all our in-core data structures and freeing the extra - information. Now we allow the first part of the mount to complete a lot quicker, - but we have to go _back_ to the flash in order to finish the CRC checking, etc. - Which means that the _full_ amount of time to get to proper write mode with GC - operational may actually be _longer_ than before. Sucks to be me. */ - - raw = jffs2_alloc_raw_node_ref(); - if (!raw) { - printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n"); - return -ENOMEM; - } - - ic = jffs2_get_ino_cache(c, ino); - if (!ic) { - /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the - first node we found for this inode. Do a CRC check to protect against the former - case */ - uint32_t crc = crc32(0, ri, sizeof(*ri)-8); - - if (crc != je32_to_cpu(ri->node_crc)) { - printk(KERN_NOTICE "jffs2_scan_inode_node(): CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ofs, je32_to_cpu(ri->node_crc), crc); - /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ - DIRTY_SPACE(PAD(je32_to_cpu(ri->totlen))); - jffs2_free_raw_node_ref(raw); - return 0; - } - ic = jffs2_scan_make_ino_cache(c, ino); - if (!ic) { - jffs2_free_raw_node_ref(raw); - return -ENOMEM; - } - } - - /* Wheee. It worked */ - - raw->flash_offset = ofs | REF_UNCHECKED; - raw->__totlen = PAD(je32_to_cpu(ri->totlen)); - raw->next_phys = NULL; - raw->next_in_ino = ic->nodes; - - ic->nodes = raw; - if (!jeb->first_node) - jeb->first_node = raw; - if (jeb->last_node) - jeb->last_node->next_phys = raw; - jeb->last_node = raw; - - D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", - je32_to_cpu(ri->ino), je32_to_cpu(ri->version), - je32_to_cpu(ri->offset), - je32_to_cpu(ri->offset)+je32_to_cpu(ri->dsize))); - - pseudo_random += je32_to_cpu(ri->version); - - UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen))); - return 0; -} - -static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, - struct jffs2_raw_dirent *rd, uint32_t ofs) -{ - struct jffs2_raw_node_ref *raw; - struct jffs2_full_dirent *fd; - struct jffs2_inode_cache *ic; - uint32_t crc; - - D1(printk(KERN_DEBUG "jffs2_scan_dirent_node(): Node at 0x%08x\n", ofs)); - - /* We don't get here unless the node is still valid, so we don't have to - mask in the ACCURATE bit any more. */ - crc = crc32(0, rd, sizeof(*rd)-8); - - if (crc != je32_to_cpu(rd->node_crc)) { - printk(KERN_NOTICE "jffs2_scan_dirent_node(): Node CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ofs, je32_to_cpu(rd->node_crc), crc); - /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ - DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen))); - return 0; - } - - pseudo_random += je32_to_cpu(rd->version); - - fd = jffs2_alloc_full_dirent(rd->nsize+1); - if (!fd) { - return -ENOMEM; - } - memcpy(&fd->name, rd->name, rd->nsize); - fd->name[rd->nsize] = 0; - - crc = crc32(0, fd->name, rd->nsize); - if (crc != je32_to_cpu(rd->name_crc)) { - printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n", - ofs, je32_to_cpu(rd->name_crc), crc); - D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, je32_to_cpu(rd->ino))); - jffs2_free_full_dirent(fd); - /* FIXME: Why do we believe totlen? */ - /* We believe totlen because the CRC on the node _header_ was OK, just the name failed. */ - DIRTY_SPACE(PAD(je32_to_cpu(rd->totlen))); - return 0; - } - raw = jffs2_alloc_raw_node_ref(); - if (!raw) { - jffs2_free_full_dirent(fd); - printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n"); - return -ENOMEM; - } - ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino)); - if (!ic) { - jffs2_free_full_dirent(fd); - jffs2_free_raw_node_ref(raw); - return -ENOMEM; - } - - raw->__totlen = PAD(je32_to_cpu(rd->totlen)); - raw->flash_offset = ofs | REF_PRISTINE; - raw->next_phys = NULL; - raw->next_in_ino = ic->nodes; - ic->nodes = raw; - if (!jeb->first_node) - jeb->first_node = raw; - if (jeb->last_node) - jeb->last_node->next_phys = raw; - jeb->last_node = raw; - - fd->raw = raw; - fd->next = NULL; - fd->version = je32_to_cpu(rd->version); - fd->ino = je32_to_cpu(rd->ino); - fd->nhash = full_name_hash(fd->name, rd->nsize); - fd->type = rd->type; - USED_SPACE(PAD(je32_to_cpu(rd->totlen))); - jffs2_add_fd_to_list(c, fd, &ic->scan_dents); - - return 0; -} - -static int count_list(struct list_head *l) -{ - uint32_t count = 0; - struct list_head *tmp; - - list_for_each(tmp, l) { - count++; - } - return count; -} - -/* Note: This breaks if list_empty(head). I don't care. You - might, if you copy this code and use it elsewhere :) */ -static void rotate_list(struct list_head *head, uint32_t count) -{ - struct list_head *n = head->next; - - list_del(head); - while(count--) { - n = n->next; - } - list_add(head, n); -} - -void jffs2_rotate_lists(struct jffs2_sb_info *c) -{ - uint32_t x; - uint32_t rotateby; - - x = count_list(&c->clean_list); - if (x) { - rotateby = pseudo_random % x; - D1(printk(KERN_DEBUG "Rotating clean_list by %d\n", rotateby)); - - rotate_list((&c->clean_list), rotateby); - - D1(printk(KERN_DEBUG "Erase block at front of clean_list is at %08x\n", - list_entry(c->clean_list.next, struct jffs2_eraseblock, list)->offset)); - } else { - D1(printk(KERN_DEBUG "Not rotating empty clean_list\n")); - } - - x = count_list(&c->very_dirty_list); - if (x) { - rotateby = pseudo_random % x; - D1(printk(KERN_DEBUG "Rotating very_dirty_list by %d\n", rotateby)); - - rotate_list((&c->very_dirty_list), rotateby); - - D1(printk(KERN_DEBUG "Erase block at front of very_dirty_list is at %08x\n", - list_entry(c->very_dirty_list.next, struct jffs2_eraseblock, list)->offset)); - } else { - D1(printk(KERN_DEBUG "Not rotating empty very_dirty_list\n")); - } - - x = count_list(&c->dirty_list); - if (x) { - rotateby = pseudo_random % x; - D1(printk(KERN_DEBUG "Rotating dirty_list by %d\n", rotateby)); - - rotate_list((&c->dirty_list), rotateby); - - D1(printk(KERN_DEBUG "Erase block at front of dirty_list is at %08x\n", - list_entry(c->dirty_list.next, struct jffs2_eraseblock, list)->offset)); - } else { - D1(printk(KERN_DEBUG "Not rotating empty dirty_list\n")); - } - - x = count_list(&c->erasable_list); - if (x) { - rotateby = pseudo_random % x; - D1(printk(KERN_DEBUG "Rotating erasable_list by %d\n", rotateby)); - - rotate_list((&c->erasable_list), rotateby); - - D1(printk(KERN_DEBUG "Erase block at front of erasable_list is at %08x\n", - list_entry(c->erasable_list.next, struct jffs2_eraseblock, list)->offset)); - } else { - D1(printk(KERN_DEBUG "Not rotating empty erasable_list\n")); - } - - if (c->nr_erasing_blocks) { - rotateby = pseudo_random % c->nr_erasing_blocks; - D1(printk(KERN_DEBUG "Rotating erase_pending_list by %d\n", rotateby)); - - rotate_list((&c->erase_pending_list), rotateby); - - D1(printk(KERN_DEBUG "Erase block at front of erase_pending_list is at %08x\n", - list_entry(c->erase_pending_list.next, struct jffs2_eraseblock, list)->offset)); - } else { - D1(printk(KERN_DEBUG "Not rotating empty erase_pending_list\n")); - } - - if (c->nr_free_blocks) { - rotateby = pseudo_random % c->nr_free_blocks; - D1(printk(KERN_DEBUG "Rotating free_list by %d\n", rotateby)); - - rotate_list((&c->free_list), rotateby); - - D1(printk(KERN_DEBUG "Erase block at front of free_list is at %08x\n", - list_entry(c->free_list.next, struct jffs2_eraseblock, list)->offset)); - } else { - D1(printk(KERN_DEBUG "Not rotating empty free_list\n")); - } -} diff --git a/components/dfs/filesystems/jffs2/src/write.c b/components/dfs/filesystems/jffs2/src/write.c deleted file mode 100644 index dcfc3a49c1..0000000000 --- a/components/dfs/filesystems/jffs2/src/write.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * JFFS2 -- Journalling Flash File System, Version 2. - * - * Copyright (C) 2001-2003 Red Hat, Inc. - * - * Created by David Woodhouse <[email protected]> - * - * For licensing information, see the file 'LICENCE' in this directory. - * - * $Id: write.c,v 1.94 2005/07/20 15:50:51 dedekind Exp $ - * - */ - -#include <linux/kernel.h> -#include <linux/fs.h> -#include <linux/crc32.h> -#include <linux/slab.h> -#include <linux/pagemap.h> -#include <linux/mtd/mtd.h> -#include "nodelist.h" -#include "compr.h" - - -int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri) -{ - struct jffs2_inode_cache *ic; - - ic = jffs2_alloc_inode_cache(); - if (!ic) { - return -ENOMEM; - } - - memset(ic, 0, sizeof(*ic)); - - f->inocache = ic; - f->inocache->nlink = 1; - f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; - f->inocache->state = INO_STATE_PRESENT; - - - jffs2_add_ino_cache(c, f->inocache); - D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino)); - ri->ino = cpu_to_je32(f->inocache->ino); - - ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); - ri->totlen = cpu_to_je32(PAD(sizeof(*ri))); - ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); - ri->mode = cpu_to_jemode(mode); - - f->highest_version = 1; - ri->version = cpu_to_je32(f->highest_version); - - return 0; -} - -/* jffs2_write_dnode - given a raw_inode, allocate a full_dnode for it, - write it to the flash, link it into the existing inode/fragment list */ - -struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const unsigned char *data, uint32_t datalen, uint32_t flash_ofs, int alloc_mode) - -{ - struct jffs2_raw_node_ref *raw; - struct jffs2_full_dnode *fn; - size_t retlen; - struct kvec vecs[2]; - int ret; - int retried = 0; - unsigned long cnt = 2; - - D1(if(je32_to_cpu(ri->hdr_crc) != crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)) { - printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dnode()\n"); - BUG(); - } - ); - vecs[0].iov_base = ri; - vecs[0].iov_len = sizeof(*ri); - vecs[1].iov_base = (unsigned char *)data; - vecs[1].iov_len = datalen; - - jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); - - if (je32_to_cpu(ri->totlen) != sizeof(*ri) + datalen) { - printk(KERN_WARNING "jffs2_write_dnode: ri->totlen (0x%08x) != sizeof(*ri) (0x%08zx) + datalen (0x%08x)\n", je32_to_cpu(ri->totlen), sizeof(*ri), datalen); - } - raw = jffs2_alloc_raw_node_ref(); - if (!raw) - return ERR_PTR(-ENOMEM); - - fn = jffs2_alloc_full_dnode(); - if (!fn) { - jffs2_free_raw_node_ref(raw); - return ERR_PTR(-ENOMEM); - } - - fn->ofs = je32_to_cpu(ri->offset); - fn->size = je32_to_cpu(ri->dsize); - fn->frags = 0; - - /* check number of valid vecs */ - if (!datalen || !data) - cnt = 1; - retry: - fn->raw = raw; - - raw->flash_offset = flash_ofs; - raw->__totlen = PAD(sizeof(*ri)+datalen); - raw->next_phys = NULL; - - if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) { - BUG_ON(!retried); - D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, " - "highest version %d -> updating dnode\n", - je32_to_cpu(ri->version), f->highest_version)); - ri->version = cpu_to_je32(++f->highest_version); - ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); - } - - ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen, - (alloc_mode==ALLOC_GC)?0:f->inocache->ino); - - if (ret || (retlen != sizeof(*ri) + datalen)) { - printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", - sizeof(*ri)+datalen, flash_ofs, ret, retlen); - - /* Mark the space as dirtied */ - if (retlen) { - /* Doesn't belong to any inode */ - raw->next_in_ino = NULL; - - /* Don't change raw->size to match retlen. We may have - written the node header already, and only the data will - seem corrupted, in which case the scan would skip over - any node we write before the original intended end of - this node */ - raw->flash_offset |= REF_OBSOLETE; - jffs2_add_physical_node_ref(c, raw); - jffs2_mark_node_obsolete(c, raw); - } else { - printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); - jffs2_free_raw_node_ref(raw); - } - if (!retried && alloc_mode != ALLOC_NORETRY && (raw = jffs2_alloc_raw_node_ref())) { - /* Try to reallocate space and retry */ - uint32_t dummy; - struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; - - retried = 1; - - D1(printk(KERN_DEBUG "Retrying failed write.\n")); - - jffs2_dbg_acct_sanity_check(c,jeb); - jffs2_dbg_acct_paranoia_check(c, jeb); - - if (alloc_mode == ALLOC_GC) { - ret = jffs2_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy); - } else { - /* Locking pain */ - up(&f->sem); - jffs2_complete_reservation(c); - - ret = jffs2_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode); - down(&f->sem); - } - - if (!ret) { - D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); - - jffs2_dbg_acct_sanity_check(c,jeb); - jffs2_dbg_acct_paranoia_check(c, jeb); - - goto retry; - } - D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); - jffs2_free_raw_node_ref(raw); - } - /* Release the full_dnode which is now useless, and return */ - jffs2_free_full_dnode(fn); - return ERR_PTR(ret?ret:-EIO); - } - /* Mark the space used */ - /* If node covers at least a whole page, or if it starts at the - beginning of a page and runs to the end of the file, or if - it's a hole node, mark it REF_PRISTINE, else REF_NORMAL. - */ - if ((je32_to_cpu(ri->dsize) >= PAGE_CACHE_SIZE) || - ( ((je32_to_cpu(ri->offset)&(PAGE_CACHE_SIZE-1))==0) && - (je32_to_cpu(ri->dsize)+je32_to_cpu(ri->offset) == je32_to_cpu(ri->isize)))) { - raw->flash_offset |= REF_PRISTINE; - } else { - raw->flash_offset |= REF_NORMAL; - } - jffs2_add_physical_node_ref(c, raw); - - /* Link into per-inode list */ - spin_lock(&c->erase_completion_lock); - raw->next_in_ino = f->inocache->nodes; - f->inocache->nodes = raw; - spin_unlock(&c->erase_completion_lock); - - D1(printk(KERN_DEBUG "jffs2_write_dnode wrote node at 0x%08x(%d) with dsize 0x%x, csize 0x%x, node_crc 0x%08x, data_crc 0x%08x, totlen 0x%08x\n", - flash_ofs, ref_flags(raw), je32_to_cpu(ri->dsize), - je32_to_cpu(ri->csize), je32_to_cpu(ri->node_crc), - je32_to_cpu(ri->data_crc), je32_to_cpu(ri->totlen))); - - if (retried) { - jffs2_dbg_acct_sanity_check(c,NULL); - } - - return fn; -} - -struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jffs2_inode_info *f, struct jffs2_raw_dirent *rd, const unsigned char *name, uint32_t namelen, uint32_t flash_ofs, int alloc_mode) -{ - struct jffs2_raw_node_ref *raw; - struct jffs2_full_dirent *fd; - size_t retlen; - struct kvec vecs[2]; - int retried = 0; - int ret; - - D1(printk(KERN_DEBUG "jffs2_write_dirent(ino #%u, name at *0x%p \"%s\"->ino #%u, name_crc 0x%08x)\n", - je32_to_cpu(rd->pino), name, name, je32_to_cpu(rd->ino), - je32_to_cpu(rd->name_crc))); - - D1(if(je32_to_cpu(rd->hdr_crc) != crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)) { - printk(KERN_CRIT "Eep. CRC not correct in jffs2_write_dirent()\n"); - BUG(); - } - ); - - vecs[0].iov_base = rd; - vecs[0].iov_len = sizeof(*rd); - vecs[1].iov_base = (unsigned char *)name; - vecs[1].iov_len = namelen; - - jffs2_dbg_prewrite_paranoia_check(c, flash_ofs, vecs[0].iov_len + vecs[1].iov_len); - - raw = jffs2_alloc_raw_node_ref(); - - if (!raw) - return ERR_PTR(-ENOMEM); - - fd = jffs2_alloc_full_dirent(namelen+1); - if (!fd) { - jffs2_free_raw_node_ref(raw); - return ERR_PTR(-ENOMEM); - } - - fd->version = je32_to_cpu(rd->version); - fd->ino = je32_to_cpu(rd->ino); - fd->nhash = full_name_hash(name, strlen((const char *)name)); - fd->type = rd->type; - memcpy(fd->name, name, namelen); - fd->name[namelen]=0; - - retry: - fd->raw = raw; - - raw->flash_offset = flash_ofs; - raw->__totlen = PAD(sizeof(*rd)+namelen); - raw->next_phys = NULL; - - if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) { - BUG_ON(!retried); - D1(printk(KERN_DEBUG "jffs2_write_dirent : dirent_version %d, " - "highest version %d -> updating dirent\n", - je32_to_cpu(rd->version), f->highest_version)); - rd->version = cpu_to_je32(++f->highest_version); - fd->version = je32_to_cpu(rd->version); - rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); - } - - ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, - (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); - if (ret || (retlen != sizeof(*rd) + namelen)) { - printk(KERN_NOTICE "Write of %zd bytes at 0x%08x failed. returned %d, retlen %zd\n", - sizeof(*rd)+namelen, flash_ofs, ret, retlen); - /* Mark the space as dirtied */ - if (retlen) { - raw->next_in_ino = NULL; - raw->flash_offset |= REF_OBSOLETE; - jffs2_add_physical_node_ref(c, raw); - jffs2_mark_node_obsolete(c, raw); - } else { - printk(KERN_NOTICE "Not marking the space at 0x%08x as dirty because the flash driver returned retlen zero\n", raw->flash_offset); - jffs2_free_raw_node_ref(raw); - } - if (!retried && (raw = jffs2_alloc_raw_node_ref())) { - /* Try to reallocate space and retry */ - uint32_t dummy; - struct jffs2_eraseblock *jeb = &c->blocks[flash_ofs / c->sector_size]; - - retried = 1; - - D1(printk(KERN_DEBUG "Retrying failed write.\n")); - - jffs2_dbg_acct_sanity_check(c,jeb); - jffs2_dbg_acct_paranoia_check(c, jeb); - - if (alloc_mode == ALLOC_GC) { - ret = jffs2_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy); - } else { - /* Locking pain */ - up(&f->sem); - jffs2_complete_reservation(c); - - ret = jffs2_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode); - down(&f->sem); - } - - if (!ret) { - D1(printk(KERN_DEBUG "Allocated space at 0x%08x to retry failed write.\n", flash_ofs)); - jffs2_dbg_acct_sanity_check(c,jeb); - jffs2_dbg_acct_paranoia_check(c, jeb); - goto retry; - } - D1(printk(KERN_DEBUG "Failed to allocate space to retry failed write: %d!\n", ret)); - jffs2_free_raw_node_ref(raw); - } - /* Release the full_dnode which is now useless, and return */ - jffs2_free_full_dirent(fd); - return ERR_PTR(ret?ret:-EIO); - } - /* Mark the space used */ - raw->flash_offset |= REF_PRISTINE; - jffs2_add_physical_node_ref(c, raw); - - spin_lock(&c->erase_completion_lock); - raw->next_in_ino = f->inocache->nodes; - f->inocache->nodes = raw; - spin_unlock(&c->erase_completion_lock); - - if (retried) { - jffs2_dbg_acct_sanity_check(c,NULL); - } - - return fd; -} - -/* The OS-specific code fills in the metadata in the jffs2_raw_inode for us, so that - we don't have to go digging in struct inode or its equivalent. It should set: - mode, uid, gid, (starting)isize, atime, ctime, mtime */ -int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, - struct jffs2_raw_inode *ri, unsigned char *buf, - uint32_t offset, uint32_t writelen, uint32_t *retlen) -{ - int ret = 0; - uint32_t writtenlen = 0; - - D1(printk(KERN_DEBUG "jffs2_write_inode_range(): Ino #%u, ofs 0x%x, len 0x%x\n", - f->inocache->ino, offset, writelen)); - - while(writelen) { - struct jffs2_full_dnode *fn; - unsigned char *comprbuf = NULL; - uint16_t comprtype = JFFS2_COMPR_NONE; - uint32_t phys_ofs, alloclen; - uint32_t datalen, cdatalen; - int retried = 0; - - retry: - D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset)); - - ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL); - if (ret) { - D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret)); - break; - } - down(&f->sem); - datalen = min_t(uint32_t, writelen, PAGE_CACHE_SIZE - (offset & (PAGE_CACHE_SIZE-1))); - cdatalen = min_t(uint32_t, alloclen - sizeof(*ri), datalen); - - comprtype = jffs2_compress(c, f, buf, &comprbuf, &datalen, &cdatalen); - - ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); - ri->totlen = cpu_to_je32(sizeof(*ri) + cdatalen); - ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); - - ri->ino = cpu_to_je32(f->inocache->ino); - ri->version = cpu_to_je32(++f->highest_version); - ri->isize = cpu_to_je32(max(je32_to_cpu(ri->isize), offset + datalen)); - ri->offset = cpu_to_je32(offset); - ri->csize = cpu_to_je32(cdatalen); - ri->dsize = cpu_to_je32(datalen); - ri->compr = comprtype & 0xff; - ri->usercompr = (comprtype >> 8 ) & 0xff; - ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); - ri->data_crc = cpu_to_je32(crc32(0, comprbuf, cdatalen)); - - fn = jffs2_write_dnode(c, f, ri, comprbuf, cdatalen, phys_ofs, ALLOC_NORETRY); - - jffs2_free_comprbuf(comprbuf, buf); - - if (IS_ERR(fn)) { - ret = PTR_ERR(fn); - up(&f->sem); - jffs2_complete_reservation(c); - if (!retried) { - /* Write error to be retried */ - retried = 1; - D1(printk(KERN_DEBUG "Retrying node write in jffs2_write_inode_range()\n")); - goto retry; - } - break; - } - ret = jffs2_add_full_dnode_to_inode(c, f, fn); - if (f->metadata) { - jffs2_mark_node_obsolete(c, f->metadata->raw); - jffs2_free_full_dnode(f->metadata); - f->metadata = NULL; - } - if (ret) { - /* Eep */ - D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret)); - jffs2_mark_node_obsolete(c, fn->raw); - jffs2_free_full_dnode(fn); - - up(&f->sem); - jffs2_complete_reservation(c); - break; - } - up(&f->sem); - jffs2_complete_reservation(c); - if (!datalen) { - printk(KERN_WARNING "Eep. We didn't actually write any data in jffs2_write_inode_range()\n"); - ret = -EIO; - break; - } - D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen)); - writtenlen += datalen; - offset += datalen; - writelen -= datalen; - buf += datalen; - } - *retlen = writtenlen; - return ret; -} - -int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen) -{ - struct jffs2_raw_dirent *rd; - struct jffs2_full_dnode *fn; - struct jffs2_full_dirent *fd; - uint32_t alloclen, phys_ofs; - int ret; - - /* Try to reserve enough space for both node and dirent. - * Just the node will do for now, though - */ - ret = jffs2_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL); - D1(printk(KERN_DEBUG "jffs2_do_create(): reserved 0x%x bytes\n", alloclen)); - if (ret) { - up(&f->sem); - return ret; - } - - ri->data_crc = cpu_to_je32(0); - ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); - - fn = jffs2_write_dnode(c, f, ri, NULL, 0, phys_ofs, ALLOC_NORMAL); - - D1(printk(KERN_DEBUG "jffs2_do_create created file with mode 0x%x\n", - jemode_to_cpu(ri->mode))); - - if (IS_ERR(fn)) { - D1(printk(KERN_DEBUG "jffs2_write_dnode() failed\n")); - /* Eeek. Wave bye bye */ - up(&f->sem); - jffs2_complete_reservation(c); - return PTR_ERR(fn); - } - /* No data here. Only a metadata node, which will be - obsoleted by the first data write - */ - f->metadata = fn; - - up(&f->sem); - jffs2_complete_reservation(c); - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); - - if (ret) { - /* Eep. */ - D1(printk(KERN_DEBUG "jffs2_reserve_space() for dirent failed\n")); - return ret; - } - - rd = jffs2_alloc_raw_dirent(); - if (!rd) { - /* Argh. Now we treat it like a normal delete */ - jffs2_complete_reservation(c); - return -ENOMEM; - } - - down(&dir_f->sem); - - rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); - rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); - rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); - - rd->pino = cpu_to_je32(dir_f->inocache->ino); - rd->version = cpu_to_je32(++dir_f->highest_version); - rd->ino = ri->ino; - rd->mctime = ri->ctime; - rd->nsize = namelen; - rd->type = DT_REG; - rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); - rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); - - fd = jffs2_write_dirent(c, dir_f, rd, (const unsigned char *)name, namelen, phys_ofs, ALLOC_NORMAL); - - jffs2_free_raw_dirent(rd); - - if (IS_ERR(fd)) { - /* dirent failed to write. Delete the inode normally - as if it were the final unlink() */ - jffs2_complete_reservation(c); - up(&dir_f->sem); - return PTR_ERR(fd); - } - - /* Link the fd into the inode's list, obsoleting an old - one if necessary. */ - jffs2_add_fd_to_list(c, fd, &dir_f->dents); - - jffs2_complete_reservation(c); - up(&dir_f->sem); - - return 0; -} - - -int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, - const char *name, int namelen, struct jffs2_inode_info *dead_f) -{ - struct jffs2_raw_dirent *rd; - struct jffs2_full_dirent *fd; - uint32_t alloclen, phys_ofs; - int ret; - - if (1 /* alternative branch needs testing */ || - !jffs2_can_mark_obsolete(c)) { - /* We can't mark stuff obsolete on the medium. We need to write a deletion dirent */ - - rd = jffs2_alloc_raw_dirent(); - if (!rd) - return -ENOMEM; - - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION); - if (ret) { - jffs2_free_raw_dirent(rd); - return ret; - } - - down(&dir_f->sem); - - /* Build a deletion node */ - rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); - rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); - rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); - - rd->pino = cpu_to_je32(dir_f->inocache->ino); - rd->version = cpu_to_je32(++dir_f->highest_version); - rd->ino = cpu_to_je32(0); - rd->mctime = cpu_to_je32(get_seconds()); - rd->nsize = namelen; - rd->type = DT_UNKNOWN; - rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); - rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); - - fd = jffs2_write_dirent(c, dir_f, rd, (const unsigned char *)name, namelen, phys_ofs, ALLOC_DELETION); - - jffs2_free_raw_dirent(rd); - - if (IS_ERR(fd)) { - jffs2_complete_reservation(c); - up(&dir_f->sem); - return PTR_ERR(fd); - } - - /* File it. This will mark the old one obsolete. */ - jffs2_add_fd_to_list(c, fd, &dir_f->dents); - up(&dir_f->sem); - } else { - struct jffs2_full_dirent **prev = &dir_f->dents; - uint32_t nhash = full_name_hash((const unsigned char *)name, namelen); - - down(&dir_f->sem); - - while ((*prev) && (*prev)->nhash <= nhash) { - if ((*prev)->nhash == nhash && - !memcmp((*prev)->name, name, namelen) && - !(*prev)->name[namelen]) { - struct jffs2_full_dirent *this = *prev; - - D1(printk(KERN_DEBUG "Marking old dirent node (ino #%u) @%08x obsolete\n", - this->ino, ref_offset(this->raw))); - - *prev = this->next; - jffs2_mark_node_obsolete(c, (this->raw)); - jffs2_free_full_dirent(this); - break; - } - prev = &((*prev)->next); - } - up(&dir_f->sem); - } - - /* dead_f is NULL if this was a rename not a real unlink */ - /* Also catch the !f->inocache case, where there was a dirent - pointing to an inode which didn't exist. */ - if (dead_f && dead_f->inocache) { - - down(&dead_f->sem); - - if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) { - while (dead_f->dents) { - /* There can be only deleted ones */ - fd = dead_f->dents; - - dead_f->dents = fd->next; - - if (fd->ino) { - printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", - dead_f->inocache->ino, fd->name, fd->ino); - } else { - D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", - fd->name, dead_f->inocache->ino)); - } - jffs2_mark_node_obsolete(c, fd->raw); - jffs2_free_full_dirent(fd); - } - } - - dead_f->inocache->nlink--; - /* NB: Caller must set inode nlink if appropriate */ - up(&dead_f->sem); - } - - jffs2_complete_reservation(c); - - return 0; -} - - -int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen) -{ - struct jffs2_raw_dirent *rd; - struct jffs2_full_dirent *fd; - uint32_t alloclen, phys_ofs; - int ret; - - rd = jffs2_alloc_raw_dirent(); - if (!rd) - return -ENOMEM; - - ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL); - if (ret) { - jffs2_free_raw_dirent(rd); - return ret; - } - - down(&dir_f->sem); - - /* Build a deletion node */ - rd->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); - rd->nodetype = cpu_to_je16(JFFS2_NODETYPE_DIRENT); - rd->totlen = cpu_to_je32(sizeof(*rd) + namelen); - rd->hdr_crc = cpu_to_je32(crc32(0, rd, sizeof(struct jffs2_unknown_node)-4)); - - rd->pino = cpu_to_je32(dir_f->inocache->ino); - rd->version = cpu_to_je32(++dir_f->highest_version); - rd->ino = cpu_to_je32(ino); - rd->mctime = cpu_to_je32(get_seconds()); - rd->nsize = namelen; - - rd->type = type; - - rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); - rd->name_crc = cpu_to_je32(crc32(0, name, namelen)); - - fd = jffs2_write_dirent(c, dir_f, rd, (const unsigned char *)name, namelen, phys_ofs, ALLOC_NORMAL); - - jffs2_free_raw_dirent(rd); - - if (IS_ERR(fd)) { - jffs2_complete_reservation(c); - up(&dir_f->sem); - return PTR_ERR(fd); - } - - /* File it. This will mark the old one obsolete. */ - jffs2_add_fd_to_list(c, fd, &dir_f->dents); - - jffs2_complete_reservation(c); - up(&dir_f->sem); - - return 0; -} diff --git a/components/dfs/filesystems/uffs/AUTHORS b/components/dfs/filesystems/uffs/AUTHORS deleted file mode 100644 index adaedefb4f..0000000000 --- a/components/dfs/filesystems/uffs/AUTHORS +++ /dev/null @@ -1 +0,0 @@ -Ricky Zheng <[email protected]> diff --git a/components/dfs/filesystems/uffs/CMakeLists.txt b/components/dfs/filesystems/uffs/CMakeLists.txt deleted file mode 100644 index cc36f060e1..0000000000 --- a/components/dfs/filesystems/uffs/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.6 ) -PROJECT( uffs ) - -SET(CMAKE_CXX_FLAGS_VGL "-O0 -g") -SET(CMAKE_C_FLAGS_VGL "-O0 -g") - -SET(CMAKE_C_FLAGS_GCOV "-g -O0 -Wall -fprofile-arcs -ftest-coverage") -SET(CMAKE_CXX_FLAGS_GCOV "-g -O0 -Wall -fprofile-arcs -ftest-coverage") -SET(CMAKE_EXE_LINKER_FLAGS_GCOV "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -lgcov") - -IF (CMAKE_COMPILER_IS_GNUCC) -IF (APPLE) - SET(CMAKE_CXX_FLAGS "-fPIC -Wall -Werror -g -rdynamic") - SET(CMAKE_C_FLAGS "-fPIC -Wall -Werror -g -rdynamic") -ELSE () - SET(CMAKE_CXX_FLAGS "-fPIC -Wall -Werror -Wclobbered -Wempty-body -Wignored-qualifiers -Wmissing-parameter-type -Woverride-init -Wtype-limits -Wuninitialized -g -rdynamic") - SET(CMAKE_C_FLAGS "-fPIC -Wall -Werror -Wclobbered -Wempty-body -Wignored-qualifiers -Wmissing-parameter-type -Woverride-init -Wtype-limits -Wuninitialized -g -rdynamic") -ENDIF() -ENDIF() - -IF (UNIX) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNIX") - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUNIX") -ENDIF() - -ADD_SUBDIRECTORY( src ) - diff --git a/components/dfs/filesystems/uffs/COPYING b/components/dfs/filesystems/uffs/COPYING deleted file mode 100644 index d511905c16..0000000000 --- a/components/dfs/filesystems/uffs/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - <one line to give the program's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - <signature of Ty Coon>, 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/components/dfs/filesystems/uffs/Doxyfile b/components/dfs/filesystems/uffs/Doxyfile deleted file mode 100644 index f46a4c0af1..0000000000 --- a/components/dfs/filesystems/uffs/Doxyfile +++ /dev/null @@ -1,275 +0,0 @@ -# Doxyfile 1.4.1-KDevelop - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = uffs-doc -PROJECT_NUMBER = 0.1 -OUTPUT_DIRECTORY = doc/doxygen-doc -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = ./ -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -DISTRIBUTE_GROUP_DOC = NO -TAB_SIZE = 4 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = YES -OPTIMIZE_OUTPUT_JAVA = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = NO -EXTRACT_LOCAL_METHODS = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = YES -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = YES -CASE_SENSE_NAMES = NO -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = YES -SORT_BY_SCOPE_NAME = YES -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = YES -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = ./src -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.C \ - *.CC \ - *.C++ \ - *.II \ - *.I++ \ - *.H \ - *.HH \ - *.H++ \ - *.CS \ - *.PHP \ - *.PHP3 \ - *.M \ - *.MM \ - *.C \ - *.H \ - *.tlh \ - *.diff \ - *.patch \ - *.moc \ - *.xpm \ - *.dox -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -VERBATIM_HEADERS = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = YES -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = uffs.tag -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = NO -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/components/dfs/filesystems/uffs/README b/components/dfs/filesystems/uffs/README deleted file mode 100644 index 0828cf134c..0000000000 --- a/components/dfs/filesystems/uffs/README +++ /dev/null @@ -1,275 +0,0 @@ -UFFS: Ultra-low-cost Flash File System - -Project: http://uffs.sf.net/ -Blog: http://all-about-uffs.blogspot.com/ -Q/A: http://groups.google.com/group/uffs/ - -Author: Ricky Zheng <[email protected]> - -INTRODUCTION ------------- - -UFFS is a nand flash file system designed for embedded system. - -UFFS have some unique and advanced features: - * Low cost: e.g. it needs only 41K bytes RAM for 64MB NAND flash (page size 2048). - - * Fast booting: it reads only a few spares from each block, typically - mounting a fully filled file system (Gbits) within one second. - - * Superb Reliability: - - The file system is designed for the embedded system which may - frequently lost power/reset without care. - - Journal file system, the file system will automatically rollback - to the last state when lost power on the middle of flash programing. - - When 'write' return without error, the data is guarenteed been - saved on flash. - - * Fast file create/read/write/seek. - * Bad-block tolerant, ECC enable and good ware-leveling. - * There is no garbage collection needed for UFFS. - * Support multiple NAND flash class in one system. - * Support bare flash hardware, no operating system needed. - * Support static memory allocation (works without 'malloc'). - * Fully simulated on PC (Windows/Linux) platform. - -Disadvantage: - * space inefficency for small files: UFFS use at least one - 'block'(the minial erase unit for NAND flash, e.g. 16K ) for a file. - * maximum supported blocks: 2^16 = 65535 - -Memory consuming example: - For page size = 512: - [VARY]Tree nodes: 16 * total_blocks - [CONST]Page Bufs: MAX_CACHED_BUFFERS(10) * (40 + pageSize(512)) = 5.4K - [CONST]Block Info caches: (24 + 14 * pages_per_block (32)) * MAX_CACHED_BLOCK_INFO (10) = 4.6K - - Example 1: 128M bytes NAND, 8192 blocks, total memory cost: - (16 * 8192)128K + 5.4K + 4.6K = 138K bytes. - - Example 2: 32M Bytes NAND, 2048 blocks, total memory cost: - (16 * 2048)32K + 5.4K + 4.6K = 42K bytes. - - Example 3: 16M bytes NAND, 1024 blocks, total memory cost: - (16 * 1024)16K + 5.4K + 4.6K = 26K bytes. - - For page size = 2048: - [VARY]Tree nodes: 16 * total_blocks - [CONST]Page Bufs: MAX_CACHED_BUFFERS(10) * (40 + pageSize(2048)) = 20.4K - [CONST]Block Info caches: (24 + 14 * pages_per_block (32)) * MAX_CACHED_BLOCK_INFO (10) = 4.6K - - Example 1: 512M bytes NAND, 8192 blocks, total memory cost: - (16 * 8192)128K + 20.4K + 4.6K = 153K bytes. - - Example 2: 128M Bytes NAND, 2048 blocks, total memory cost: - (16 * 2048)32K + 20.4K + 4.6K = 57K bytes. - - Example 3: 64M bytes NAND, 1024 blocks, total memory cost: - (16 * 1024)16K + 20.4K + 4.6K = 41K bytes. - - -BUILD SIMULATOR REQUIREMENT ---------------------------- -From V1.2.0, build uffs simulator requires 'cmake'. -'cmake' can be downloaded from: http://www.cmake.org/ - -or, under Debian/Ubuntu: - sudo apt-get install cmake - -BUILD SIMULATOR ON LINUX ------------------------- -1) create a 'build' dir: - -mkdir -p ~/build/uffs - -2) create Makefiles and build: - cd ~/build/uffs - cmake <path_to_uffs> - make - -5) run simulator (interactive mode): - src/utils/mkuffs - - -BUILD SIMULATOR ON WINDOWS --------------------------- - -1) create a 'build' dir along with uffs source dir, - d:\build\uffs - -2) Create VC project files: - cd build\uffs - cmake <path_to_uffs> - -3) Open uffs.dsw (or uffs.sln for VC > 6 ), compile & run. - - -LATEST SOURCE CODE ------------------- -You can get the latest source code from git repository: - git clone git://uffs.git.sourceforge.net/gitroot/uffs/uffs - - -CURRENT STATUS --------------- -UFFS 0.1.x is a working version on PC simulator, also has been ported to -uBase embedded OS as a 'real world' product for thousands of copies, -it works fine so far. - -UFFS 0.2.0 implementes full directory. - -UFFS 1.0.0 is the first stable release at sf.net. - -UFFS 1.1.0: support NAND flash with large page size (up to 2K). - -UFFS 1.1.1: bug fixes. a tool for making uffs disk image. - -UFFS 1.1.2: bug fixes. add more Flash Class. change Licence from GNU GPLv2 to GNU LGPLv2 - -UFFS 1.2.0: - - eliminate 'current path' and relatives. Now you should use absolute path in all - uffs APIs. For dir, the fullname should end with '/'. - - allow using static memory allocation, 'malloc' is no longer needed. - - using cmake for building simulator. - - bug fixes & minor changes. - -UFFS 1.2.1: - - improve bad block management - - bug fixes - - change Licence to modified GNU GPLv2. - -UFFS 1.3.0: - - improved flash interface - - support hardware ECC - - support user defined spare layout (for customized NAND flash controller) - - support 4K page size - - no partial page program required, support MLC NAND flash - - reduced buffer flushes by grouping buffers - - structual improvments and bug fixes - -UFFS v1.3.1: - - Tidy up three memory allocators: static, native and system. - - Fix bugs in flash interface example. - - Fix memory allocation bugs when using static memory allocator. - - Add flash driver interface 'WriteFullPage()'. - - Fix compilation errors for BlackFin DSP compiler. - -UFFS v1.3.2: - - Add POSIX like file system APIs. - - Bug fixes. - -UFFS v1.3.3: - - Change Flash Interface, simplify interface. - - Improved bad block handling. - - Better support for MLC NAND flash. - - Added hardware ECC and RS-ECC controller emulator. - - Bug fixes. - -UFFS v1.3.4 - - New UO_NOECC option for skipping ECC (fast reading). - - POSIX compliance uffs_seek(). - - Improved unclean page detection (add new 'seal' byte in spare area). - - Optional page data CRC. - - Bug fixes. - - Other improvements. - -LICENCE -------- - From v1.2.1, UFFS is released under a modified GNU GPLv2. (the same as eCos Licence) - The full licence text can be found in the header of source files: - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. - - -TESTING UFFS WITH SQLITE3 REGRESSION TEST CASES ------------------------------------------------ -UFFS can be tested with sqlite3 regression test cases (on Linux). - -1) install tcl8.5-dev on host PC: - apt-get install tcl8.5 tcl8.5-dev - - # make sure your Linux is using tcl8.5 as the default tclsh: - sudo update-alternatives --config tclsh - (select "tclsh8.5" from the list.) - -2) build uffs: - mkdir -p ~/build/uffs - cd ~/build/uffs - cmake <path_to_uffs> - -3) build sqlite3: - cd <path_to_uffs>/src/test/sqlite3/sqlite-src-3070900 - ./configure # create some build support files - git checkout -f Makefile config.h # restore modified Makefile and config.h - make test # start build 'testfixture' program. - - # now you'll see something like: - Connect: Connection refused - Assert (uffs_ret == ret && ret == bak_ret) fail at /home/.../src/test/api_test/os_uffs.c:os_unlink:329: unlink("/home/.../src/test/sqlite3/sqlite-src-3070900/./test.db-journal"), unix return 0, uffs return -1, bak return -1 - make: *** [test] Error 1 - -4) run test cases: - Open two terminals. - on termional A: - cd ~/build/uffs - src/utils/mkuffs -t 1024 - - #on uffs simulator command line, enter: - format / - apisrv - - on terminal B: - cd <path_to_uffs>/src/test/sqlite3/sqlite-src-3070900 - ./test-uffs.sh - - Note: if you want to run mkuffs on another PC, for example, a Windows PC, you need to specify the IP address in test-uffs.sh. - - The test will take 1~4 hours, depends on how fast your Linux box is. - - -ACKNOWLEDGMENT ---------------- -Special thanks for your contributions to: -(list in no particular order) - -* Chen Jun <[email protected]> -* Michail <[email protected]> -* Sjpu <[email protected]> -* RobertGray <[email protected]> -* Dongbo <[email protected]> -* Cag <[email protected]> -* Sergey <[email protected]> -* Chris Conrad <[email protected]> -* Vladimir <[email protected]> -* Thien Pham <[email protected]> -* Emmanuel Blot <[email protected]> -* Michael <[email protected]> -* Mick D <[email protected]> -* Paul <[email protected]> -* Rogerz <[email protected]> - - diff --git a/components/dfs/filesystems/uffs/SConscript b/components/dfs/filesystems/uffs/SConscript deleted file mode 100644 index 53f7713fc2..0000000000 --- a/components/dfs/filesystems/uffs/SConscript +++ /dev/null @@ -1,38 +0,0 @@ -# RT-Thread building script for component - -from building import * - -cwd = GetCurrentDir() - -src = Glob('*.c') - -uffs = Split(''' -src/uffs/uffs_badblock.c -src/uffs/uffs_blockinfo.c -src/uffs/uffs_buf.c -src/uffs/uffs_debug.c -src/uffs/uffs_device.c -src/uffs/uffs_ecc.c -src/uffs/uffs_crc.c -src/uffs/uffs_fd.c -src/uffs/uffs_find.c -src/uffs/uffs_flash.c -src/uffs/uffs_fs.c -src/uffs/uffs_init.c -src/uffs/uffs_mem.c -src/uffs/uffs_mtb.c -src/uffs/uffs_pool.c -src/uffs/uffs_public.c -src/uffs/uffs_tree.c -src/uffs/uffs_utils.c -src/uffs/uffs_version.c - -''') - -src = src + uffs - -CPPPATH = [cwd, cwd + '/src/inc'] - -group = DefineGroup('Filesystem', src , depend = ['RT_USING_DFS', 'RT_USING_DFS_UFFS'], CPPPATH = CPPPATH) - -Return('group') diff --git a/components/dfs/filesystems/uffs/TODO b/components/dfs/filesystems/uffs/TODO deleted file mode 100644 index bf6b4fb66a..0000000000 --- a/components/dfs/filesystems/uffs/TODO +++ /dev/null @@ -1,5 +0,0 @@ -TODO list for v1.3: - -* New API: int uffs_SkipObject(uffs_Object *obj, int size); -* Introduce buffer group -* Interface to Linux MTD diff --git a/components/dfs/filesystems/uffs/dfs_uffs.c b/components/dfs/filesystems/uffs/dfs_uffs.c deleted file mode 100644 index fb8caf9dd7..0000000000 --- a/components/dfs/filesystems/uffs/dfs_uffs.c +++ /dev/null @@ -1,660 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2011-10-22 prife the first version - * 2012-03-28 prife use mtd device interface - * 2012-04-05 prife update uffs with official repo and use uffs_UnMount/Mount - * 2017-04-12 lizhen9880 fix the f_bsize and f_blocks issue in function dfs_uffs_statfs - */ - -#include <rtthread.h> - -#include <dfs_fs.h> -#include <dfs_file.h> -#include <rtdevice.h> - -#include "dfs_uffs.h" - -#include "uffs/uffs_fd.h" /* posix file api is here */ -#include "uffs/uffs_mtb.h" -#include "uffs/uffs_mem.h" -#include "uffs/uffs_utils.h" - -/* - * RT-Thread DFS Interface for uffs - */ -#define UFFS_DEVICE_MAX 2 /* the max partions on a nand deivce*/ -#define UFFS_MOUNT_PATH_MAX 128 /* the mount point max length */ -#define FILE_PATH_MAX 256 /* the longest file path */ - -struct _nand_dev -{ - struct rt_mtd_nand_device *dev; - struct uffs_StorageAttrSt storage; - uffs_Device uffs_dev; - uffs_MountTable mount_table; - char mount_path[UFFS_MOUNT_PATH_MAX]; - void *data; /* when uffs use static buf, it will save ptr here */ -}; -/* make sure the following struct var had been initilased to 0! */ -static struct _nand_dev nand_part[UFFS_DEVICE_MAX] = {0}; - -static int uffs_result_to_dfs(int result) -{ - int status = -1; - - result = result < 0 ? -result : result; - switch (result) - { - case UENOERR:/** no error */ - break; - case UEACCES:/** Tried to open read-only file for writing, or files sharing mode - does not allow specified operations, or given path is directory */ - status = -EINVAL; - break;/* no suitable */ - case UEEXIST: /** _O_CREAT and _O_EXCL flags specified, but filename already exists */ - status = -EEXIST; - break; - case UEINVAL: /** Invalid oflag or pmode argument */ - status = -EINVAL; - break; - case UEMFILE: /** No more file handles available(too many open files) */ - status = -1; - break; - case UENOENT: /** file or path not found */ - status = -ENOENT; - break; - case UETIME: /** can't set file time */ - status = -1; - break; - case UEBADF: /** invalid file handle */ - status = -EBADF; - break; - case UENOMEM:/** no enough memory */ - status = -ENOSPC; - break; - case UEIOERR: /** I/O error from lower level flash operation */ - status = -EIO; - break; - case UENOTDIR: /** Not a directory */ - status = -ENOTDIR; - break; - case UEISDIR: /** Is a directory */ - status = -EISDIR; - break; - case UEUNKNOWN_ERR: - default: - status = -1; - break; /* unknown error! */ - } - - return status; -} - -static URET _device_init(uffs_Device *dev) -{ - dev->attr->_private = NULL; // hook nand_chip data structure to attr->_private - dev->ops = (struct uffs_FlashOpsSt *)&nand_ops; - - return U_SUCC; -} - -static URET _device_release(uffs_Device *dev) -{ - return U_SUCC; -} - -static int init_uffs_fs( - struct _nand_dev *nand_part) -{ - uffs_MountTable *mtb; - struct rt_mtd_nand_device *nand; - struct uffs_StorageAttrSt *flash_storage; - - mtb = &nand_part->mount_table; - nand = nand_part->dev; - flash_storage = &nand_part->storage; - - /* setup nand storage attributes */ - uffs_setup_storage(flash_storage, nand); - - /* register mount table */ - if (mtb->dev) - { - /* set memory allocator for uffs */ -#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0 - uffs_MemSetupSystemAllocator(&mtb->dev->mem); -#endif - /* setup device init/release entry */ - mtb->dev->Init = _device_init; - mtb->dev->Release = _device_release; - mtb->dev->attr = flash_storage; - - uffs_RegisterMountTable(mtb); - } - /* mount uffs partion on nand device */ - return uffs_Mount(nand_part->mount_path) == U_SUCC ? 0 : -1; -} - -static int dfs_uffs_mount( - struct dfs_filesystem *fs, - unsigned long rwflag, - const void *data) -{ - rt_base_t index; - uffs_MountTable *mount_part; - struct rt_mtd_nand_device *dev; - - RT_ASSERT(rt_strlen(fs->path) < (UFFS_MOUNT_PATH_MAX - 1)); - dev = RT_MTD_NAND_DEVICE(fs->dev_id); - - /*1. find a empty entry in partition table */ - for (index = 0; index < UFFS_DEVICE_MAX ; index ++) - { - if (nand_part[index].dev == RT_NULL) - break; - } - if (index == UFFS_DEVICE_MAX) - return -ENOENT; - - /*2. fill partition structure */ - nand_part[index].dev = dev; - - /* make a right mount path for uffs, end with '/' */ - rt_snprintf(nand_part[index].mount_path, UFFS_MOUNT_PATH_MAX, "%s/", fs->path); - if (nand_part[index].mount_path[1] == '/') - nand_part[index].mount_path[1] = 0; - - mount_part = &(nand_part[index].mount_table); - mount_part->mount = nand_part[index].mount_path; - mount_part->dev = &(nand_part[index].uffs_dev); - rt_memset(mount_part->dev, 0, sizeof(uffs_Device));//in order to make uffs happy. - mount_part->dev->_private = dev; /* save dev_id into uffs */ - mount_part->start_block = dev->block_start; - mount_part->end_block = dev->block_end; - /*3. mount uffs */ - if (init_uffs_fs(&nand_part[index]) < 0) - { - return uffs_result_to_dfs(uffs_get_error()); - } - return 0; -} - -static int dfs_uffs_unmount(struct dfs_filesystem *fs) -{ - rt_base_t index; - int result; - - /* find the device index and then unmount it */ - for (index = 0; index < UFFS_DEVICE_MAX; index++) - { - if (nand_part[index].dev == RT_MTD_NAND_DEVICE(fs->dev_id)) - { - nand_part[index].dev = RT_NULL; - result = uffs_UnMount(nand_part[index].mount_path); - if (result != U_SUCC) - break; - - result = uffs_UnRegisterMountTable(& nand_part[index].mount_table); - return (result == U_SUCC) ? RT_EOK : -1; - } - } - return -ENOENT; -} - -static int dfs_uffs_mkfs(rt_device_t dev_id) -{ - rt_base_t index; - rt_uint32_t block; - struct rt_mtd_nand_device *mtd; - - /*1. find the device index */ - for (index = 0; index < UFFS_DEVICE_MAX; index++) - { - if (nand_part[index].dev == (struct rt_mtd_nand_device *)dev_id) - break; - } - - if (index == UFFS_DEVICE_MAX) - { - /* can't find device driver */ - return -ENOENT; - } - - /*2. then unmount the partition */ - uffs_UnMount(nand_part[index].mount_path); - mtd = nand_part[index].dev; - - /*3. erase all blocks on the partition */ - block = mtd->block_start; - for (; block <= mtd->block_end; block++) - { - rt_mtd_nand_erase_block(mtd, block); -#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON) - if (rt_mtd_nand_check_block(mtd, block) != RT_EOK) - { - rt_kprintf("found bad block %d\n", block); - rt_mtd_nand_mark_badblock(mtd, block); - } -#endif - } - - /*4. remount it */ - if (init_uffs_fs(&nand_part[index]) < 0) - { - return uffs_result_to_dfs(uffs_get_error()); - } - return RT_EOK; -} - -static int dfs_uffs_statfs(struct dfs_filesystem *fs, - struct statfs *buf) -{ - rt_base_t index; - struct rt_mtd_nand_device *mtd = RT_MTD_NAND_DEVICE(fs->dev_id); - - RT_ASSERT(mtd != RT_NULL); - - /* find the device index */ - for (index = 0; index < UFFS_DEVICE_MAX; index++) - { - if (nand_part[index].dev == (void *)mtd) - break; - } - if (index == UFFS_DEVICE_MAX) - return -ENOENT; - - buf->f_bsize = mtd->page_size * mtd->pages_per_block; - buf->f_blocks = (mtd->block_end - mtd->block_start + 1); - buf->f_bfree = uffs_GetDeviceFree(&nand_part[index].uffs_dev) / buf->f_bsize ; - - return 0; -} - -static int dfs_uffs_open(struct dfs_fd *file) -{ - int fd; - int oflag, mode; - char *file_path; - - oflag = file->flags; - if (oflag & O_DIRECTORY) /* operations about dir */ - { - uffs_DIR *dir; - - if (oflag & O_CREAT) /* create a dir*/ - { - if (uffs_mkdir(file->path) < 0) - return uffs_result_to_dfs(uffs_get_error()); - } - /* open dir */ - file_path = rt_malloc(FILE_PATH_MAX); - if (file_path == RT_NULL) - return -ENOMEM; - - if (file->path[0] == '/' && !(file->path[1] == 0)) - rt_snprintf(file_path, FILE_PATH_MAX, "%s/", file->path); - else - { - file_path[0] = '/'; - file_path[1] = 0; - } - - dir = uffs_opendir(file_path); - - if (dir == RT_NULL) - { - rt_free(file_path); - return uffs_result_to_dfs(uffs_get_error()); - } - /* save this pointer,will used by dfs_uffs_getdents*/ - file->data = dir; - rt_free(file_path); - return RT_EOK; - } - /* regular file operations */ - /* int uffs_open(const char *name, int oflag, ...); what is this? - * uffs_open can open dir!! **/ - mode = 0; - if (oflag & O_RDONLY) mode |= UO_RDONLY; - if (oflag & O_WRONLY) mode |= UO_WRONLY; - if (oflag & O_RDWR) mode |= UO_RDWR; - /* Opens the file, if it is existing. If not, a new file is created. */ - if (oflag & O_CREAT) mode |= UO_CREATE; - /* Creates a new file. If the file is existing, it is truncated and overwritten. */ - if (oflag & O_TRUNC) mode |= UO_TRUNC; - /* Creates a new file. The function fails if the file is already existing. */ - if (oflag & O_EXCL) mode |= UO_EXCL; - - fd = uffs_open(file->path, mode); - if (fd < 0) - { - return uffs_result_to_dfs(uffs_get_error()); - } - - /* save this pointer, it will be used when calling read(), write(), - * flush(), seek(), and will be free when calling close()*/ - - file->data = (void *)fd; - file->pos = uffs_seek(fd, 0, USEEK_CUR); - file->size = uffs_seek(fd, 0, USEEK_END); - uffs_seek(fd, file->pos, USEEK_SET); - - if (oflag & O_APPEND) - { - file->pos = uffs_seek(fd, 0, USEEK_END); - } - return 0; -} - -static int dfs_uffs_close(struct dfs_fd *file) -{ - int oflag; - int fd; - - oflag = file->flags; - if (oflag & O_DIRECTORY) - { - /* operations about dir */ - if (uffs_closedir((uffs_DIR *)(file->data)) < 0) - return uffs_result_to_dfs(uffs_get_error()); - - return 0; - } - /* regular file operations */ - fd = (int)(file->data); - - if (uffs_close(fd) == 0) - return 0; - - return uffs_result_to_dfs(uffs_get_error()); -} - -static int dfs_uffs_ioctl(struct dfs_fd *file, int cmd, void *args) -{ - return -ENOSYS; -} - -static int dfs_uffs_read(struct dfs_fd *file, void *buf, size_t len) -{ - int fd; - int char_read; - - fd = (int)(file->data); - char_read = uffs_read(fd, buf, len); - if (char_read < 0) - return uffs_result_to_dfs(uffs_get_error()); - - /* update position */ - file->pos = uffs_seek(fd, 0, USEEK_CUR); - return char_read; -} - -static int dfs_uffs_write(struct dfs_fd *file, - const void *buf, - size_t len) -{ - int fd; - int char_write; - - fd = (int)(file->data); - - char_write = uffs_write(fd, buf, len); - if (char_write < 0) - return uffs_result_to_dfs(uffs_get_error()); - - /* update position */ - file->pos = uffs_seek(fd, 0, USEEK_CUR); - return char_write; -} - -static int dfs_uffs_flush(struct dfs_fd *file) -{ - int fd; - int result; - - fd = (int)(file->data); - - result = uffs_flush(fd); - if (result < 0) - return uffs_result_to_dfs(uffs_get_error()); - return 0; -} - -int uffs_seekdir(uffs_DIR *dir, long offset) -{ - int i = 0; - - while (i < offset) - { - if (uffs_readdir(dir) == RT_NULL) - return -1; - i++; - } - return 0; -} - - -static int dfs_uffs_seek(struct dfs_fd *file, - rt_off_t offset) -{ - int result; - - /* set offset as current offset */ - if (file->type == FT_DIRECTORY) - { - uffs_rewinddir((uffs_DIR *)(file->data)); - result = uffs_seekdir((uffs_DIR *)(file->data), offset / sizeof(struct dirent)); - if (result >= 0) - { - file->pos = offset; - return offset; - } - } - else if (file->type == FT_REGULAR) - { - result = uffs_seek((int)(file->data), offset, USEEK_SET); - if (result >= 0) - return offset; - } - - return uffs_result_to_dfs(uffs_get_error()); -} - -/* return the size of struct dirent*/ -static int dfs_uffs_getdents( - struct dfs_fd *file, - struct dirent *dirp, - uint32_t count) -{ - rt_uint32_t index; - char *file_path; - struct dirent *d; - uffs_DIR *dir; - struct uffs_dirent *uffs_d; - - dir = (uffs_DIR *)(file->data); - RT_ASSERT(dir != RT_NULL); - - /* round count, count is always 1 */ - count = (count / sizeof(struct dirent)) * sizeof(struct dirent); - if (count == 0) return -EINVAL; - - /* allocate file name */ - file_path = rt_malloc(FILE_PATH_MAX); - if (file_path == RT_NULL) - return -ENOMEM; - - index = 0; - /* usually, the while loop should only be looped only once! */ - while (1) - { - struct uffs_stat s; - - d = dirp + index; - - uffs_d = uffs_readdir(dir); - if (uffs_d == RT_NULL) - { - rt_free(file_path); - return (uffs_result_to_dfs(uffs_get_error())); - } - - if (file->path[0] == '/' && !(file->path[1] == 0)) - rt_snprintf(file_path, FILE_PATH_MAX, "%s/%s", file->path, uffs_d->d_name); - else - rt_strncpy(file_path, uffs_d->d_name, FILE_PATH_MAX); - - uffs_stat(file_path, &s); - switch (s.st_mode & US_IFMT) /* file type mark */ - { - case US_IFREG: /* directory */ - d->d_type = DT_REG; - break; - case US_IFDIR: /* regular file */ - d->d_type = DT_DIR; - break; - case US_IFLNK: /* symbolic link */ - case US_IREAD: /* read permission */ - case US_IWRITE:/* write permission */ - default: - d->d_type = DT_UNKNOWN; - break; - } - - /* write the rest args of struct dirent* dirp */ - d->d_namlen = rt_strlen(uffs_d->d_name); - d->d_reclen = (rt_uint16_t)sizeof(struct dirent); - rt_strncpy(d->d_name, uffs_d->d_name, rt_strlen(uffs_d->d_name) + 1); - - index ++; - if (index * sizeof(struct dirent) >= count) - break; - } - - /* free file name buf */ - rt_free(file_path); - - if (index == 0) - return uffs_result_to_dfs(uffs_get_error()); - - file->pos += index * sizeof(struct dirent); - - return index * sizeof(struct dirent); -} - -static int dfs_uffs_unlink(struct dfs_filesystem *fs, const char *path) -{ - int result; - struct uffs_stat s; - - /* judge file type, dir is to be delete by uffs_rmdir, others by uffs_remove */ - if (uffs_lstat(path, &s) < 0) - { - return uffs_result_to_dfs(uffs_get_error()); - } - - switch (s.st_mode & US_IFMT) - { - case US_IFREG: - result = uffs_remove(path); - break; - case US_IFDIR: - result = uffs_rmdir(path); - break; - default: - /* unknown file type */ - return -1; - } - if (result < 0) - return uffs_result_to_dfs(uffs_get_error()); - - return 0; -} - -static int dfs_uffs_rename( - struct dfs_filesystem *fs, - const char *oldpath, - const char *newpath) -{ - int result; - - result = uffs_rename(oldpath, newpath); - if (result < 0) - return uffs_result_to_dfs(uffs_get_error()); - - return 0; -} - -static int dfs_uffs_stat(struct dfs_filesystem *fs, const char *path, struct stat *st) -{ - int result; - struct uffs_stat s; - - result = uffs_stat(path, &s); - if (result < 0) - return uffs_result_to_dfs(uffs_get_error()); - - /* convert uffs stat to dfs stat structure */ - /* FIXME, these field may not be the same */ - st->st_dev = 0; - st->st_mode = s.st_mode; - st->st_size = s.st_size; - st->st_mtime = s.st_mtime; - - return 0; -} - -static const struct dfs_file_ops dfs_uffs_fops = -{ - dfs_uffs_open, - dfs_uffs_close, - dfs_uffs_ioctl, - dfs_uffs_read, - dfs_uffs_write, - dfs_uffs_flush, - dfs_uffs_seek, - dfs_uffs_getdents, -}; - -static const struct dfs_filesystem_ops dfs_uffs_ops = -{ - "uffs", /* file system type: uffs */ -#if RTTHREAD_VERSION >= 10100 - DFS_FS_FLAG_FULLPATH, -#else -#error "uffs can only work with rtthread whose version should >= 1.01\n" -#endif - &dfs_uffs_fops, - - dfs_uffs_mount, - dfs_uffs_unmount, - dfs_uffs_mkfs, - dfs_uffs_statfs, - - dfs_uffs_unlink, - dfs_uffs_stat, - dfs_uffs_rename, -}; - -int dfs_uffs_init(void) -{ - /* register uffs file system */ - dfs_register(&dfs_uffs_ops); - - if (uffs_InitObjectBuf() == U_SUCC) - { - if (uffs_DirEntryBufInit() == U_SUCC) - { - uffs_InitGlobalFsLock(); - return RT_EOK; - } - } - return -RT_ERROR; -} -INIT_COMPONENT_EXPORT(dfs_uffs_init); - diff --git a/components/dfs/filesystems/uffs/dfs_uffs.h b/components/dfs/filesystems/uffs/dfs_uffs.h deleted file mode 100644 index 72f0ee9240..0000000000 --- a/components/dfs/filesystems/uffs/dfs_uffs.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-03-30 prife the first version - */ - -#ifndef DFS_UFFS_H_ -#define DFS_UFFS_H_ - -#include "uffs_config.h" -#include "uffs/uffs_public.h" - -/* the UFFS ECC mode opitons */ -#ifndef RT_UFFS_ECC_MODE -#define RT_UFFS_ECC_MODE 1 -#endif - -/* - * RT_UFFS_ECC_MODE: - * 0, Do not use ECC - * 1, UFFS calculate the ECC - * 2, Flash driver(or by hardware) calculate the ECC - * 3, Hardware calculate the ECC and automatically write to spare. - */ -#if RT_UFFS_ECC_MODE == 0 -#define RT_CONFIG_UFFS_ECC_MODE UFFS_ECC_NONE -#elif RT_UFFS_ECC_MODE == 1 -#define RT_CONFIG_UFFS_ECC_MODE UFFS_ECC_SOFT -#elif RT_UFFS_ECC_MODE == 2 -#define RT_CONFIG_UFFS_ECC_MODE UFFS_ECC_HW -#elif RT_UFFS_ECC_MODE == 3 -#define RT_CONFIG_UFFS_ECC_MODE UFFS_ECC_HW_AUTO -#endif - -/* #define RT_CONFIG_UFFS_ECC_MODE UFFS_ECC_HW_AUTO */ -/* #define RT_CONFIG_UFFS_ECC_MODE UFFS_ECC_SOFT */ -/* #define RT_CONFIG_UFFS_ECC_MODE UFFS_ECC_NONE */ - -/* enable this ,you need provide a mark_badblock/check_block funciton */ -/* #define RT_UFFS_USE_CHECK_MARK_FUNCITON */ - -#if RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_SOFT /* let uffs do soft ecc */ -#define RT_CONFIG_UFFS_LAYOUT UFFS_LAYOUT_UFFS /* UFFS_LAYOUT_FLASH */ - -#elif RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_HW_AUTO /* nand driver make ecc and do ecc correct */ -#define RT_CONFIG_UFFS_LAYOUT UFFS_LAYOUT_FLASH - -#elif RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_NONE -#define RT_CONFIG_UFFS_LAYOUT UFFS_LAYOUT_UFFS /* UFFS_LAYOUT_FLASH */ - -#else -#error "uffs under rt-thread do not support this ECC mode" -#endif /* RT_CONFIG_UFFS_ECC_MODE */ - -#if (!CONFIG_USE_STATIC_MEMORY_ALLOCATOR) && (CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR) -#define RT_UFFS_MEMORY_ALLOCATOR 1 /* use system memory allocator */ -#elif (CONFIG_USE_STATIC_MEMORY_ALLOCATOR) && (!CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR) -#define RT_UFFS_MEMORY_ALLOCATOR 0 /* use static memory allocator */ -#else -#error "UFFS: CONFIG_USE_STATIC_MEMORY_ALLOCATOR ,CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR are invalid!" -#endif - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0 -#error "dfs_uffs only support CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR" -#endif - -#if defined(CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME) -#error "dfs_uffs not support CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME" -#endif - -#if (RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_HW_AUTO) && (RT_CONFIG_UFFS_LAYOUT != UFFS_LAYOUT_FLASH) -#error "when use UFFS_ECC_HW_AUTO, you must use UFFS_LAYOUT_FLASH" - -#elif (RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_SOFT) && (RT_CONFIG_UFFS_LAYOUT != UFFS_LAYOUT_UFFS) -#warning "when use UFFS_ECC_SOFT, it is recommended to use UFFS_LAYOUT_UFFS" -#endif - -extern const uffs_FlashOps nand_ops; - -extern void uffs_setup_storage( - struct uffs_StorageAttrSt *attr, - struct rt_mtd_nand_device *nand); - -extern int dfs_uffs_init(void); -#endif /* DFS_UFFS_H_ */ diff --git a/components/dfs/filesystems/uffs/doc/Understanding-UFFS.odp b/components/dfs/filesystems/uffs/doc/Understanding-UFFS.odp Binary files differdeleted file mode 100644 index b39f4d0f32..0000000000 --- a/components/dfs/filesystems/uffs/doc/Understanding-UFFS.odp +++ /dev/null diff --git a/components/dfs/filesystems/uffs/doc/Understanding-UFFS.pdf b/components/dfs/filesystems/uffs/doc/Understanding-UFFS.pdf Binary files differdeleted file mode 100644 index 02926c8e18..0000000000 --- a/components/dfs/filesystems/uffs/doc/Understanding-UFFS.pdf +++ /dev/null diff --git a/components/dfs/filesystems/uffs/doc/uffs-serial-num-relationship.JPG b/components/dfs/filesystems/uffs/doc/uffs-serial-num-relationship.JPG Binary files differdeleted file mode 100644 index 2cdbbcd2b2..0000000000 --- a/components/dfs/filesystems/uffs/doc/uffs-serial-num-relationship.JPG +++ /dev/null diff --git a/components/dfs/filesystems/uffs/src/CMakeLists.txt b/components/dfs/filesystems/uffs/src/CMakeLists.txt deleted file mode 100644 index 7d744d16ee..0000000000 --- a/components/dfs/filesystems/uffs/src/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -ADD_SUBDIRECTORY(emu) -ADD_SUBDIRECTORY(uffs) -ADD_SUBDIRECTORY(utils) -ADD_SUBDIRECTORY(example) -ADD_SUBDIRECTORY(platform) -ADD_SUBDIRECTORY(test/api_test) -ADD_SUBDIRECTORY(test/clients) diff --git a/components/dfs/filesystems/uffs/src/emu/CMakeLists.txt b/components/dfs/filesystems/uffs/src/emu/CMakeLists.txt deleted file mode 100644 index f70deff7a2..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -SET (libemu_SRCS - cmdline.c - cmdline.h - helper_cmds.c - uffs_fileem.c - uffs_fileem_share.c - uffs_fileem_wrap.c - uffs_fileem_ecc_soft.c - uffs_fileem_ecc_hw.c - uffs_fileem_ecc_hw_auto.c - uffs_fileem.h - test_cmds.c - ) - -IF (UNIX) - INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/posix) -ENDIF() -IF (WIN32) - INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/win32) -ENDIF() -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc) -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/test/api_test) -ADD_LIBRARY(emu STATIC ${libemu_SRCS} ) - diff --git a/components/dfs/filesystems/uffs/src/emu/cmdline.c b/components/dfs/filesystems/uffs/src/emu/cmdline.c deleted file mode 100644 index 9774a11ca1..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/cmdline.c +++ /dev/null @@ -1,643 +0,0 @@ -/* -This file is part of UFFS, the Ultra-low-cost Flash File System. - -Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - -UFFS is free software; you can redistribute it and/or modify it under -the GNU Library General Public License as published by the Free Software -Foundation; either version 2 of the License, or (at your option) any -later version. - -UFFS is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -or GNU Library General Public License, as applicable, for more details. - -You should have received a copy of the GNU General Public License -and GNU Library General Public License along with UFFS; if not, write -to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. - -As a special exception, if other files instantiate templates or use -macros or inline functions from this file, or you compile this file -and link it with other works to produce a work based on this file, -this file does not by itself cause the resulting work to be covered -by the GNU General Public License. However the source code for this -file must still be made available in accordance with section (3) of -the GNU General Public License v2. - -This exception does not invalidate any other reasons why a work based -on this file might be covered by the GNU General Public License. -*/ - -/** -* \file cmdline.c -* \brief command line test interface -* \author Ricky Zheng, created in 22th Feb, 2007 -*/ - -#include <string.h> -#include <stdio.h> -//#include <conio.h> -#include "uffs_config.h" -#include "cmdline.h" -#include "uffs/uffs_fs.h" - -#define PROMPT "UFFS>" - -#define PFX "cli : " -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - -#define MAX_CLI_ARGS_BUF_LEN 120 -#define MAX_CLI_ARGS_NUM 20 -#define MAX_CLI_ENV_NUM 11 // '?', '0' - '9' - - -struct cli_arg { - int argc; - char *argv[MAX_CLI_ARGS_NUM]; - char _buf[MAX_CLI_ARGS_BUF_LEN]; -}; - -static BOOL m_exit = FALSE; -static BOOL m_abort = FALSE; -static struct cli_commandset *m_cmdset_head = NULL; - -// Note: last command return code stored in env 0. -static int m_cli_envs[MAX_CLI_ENV_NUM] = {0}; // cli environment variables - -static const struct cli_command * cli_find(const char *cmd); -static int cmd_help(int argc, char *argv[]); - - -#define FOR_EACH_CLI_CMD(set, cmd) \ - for (set = m_cmdset_head; set && set->cmds; set = set->next) \ - for (cmd = set->cmds; cmd && cmd->handler; cmd++) - - -/*** filter out leading and tailing spaces, discard comments - * return pointer to start of new command line - */ -static char * cli_process_line(char *p) -{ - char *s; - char *x; - - if (!p) - return NULL; - - // skip leading spaces - while (p && (*p == ' ' || *p == '\t')) - p++; - - for (s = x = p; *p; x++, p++) { - switch(*p) { - case '\\': - p++; - if (*p) { - switch(*p) { - case 'n': - *x = '\n'; - break; - case 'r': - *x = '\r'; - break; - case 't': - *x = '\t'; - break; - case 'b': - *x = '\b'; - break; - default: - if (*p >= '0' && *p <= '9') - *x = *p - '0'; - else - *x = *p; - break; - } - } - break; - default: - if (*p == '\r' || *p == '\n' || *p == '#') *p = '\0'; - *x = *p; - break; - } - - if (*p == 0) - break; - } - - // trim tailing spaces - p--; - while (p > s && (*p == ' ' || *p == '\t')) - *p-- = '\0'; - - return s; -} - -static int cli_env_to_idx(char env) -{ - int idx = -1; - - if (env >= '0' && env <= '9') { - idx = env - '0' + 1; - } - else if (env == '?') { - idx = 0; - } - - return idx; -} - -int cli_env_set(char env, int val) -{ - int idx = cli_env_to_idx(env); - - if (idx >= 0) { - m_cli_envs[idx] = val; - return 0; - } - else - return -1; -} - -int cli_env_get(char env) -{ - int idx = cli_env_to_idx(env); - - return idx >= 0 ? m_cli_envs[idx] : 0; -} - -/** exec command <n> times: - * exec <n> <cmd> [...] - */ -static int cmd_exec(int argc, char *argv[]) -{ - int n = 0; - const struct cli_command *cmd; - - CHK_ARGC(3, 0); - - if (sscanf(argv[1], "%d", &n) != 1) - return CLI_INVALID_ARG; - if (n <= 0) - return CLI_INVALID_ARG; - - cmd = cli_find(argv[2]); - if (cmd == NULL) { - MSG("Unknown command '%s'\n", argv[2]); - return -1; - } - else { - argv += 2; - while (n-- >= 0) { - if (cmd->handler(argc - 2, argv) != 0) - return -1; - } - } - - return 0; -} - -/** - * test expression - * test <a> <op> <b> - * for example: - * test 1 > 0 ==> return 0 - * test 1 <= 0 ==> return -1 - */ -static int cmd_test(int argc, char *argv[]) -{ - int a, b; - char *op; - BOOL tst = FALSE; - - CHK_ARGC(4, 4); - - if (sscanf(argv[1], "%d", &a) != 1 || - sscanf(argv[3], "%d", &b) != 1) - { - return CLI_INVALID_ARG; - } - - op = argv[2]; - if (!strcmp(op, ">")) { - tst = (a > b); - } - else if (!strcmp(op, "<")) { - tst = (a < b); - } - else if (!strcmp(op, "==")) { - tst = (a == b); - } - else if (!strcmp(op, ">=")) { - tst = (a >= b); - } - else if (!strcmp(op, "<=")) { - tst = (a <= b); - } - else if (!strcmp(op, "!=")) { - tst = (a != b); - } - else { - return CLI_INVALID_ARG; - } - - return tst ? 0 : -1; -} - -/** if last command failed (return != 0), run <cmd> - * ! <cmd> - */ -static int cmd_failed(int argc, char *argv[]) -{ - const struct cli_command *cmd; - - CHK_ARGC(2, 0); - - cmd = cli_find(argv[1]); - if (cmd == NULL) { - MSG("Unknown command '%s'\n", argv[1]); - return -1; - } - else { - argv++; - return (cli_env_get('?') == 0 ? 0 : cmd->handler(argc - 1, argv)); - } -} - -/** print messages - * echo [<arg> ...] - */ -static int cmd_echo(int argc, char *argv[]) -{ - int i; - - for (i = 1; i < argc; i++) { - MSG("%s%s", i > 1 ? " " : "", argv[i]); - } - MSG("\n"); - - return 0; -} - -/** set cli environment variable - * set <env> <value> - */ -static int cmd_set(int argc, char *argv[]) -{ - int val; - int ret = -1; - - CHK_ARGC(3, 0); - - if (sscanf(argv[2], "%d", &val) == 1) { - ret = cli_env_set(argv[1][0], val); - } - - return ret; -} - -/** evaluation the expresstion, result to $1 - * evl <value> <op> <value> - */ -static int cmd_evl(int argc, char *argv[]) -{ - int val1, val2, result = 0; - int ret = -1; - - CHK_ARGC(4, 4); - - if (sscanf(argv[1], "%d", &val1) == 1 && - sscanf(argv[3], "%d", &val2) == 1) { - ret = 0; - switch(argv[2][0]) { - case '+': - result = val1 + val2; - break; - case '-': - result = val1 - val2; - break; - case '*': - result = val1 * val2; - break; - case '/': - if (val2 == 0) - ret = -1; - else - result = val1 / val2; - break; - case '%': - if (val2 == 0) - ret = -1; - else - result = val1 % val2; - break; - default: - ret = CLI_INVALID_ARG; - break; - } - } - - if (ret == 0) - ret = cli_env_set('1', result); - - return ret; -} - -static int cmd_exit(int argc, char *argv[]) -{ - m_exit = TRUE; - return 0; -} - -/** Abort current script - * abort [...] - */ -static int cmd_abort(int argc, char *argv[]) -{ - if (argc > 1) { - cmd_echo(argc, argv); - } - - m_abort = TRUE; - - return 0; -} - -/** run local file system's script - * script <filename> - */ -static int cmd_script(int argc, char *argv[]) -{ - char line_buf[256]; - char *p; - FILE *fp; - const char *name; - int ret = 0; - static int stack = 0; - - CHK_ARGC(2, 0); - - if (stack++ == 0) - m_abort = FALSE; - - name = argv[1]; - fp = fopen(name, "r"); - - if (fp) { - memset(line_buf, 0, sizeof(line_buf)); - while (!m_abort && fgets(line_buf, sizeof(line_buf) - 1, fp)) { - p = line_buf + sizeof(line_buf) - 1; - while (*p == 0 && p > line_buf) - p--; - while ((*p == '\r' || *p == '\n') && p > line_buf) { - *p-- = 0; - } - p = cli_process_line(line_buf); - if (*p) - ret = cli_interpret(p); - memset(line_buf, 0, sizeof(line_buf)); - } - fclose(fp); - } - else { - MSG("Can't open host script file '%s' for read\n", name); - ret = -1; - } - - stack--; - - return ret; -} - - - -static const struct cli_command default_cmds[] = -{ - { cmd_help, "help|?", "[<command>]", "show commands or help on one command" }, - { cmd_exit, "exit", NULL, "exit command line" }, - { cmd_exec, "*", "<n> <cmd> [...]>", "run <cmd> <n> times" }, - { cmd_failed, "!", "<cmd> [...]", "run <cmd> if last command failed" }, - { cmd_echo, "echo", "[...]", "print messages" }, - { cmd_set, "set", "<env> <val>", "set env variable" }, - { cmd_evl, "evl", "<val> <op> <val>", "evaluation expresstion" }, - { cmd_test, "test", "<a> <op> <b>", "test expression: <a> <op> <b>" }, - { cmd_script, "script", "<file>", "run host script <file>" }, - { cmd_abort, "abort", NULL, "abort from the running script" }, - { NULL, NULL, NULL, NULL } -}; - -static struct cli_commandset default_cmdset = { - default_cmds, -}; - -static BOOL match_cmd(const char *src, int start, int end, const char *des) -{ - while (src[start] == ' ' && start < end) - start++; - - while (src[end] == ' ' && start < end) - end--; - - if ((int)strlen(des) == (end - start + 1)) { - if (memcmp(src + start, des, end - start + 1) == 0) { - return TRUE; - } - } - - return FALSE; -} - -static BOOL check_cmd(const char *cmds, const char *cmd) -{ - int start, end; - - for (start = end = 0; cmds[end] != 0 && cmds[end] != '|'; end++); - - while (end > start) { - if (match_cmd(cmds, start, end - 1, cmd) == TRUE) - return TRUE; - if (cmds[end] == 0) - break; - if (cmds[end] == '|') { - end++; - for (start = end; cmds[end] != 0 && cmds[end] != '|'; end++); - } - } - - return FALSE; -} - -static const struct cli_command * cli_find(const char *cmd) -{ - struct cli_commandset *work; - const struct cli_command *s; - - FOR_EACH_CLI_CMD(work, s) { - if (check_cmd(s->cmd, cmd) == TRUE) - return s; - } - - return NULL; -} - -static void show_cmd_usage(const struct cli_command *cmd) -{ - MSG("%s: %s\n", cmd->cmd, cmd->descr); - MSG("Usage: %s %s\n", cmd->cmd, cmd->args ? cmd->args : ""); -} - -static int cmd_help(int argc, char *argv[]) -{ - const struct cli_command *cmd; - struct cli_commandset *cmdset; - int i, n; - - if (argc < 2) { - MSG("Available commands:\n"); - n = 0; - FOR_EACH_CLI_CMD(cmdset, cmd) { - MSG("%s", cmd->cmd); - for (i = strlen(cmd->cmd); i%10; i++, MSG(" ")); - if ((++n % 5) == 0) MSG("\n"); - } - MSG("\n"); - } - else { - cmd = cli_find(argv[1]); - if (cmd == NULL) { - MSG("No such command\n"); - return -1; - } - else { - show_cmd_usage(cmd); - } - } - - return 0; -} - -static void cli_parse_args(const char *cmd, struct cli_arg *arg) -{ - char *p; - int val; - - if (arg) { - arg->argc = 0; - if (cmd) { - p = arg->_buf; - while (*cmd && arg->argc < MAX_CLI_ARGS_NUM && (p - arg->_buf < MAX_CLI_ARGS_BUF_LEN)) { - while(*cmd && (*cmd == ' ' || *cmd == '\t')) - cmd++; - - arg->argv[arg->argc] = p; - while (*cmd && (*cmd != ' ' && *cmd != '\t') && (p - arg->_buf < MAX_CLI_ARGS_BUF_LEN)) { - if (*cmd == '$') { - // command env replacement - cmd++; - val = cli_env_get(*cmd++); - if (p - arg->_buf < MAX_CLI_ARGS_BUF_LEN - 12) { // 12 is long enough for 32bit 'int' - p += sprintf(p, "%d", val & 0xFFFFFFFF); - } - } - else - *p++ = *cmd++; - } - *p++ = '\0'; - - if (*(arg->argv[arg->argc]) == '\0') - break; - arg->argc++; - } - } - } -} - -int cli_interpret(const char *line) -{ - struct cli_arg arg = {0}; - const struct cli_command *cmd; - int ret = -1; - - cli_parse_args(line, &arg); - - if (arg.argc > 0) { - cmd = cli_find(arg.argv[0]); - if (cmd == NULL) { - MSG("Unknown command '%s'\n", arg.argv[0]); - } - else { - ret = cmd->handler(arg.argc, arg.argv); - if (ret == CLI_INVALID_ARG) { - MSG("\n"); - show_cmd_usage(cmd); - } - } - } - - cli_env_set('?', ret); // $? = last command return code - - return ret; -} - -void cli_add_commandset(struct cli_commandset *set) -{ - if (set) { - set->next = m_cmdset_head; - m_cmdset_head = set; - } -} - -void cli_main_entry() -{ - char line[80]; - int linelen = 0; - char *p; - - MSG("$ "); - cli_add_commandset(&default_cmdset); - - while (!m_exit) { - char ch; - if (linelen >= sizeof(line)) - continue; - ch = getc(stdin); - switch (ch) { - case 8: - case 127: - if (linelen > 0) { - --linelen; - MSG("\x08 \x08"); - } - break; - - case '\r': - case '\n': - //MSG("\r\n"); - if (linelen > 0) { - line[linelen] = 0; - p = cli_process_line(line); - if (*p) - cli_interpret(p); - linelen = 0; - } - MSG("$ "); - break; - - case 21: - while (linelen > 0) { - --linelen; - MSG("\x08 \x08"); - } - break; - - default: - if (ch >= ' ' && ch < 127 && linelen < sizeof(line) - 1) { - line[linelen++] = ch; - //MSG("%c", ch); - } - } - } -} diff --git a/components/dfs/filesystems/uffs/src/emu/cmdline.h b/components/dfs/filesystems/uffs/src/emu/cmdline.h deleted file mode 100644 index 284d68eaea..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/cmdline.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - - -#ifndef _UFFS_CLI_H_ -#define _UFFS_CLI_H_ - -#ifndef BOOL -#define BOOL int -#endif - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#define CLI_INVALID_ARG -100 - -typedef int command_t(int argc, char *argv[]); - -struct cli_command { - command_t *handler; - const char *cmd; - const char *args; - const char *descr; -}; - -struct cli_commandset { - const struct cli_command *cmds; - struct cli_commandset *next; -}; - -void cli_add_commandset(struct cli_commandset *set); -int cli_interpret(const char *line); -int cli_env_get(char env); -int cli_env_set(char env, int val); -void cli_main_entry(); - -#define u_assert(x) \ - ((x) ? TRUE : \ - (uffs_PerrorRaw(UFFS_MSG_NORMAL, \ - "Assert failed at %s:%s:%d: '%s' is not true.\n", \ - __FILE__, __FUNCTION__, __LINE__, #x), FALSE)) - - -#define CHK_ARGC(min, max) \ - if (argc < min || (max > 0 && argc > max)) \ - return CLI_INVALID_ARG - -#endif - - diff --git a/components/dfs/filesystems/uffs/src/emu/helper_cmds.c b/components/dfs/filesystems/uffs/src/emu/helper_cmds.c deleted file mode 100644 index 1526c441ca..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/helper_cmds.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file helper_cmds.c - * \brief helper commands for test uffs - * \author Ricky Zheng - */ -#include <stdio.h> -#include <string.h> -#include <stdarg.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_fs.h" -#include "uffs/uffs_utils.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs_mtb.h" -#include "uffs/uffs_find.h" -#include "cmdline.h" -#include "uffs/uffs_fd.h" -#include "uffs/uffs_mtb.h" -#include "uffs_fileem.h" - -#define PFX "cmd : " - -#define MAX_PATH_LENGTH 128 - -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - -/** format [<mount>] */ -static int cmd_format(int argc, char *argv[]) -{ - URET ret; - const char *mount = "/"; - uffs_Device *dev; - UBOOL force = U_FALSE; - - if (argc > 1) { - mount = argv[1]; - if (argc > 2 && strcmp(argv[2], "-f") == 0) - force = U_TRUE; - } - MSGLN("Formating %s ... ", mount); - - dev = uffs_GetDeviceFromMountPoint(mount); - if (dev == NULL) { - MSGLN("Can't get device from mount point."); - return -1; - } - else { - ret = uffs_FormatDevice(dev, force); - if (ret != U_SUCC) { - MSGLN("Format fail."); - return -1; - } - else { - MSGLN("Format succ."); - } - uffs_PutDevice(dev); - } - - return 0; -} - -/** mkf <file> */ -static int cmd_mkf(int argc, char *argv[]) -{ - int fd; - const char *name; - int oflags = UO_RDWR | UO_CREATE; - - CHK_ARGC(2, 2); - - name = argv[1]; - fd = uffs_open(name, oflags); - if (fd < 0) { - MSGLN("Create %s fail, err: %d", name, uffs_get_error()); - return -1; - } - else { - MSGLN("Create %s succ.", name); - uffs_close(fd); - } - - return 0; -} - -/** mkdir <dir> */ -static int cmd_mkdir(int argc, char *argv[]) -{ - const char *name; - - CHK_ARGC(2, 0); - - name = argv[1]; - - if (uffs_mkdir(name) < 0) { - MSGLN("Create %s fail, err: %d", name, uffs_get_error()); - return -1; - } - else { - MSGLN("Create %s succ.", name); - } - - return 0; -} - - -static int CountObjectUnder(const char *dir) -{ - int count = 0; - uffs_DIR *dirp; - - dirp = uffs_opendir(dir); - if (dirp) { - while (uffs_readdir(dirp) != NULL) - count++; - uffs_closedir(dirp); - } - return count; -} - -static int cmd_pwd(int argc, char *argv[]) -{ - MSGLN("not supported."); - return 0; -} - -static int cmd_cd(int argc, char *argv[]) -{ - MSGLN("Not supported"); - return 0; -} - -/** ls [<dir>] */ -static int cmd_ls(int argc, char *argv[]) -{ - uffs_DIR *dirp; - struct uffs_dirent *ent; - struct uffs_stat stat_buf; - int count = 0; - char buf[MAX_PATH_LENGTH+2]; - const char *name = "/"; - char *sub; - int ret = 0; - - CHK_ARGC(1, 2); - - if (argc > 1) - name = argv[1]; - - dirp = uffs_opendir(name); - if (dirp == NULL) { - MSGLN("Can't open '%s' for list", name); - ret = -1; - } - else { - MSG("------name-----------size---------serial-----" TENDSTR); - ent = uffs_readdir(dirp); - while (ent) { - MSG("%9s", ent->d_name); - strcpy(buf, name); - sub = buf; - if (name[strlen(name)-1] != '/') - sub = strcat(buf, "/"); - sub = strcat(sub, ent->d_name); - if (ent->d_type & FILE_ATTR_DIR) { - sub = strcat(sub, "/"); - MSG("/ \t<%8d>", CountObjectUnder(sub)); - } - else { - uffs_stat(sub, &stat_buf); - MSG(" \t %8d ", stat_buf.st_size); - } - MSG("\t%6d" TENDSTR, ent->d_ino); - count++; - ent = uffs_readdir(dirp); - } - - uffs_closedir(dirp); - - MSG("Total: %d objects." TENDSTR, count); - } - - return ret; -} - -/** rm <obj> */ -static int cmd_rm(int argc, char *argv[]) -{ - const char *name = NULL; - int ret = 0; - struct uffs_stat st; - - CHK_ARGC(2, 2); - - name = argv[1]; - - ret = uffs_stat(name, &st); - if (ret < 0) { - MSGLN("Can't stat '%s'", name); - return ret; - } - - if (st.st_mode & US_IFDIR) { - ret = uffs_rmdir(name); - } - else { - ret = uffs_remove(name); - } - - if (ret == 0) - MSGLN("Delete '%s' succ.", name); - else - MSGLN("Delete '%s' fail!", name); - - return ret; -} - -/** ren|mv <old> <new> */ -static int cmd_ren(int argc, char *argv[]) -{ - const char *oldname; - const char *newname; - int ret; - - CHK_ARGC(3, 3); - - oldname = argv[1]; - newname = argv[2]; - - if ((ret = uffs_rename(oldname, newname)) == 0) { - MSGLN("Rename from '%s' to '%s' succ.", oldname, newname); - } - else { - MSGLN("Rename from '%s' to '%s' fail!", oldname, newname); - } - - return ret; -} - -static void dump_msg_to_stdout(struct uffs_DeviceSt *dev, const char *fmt, ...) -{ - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - va_list args; - - va_start(args, fmt); - //vprintf(fmt, args); - if (emu && emu->dump_fp) - vfprintf(emu->dump_fp, fmt, args); - va_end(args); -} - -/** dump [<mount>] */ -static int cmd_dump(int argc, char *argv[]) -{ - uffs_Device *dev; - uffs_FileEmu *emu; - const char *mount = "/"; - const char *dump_file = "dump.txt"; - - if (argc > 1) { - mount = argv[1]; - if (argc > 2) - dump_file = argv[2]; - } - - dev = uffs_GetDeviceFromMountPoint(mount); - if (dev == NULL) { - MSGLN("Can't get device from mount point %s", mount); - return -1; - } - - emu = (uffs_FileEmu *)(dev->attr->_private); - emu->dump_fp = fopen(dump_file, "w"); - - uffs_DumpDevice(dev, dump_msg_to_stdout); - - if (emu->dump_fp) - fclose(emu->dump_fp); - - uffs_PutDevice(dev); - - return 0; -} - -/** st [<mount>] */ -static int cmd_st(int argc, char *argv[]) -{ - uffs_Device *dev; - const char *mount = "/"; - uffs_FlashStat *s; - TreeNode *node; - - if (argc > 1) { - mount = argv[1]; - } - - dev = uffs_GetDeviceFromMountPoint(mount); - if (dev == NULL) { - MSGLN("Can't get device from mount point %s", mount); - return -1; - } - - s = &(dev->st); - - MSG("----------- basic info -----------" TENDSTR); - MSG("TreeNode size: %d" TENDSTR, sizeof(TreeNode)); - MSG("TagStore size: %d" TENDSTR, sizeof(struct uffs_TagStoreSt)); - MSG("MaxCachedBlockInfo: %d" TENDSTR, dev->cfg.bc_caches); - MSG("MaxPageBuffers: %d" TENDSTR, dev->cfg.page_buffers); - MSG("MaxDirtyPagesPerBlock: %d" TENDSTR, dev->cfg.dirty_pages); - MSG("MaxPathLength: %d" TENDSTR, MAX_PATH_LENGTH); - MSG("MaxObjectHandles: %d" TENDSTR, MAX_OBJECT_HANDLE); - MSG("FreeObjectHandles: %d" TENDSTR, uffs_GetFreeObjectHandlers()); - MSG("MaxDirHandles: %d" TENDSTR, MAX_DIR_HANDLE); - MSG("FreeDirHandles: %d" TENDSTR, uffs_PoolGetFreeCount(uffs_DirEntryBufGetPool())); - - MSG("----------- statistics for '%s' -----------" TENDSTR, mount); - MSG("Device Ref: %d" TENDSTR, dev->ref_count); - MSG("Block Erased: %d" TENDSTR, s->block_erase_count); - MSG("Write Page: %d" TENDSTR, s->page_write_count); - MSG("Write Spare: %d" TENDSTR, s->spare_write_count); - MSG("Read Page: %d" TENDSTR, s->page_read_count - s->page_header_read_count); - MSG("Read Header: %d" TENDSTR, s->page_header_read_count); - MSG("Read Spare: %d" TENDSTR, s->spare_read_count); - MSG("I/O Read: %lu" TENDSTR, s->io_read); - MSG("I/O Write: %lu" TENDSTR, s->io_write); - - MSG("--------- partition info for '%s' ---------" TENDSTR, mount); - MSG("Space total: %d" TENDSTR, uffs_GetDeviceTotal(dev)); - MSG("Space used: %d" TENDSTR, uffs_GetDeviceUsed(dev)); - MSG("Space free: %d" TENDSTR, uffs_GetDeviceFree(dev)); - MSG("Page Size: %d" TENDSTR, dev->attr->page_data_size); - MSG("Spare Size: %d" TENDSTR, dev->attr->spare_size); - MSG("Pages Per Block: %d" TENDSTR, dev->attr->pages_per_block); - MSG("Block size: %d" TENDSTR, dev->attr->page_data_size * dev->attr->pages_per_block); - MSG("Total blocks: %d of %d" TENDSTR, (dev->par.end - dev->par.start + 1), dev->attr->total_blocks); - if (dev->tree.bad) { - MSG("Bad blocks: "); - node = dev->tree.bad; - while(node) { - MSG("%d, ", node->u.list.block); - node = node->u.list.next; - } - MSG(TENDSTR); - } - - uffs_PutDevice(dev); - - return 0; - -} - -/** cp <src> <des> */ -static int cmd_cp(int argc, char *argv[]) -{ - const char *src; - const char *des; - char buf[100]; - int fd1 = -1, fd2 = -1; - int len; - BOOL src_local = FALSE, des_local = FALSE; - FILE *fp1 = NULL, *fp2 = NULL; - int ret = -1; - - CHK_ARGC(3, 3); - - src = argv[1]; - des = argv[2]; - - if (memcmp(src, "::", 2) == 0) { - src += 2; - src_local = TRUE; - } - if (memcmp(des, "::", 2) == 0) { - des += 2; - des_local = TRUE; - } - - if (src_local) { - if ((fp1 = fopen(src, "rb")) == NULL) { - MSGLN("Can't open %s for copy.", src); - goto fail_ext; - } - } - else { - if ((fd1 = uffs_open(src, UO_RDONLY)) < 0) { - MSGLN("Can't open %s for copy.", src); - goto fail_ext; - } - } - - if (des_local) { - if ((fp2 = fopen(des, "wb")) == NULL) { - MSGLN("Can't open %s for copy.", des); - goto fail_ext; - } - } - else { - if ((fd2 = uffs_open(des, UO_RDWR|UO_CREATE|UO_TRUNC)) < 0) { - MSGLN("Can't open %s for copy.", des); - goto fail_ext; - } - } - - ret = 0; - while ( (src_local ? (feof(fp1) == 0) : (uffs_eof(fd1) == 0)) ) { - ret = -1; - if (src_local) { - len = fread(buf, 1, sizeof(buf), fp1); - } - else { - len = uffs_read(fd1, buf, sizeof(buf)); - } - if (len == 0) { - ret = -1; - break; - } - if (len < 0) { - MSGLN("read file %s fail ?", src); - break; - } - if (des_local) { - if ((int)fwrite(buf, 1, len, fp2) != len) { - MSGLN("write file %s fail ? ", des); - break; - } - } - else { - if (uffs_write(fd2, buf, len) != len) { - MSGLN("write file %s fail ? ", des); - break; - } - } - ret = 0; - } - -fail_ext: - if (fd1 > 0) - uffs_close(fd1); - if (fd2 > 0) - uffs_close(fd2); - if (fp1) - fclose(fp1); - if (fp2) - fclose(fp2); - - return ret; -} - -/** cat <file> [<offset>] [<size>] */ -static int cmd_cat(int argc, char *argv[]) -{ - int fd; - const char *name = NULL; - char buf[100]; - int start = 0, size = 0, printed = 0, n, len; - int ret = -1; - - CHK_ARGC(2, 4); - - name = argv[1]; - - if ((fd = uffs_open(name, UO_RDONLY)) < 0) { - MSGLN("Can't open %s", name); - goto fail; - } - - if (argc > 2) { - start = strtol(argv[2], NULL, 10); - if (argc > 3) size = strtol(argv[3], NULL, 10); - } - - if (start >= 0) - uffs_seek(fd, start, USEEK_SET); - else - uffs_seek(fd, -start, USEEK_END); - - while (uffs_eof(fd) == 0) { - len = uffs_read(fd, buf, sizeof(buf) - 1); - if (len == 0) - break; - if (len > 0) { - if (size == 0 || printed < size) { - n = (size == 0 ? len : (size - printed > len ? len : size - printed)); - buf[n] = 0; - MSG("%s", buf); - printed += n; - } - else { - break; - } - } - } - MSG(TENDSTR); - uffs_close(fd); - - ret = 0; -fail: - - return ret; -} - -/** mount partition or show mounted partitions - * mount [<mount>] - */ -static int cmd_mount(int argc, char *argv[]) -{ - uffs_MountTable *tab; - const char *mount = NULL; - - if (argc == 1) { - tab = uffs_MtbGetMounted(); - while (tab) { - MSG(" %s : (%d) ~ (%d)\n", tab->mount, tab->start_block, tab->end_block); - tab = tab->next; - } - } - else { - mount = argv[1]; - if (uffs_Mount(mount) < 0) { - MSGLN("Can't mount %s", mount); - return -1; - } - } - return 0; -} - -/** unmount parition or show unmounted partitions - * umount [<mount>] - */ -static int cmd_unmount(int argc, char *argv[]) -{ - uffs_MountTable *tab; - const char *mount = NULL; - - if (argc == 1) { - tab = uffs_MtbGetUnMounted(); - while (tab) { - MSG(" %s : (%d) ~ (%d)\n", tab->mount, tab->start_block, tab->end_block); - tab = tab->next; - } - } - else { - mount = argv[1]; - if (uffs_UnMount(mount) < 0) { - MSGLN("Can't unmount %s", mount); - return -1; - } - } - - return 0; -} - -/** inspect buffers - * inspb [<mount>] - */ -static int cmd_inspb(int argc, char *argv[]) -{ - uffs_Device *dev; - const char *mount = "/"; - - CHK_ARGC(1, 2); - - dev = uffs_GetDeviceFromMountPoint(mount); - if (dev == NULL) { - MSGLN("Can't get device from mount point %s", mount); - return -1; - } - uffs_BufInspect(dev); - uffs_PutDevice(dev); - - return 0; - -} - -/** print block wear-leveling information - * wl [<mount>] - */ -static int cmd_wl(int argc, char *argv[]) -{ - const char *mount = "/"; - uffs_Device *dev; - struct uffs_PartitionSt *par; - uffs_FileEmu *emu; - int i, max; - u32 n; - -#define NUM_PER_LINE 10 - - CHK_ARGC(1, 2); - - if (argc > 1) { - mount = argv[1]; - } - - dev = uffs_GetDeviceFromMountPoint(mount); - if (dev == NULL) { - MSGLN("Can't get device from mount point %s", mount); - return -1; - } - - par = &dev->par; - emu = (uffs_FileEmu *)(dev->attr->_private); - max = -1; - - for (i = 0; i < par->end - par->start; i++) { - if ((i % NUM_PER_LINE) == 0) { - MSG("%04d:", i + par->start); - } - n = i + par->start; - max = (max == -1 ? n : - (emu->em_monitor_block[n] > emu->em_monitor_block[max] ? n : max) - ); - MSG(" %4d", emu->em_monitor_block[n]); - if (uffs_TreeFindBadNodeByBlock(dev, n)) - MSG("%c", 'x'); - else if (uffs_TreeFindErasedNodeByBlock(dev, n)) - MSG("%c", ' '); - else - MSG("%c", '.'); - if (((i + 1) % NUM_PER_LINE) == 0) - MSG("\n"); - } - MSG("\n"); - MSG("Total blocks %d, peak erase count %d at block %d\n", - par->end - par->start, max == -1 ? 0 : emu->em_monitor_block[max], max); - - uffs_PutDevice(dev); - - return 0; -} - -static const struct cli_command helper_cmds[] = -{ - { cmd_format, "format", "[<mount>]", "Format device" }, - { cmd_mkf, "mkfile", "<name>", "create a new file" }, - { cmd_mkdir, "mkdir", "<name>", "create a new directory" }, - { cmd_rm, "rm", "<name>", "delete file/directory" }, - { cmd_ren, "mv|ren", "<old> <new>", "rename file/directory" }, - { cmd_ls, "ls", "<dir>", "list dirs and files" }, - { cmd_st, "info|st", "<mount>", "show statistic infomation" }, - { cmd_cp, "cp", "<src> <des>", "copy files. the local file name start with '::'" }, - { cmd_cat, "cat", "<name>", "show file content" }, - { cmd_pwd, "pwd", NULL, "show current dir" }, - { cmd_cd, "cd", "<path>", "change current dir" }, - { cmd_mount, "mount", "[<mount>]", "mount partition or list mounted partitions" }, - { cmd_unmount, "umount", "[<mount>]", "unmount partition" }, - { cmd_dump, "dump", "[<mount>]", "dump file system", }, - { cmd_wl, "wl", "[<mount>]", "show block wear-leveling info", }, - { cmd_inspb, "inspb", "[<mount>]", "inspect buffer", }, - { NULL, NULL, NULL, NULL } -}; - -static struct cli_commandset helper_cmdset = { - helper_cmds, -}; - -struct cli_commandset * get_helper_cmds() -{ - return &helper_cmdset; -}; diff --git a/components/dfs/filesystems/uffs/src/emu/test_cmds.c b/components/dfs/filesystems/uffs/src/emu/test_cmds.c deleted file mode 100644 index a4bc1eca41..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/test_cmds.c +++ /dev/null @@ -1,1186 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file test_cmds.c - * \brief commands for test uffs - * \author Ricky Zheng - */ -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_fd.h" -#include "uffs/uffs_utils.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs_mtb.h" -#include "uffs/uffs_find.h" -#include "uffs/uffs_badblock.h" -#include "cmdline.h" -#include "api_test.h" - -#define PFX "test: " - -#define MAX_TEST_BUF_LEN 8192 - -#define SEQ_INIT 10 -#define SEQ_MOD_LEN 120 - -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - - -static void memcp_seq(void *des, int size, int start_pos) -{ - int i; - u8 *p = (u8 *)des; - - for (i = 0; i < size; i++, p++) { - *p = (start_pos + SEQ_INIT + i) % SEQ_MOD_LEN; - } -} - -static UBOOL check_entry_exist(const char *name) -{ - struct uffs_stat sb; - - return uffs_stat(name, &sb) < 0 ? U_FALSE : U_TRUE; -} - -static URET do_write_test_file(int fd, int size) -{ - long pos; - unsigned char buf[100]; - int len; - - while (size > 0) { - pos = uffs_seek(fd, 0, USEEK_CUR); - len = (size > sizeof(buf) ? sizeof(buf) : size); - memcp_seq(buf, len, pos); - if (uffs_write(fd, buf, len) != len) { - MSGLN("Write file failed, size %d at %d", len, pos); - return U_FAIL; - } - size -= len; - } - - return U_SUCC; -} - -static URET test_write_file(const char *file_name, int pos, int size) -{ - int ret = U_FAIL; - int fd = -1; - - if ((fd = uffs_open(file_name, UO_RDWR|UO_CREATE)) < 0) { - MSGLN("Can't open file %s for write.", file_name); - goto test_exit; - } - - if (uffs_seek(fd, pos, USEEK_SET) != pos) { - MSGLN("Can't seek file %s at pos %d", file_name, pos); - goto test_failed; - } - - if (do_write_test_file(fd, size) == U_FAIL) { - MSGLN("Write file %s failed.", file_name); - goto test_failed; - } - ret = U_SUCC; - -test_failed: - uffs_close(fd); - -test_exit: - - return ret; -} - - -static URET test_verify_file(const char *file_name, UBOOL noecc) -{ - int fd; - int ret = U_FAIL; - unsigned char buf[100]; - int i, pos, len; - u8 x; - - if ((fd = uffs_open(file_name, (noecc ? UO_RDONLY|UO_NOECC : UO_RDONLY))) < 0) { - MSGLN("Can't open file %s for read.", file_name); - goto test_exit; - } - - pos = 0; - while (!uffs_eof(fd)) { - len = uffs_read(fd, buf, sizeof(buf)); - if (len <= 0) - goto test_failed; - for (i = 0; i < len; i++) { - x = (SEQ_INIT + pos + i) % SEQ_MOD_LEN; - if (buf[i] != x) { - MSGLN("Verify file %s failed at: %d, expect 0x%02x but got 0x%02x", file_name, pos + i, x, buf[i]); - goto test_failed; - } - } - pos += len; - } - - if (pos != uffs_seek(fd, 0, USEEK_END)) { - MSGLN("Verify file %s failed. invalid file length.", file_name); - goto test_failed; - } - - MSGLN("Verify file %s succ.", file_name); - ret = U_SUCC; - -test_failed: - uffs_close(fd); - -test_exit: - - return ret; -} - -static URET test_append_file(const char *file_name, int size) -{ - int ret = U_FAIL; - int fd = -1; - - if ((fd = uffs_open(file_name, UO_RDWR|UO_APPEND|UO_CREATE)) < 0) { - MSGLN("Can't open file %s for append.", file_name); - goto test_exit; - } - - uffs_seek(fd, 0, USEEK_END); - - if (do_write_test_file(fd, size) == U_FAIL) { - MSGLN("Write file %s failed.", file_name); - goto test_failed; - } - ret = U_SUCC; - -test_failed: - uffs_close(fd); - -test_exit: - - return ret; -} - - -/* test create file, write file and read back */ -static int cmd_t1(int argc, char *argv[]) -{ - int fd; - URET ret; - char buf[100]; - const char *name; - - if (argc < 2) { - return CLI_INVALID_ARG; - } - - name = argv[1]; - - fd = uffs_open(name, UO_RDWR|UO_CREATE|UO_TRUNC); - if (fd < 0) { - MSGLN("Can't open %s", name); - goto fail; - } - - sprintf(buf, "123456789ABCDEF"); - ret = uffs_write(fd, buf, strlen(buf)); - MSGLN("write %d bytes to file, content: %s", ret, buf); - - ret = uffs_seek(fd, 3, USEEK_SET); - MSGLN("new file position: %d", ret); - - memset(buf, 0, sizeof(buf)); - ret = uffs_read(fd, buf, 5); - MSGLN("read %d bytes, content: %s", ret, buf); - - uffs_close(fd); - - return 0; -fail: - - return -1; -} - - -static URET DoTest2(void) -{ - int fd = -1; - URET ret = U_FAIL; - char buf[100], buf_1[100]; - - fd = uffs_open("/abc/", UO_RDWR|UO_DIR); - if (fd < 0) { - MSGLN("Can't open dir abc, err: %d", uffs_get_error()); - MSGLN("Try to create a new one..."); - fd = uffs_open("/abc/", UO_RDWR|UO_CREATE|UO_DIR); - if (fd < 0) { - MSGLN("Can't create new dir /abc/"); - goto exit_test; - } - else { - uffs_close(fd); - } - } - else { - uffs_close(fd); - } - - fd = uffs_open("/abc/test.txt", UO_RDWR|UO_CREATE); - if (fd < 0) { - MSGLN("Can't open /abc/test.txt"); - goto exit_test; - } - - sprintf(buf, "123456789ABCDEF"); - ret = uffs_write(fd, buf, strlen(buf)); - MSGLN("write %d bytes to file, content: %s", ret, buf); - - ret = uffs_seek(fd, 3, USEEK_SET); - MSGLN("new file position: %d", ret); - - memset(buf_1, 0, sizeof(buf_1)); - ret = uffs_read(fd, buf_1, 5); - MSGLN("read %d bytes, content: %s", ret, buf_1); - - if (memcmp(buf + 3, buf_1, 5) != 0) { - ret = U_FAIL; - } - else { - ret = U_SUCC; - } - - uffs_close(fd); - -exit_test: - - return ret; -} - - -static int cmd_t2(int argc, char *argv[]) -{ - URET ret; - MSGLN("Test return: %s !", (ret = DoTest2()) == U_SUCC ? "succ" : "failed"); - - return (ret == U_SUCC) ? 0 : -1; -} - - -static int cmd_VerifyFile(int argc, char *argv[]) -{ - const char *name; - UBOOL noecc = U_FALSE; - - if (argc < 2) { - return CLI_INVALID_ARG; - } - - name = argv[1]; - if (argc > 2 && strcmp(argv[2], "noecc") == 0) { - noecc = U_TRUE; - } - - MSGLN("Check file %s ... ", name); - if (test_verify_file(name, noecc) != U_SUCC) { - MSGLN("Verify file %s failed.", name); - return -1; - } - - return 0; -} - -/* Test file append and 'random' write */ -static int cmd_t3(int argc, char *argv[]) -{ - const char *name; - int i; - UBOOL noecc = U_FALSE; - int write_test_seq[] = { 20, 10, 500, 40, 1140, 900, 329, 4560, 352, 1100 }; - - if (argc < 2) { - return CLI_INVALID_ARG; - } - - name = argv[1]; - if (argv[2] && strcmp(argv[2], "noecc") == 0) { - noecc = U_TRUE; - } - - if (check_entry_exist(name)) { - MSGLN("Check file %s ... ", name); - if (test_verify_file(name, noecc) != U_SUCC) { - MSGLN("Verify file %s failed.", name); - return -1; - } - } - - MSGLN("Test append file %s ...", name); - for (i = 1; i < 500; i += 29) { - if (test_append_file(name, i) != U_SUCC) { - MSGLN("Append file %s test failed at %d !", name, i); - return -1; - } - } - - MSGLN("Check file %s ... ", name); - if (test_verify_file(name, noecc) != U_SUCC) { - MSGLN("Verify file %s failed.", name); - return -1; - } - - MSGLN("Test write file ..."); - for (i = 0; i < sizeof(write_test_seq) / sizeof(int) - 1; i++) { - if (test_write_file(name, write_test_seq[i], write_test_seq[i+1]) != U_SUCC) { - MSGLN("Test write file failed !"); - return -1; - } - } - - MSGLN("Check file %s ... ", name); - if (test_verify_file(name, noecc) != U_SUCC) { - MSGLN("Verify file %s failed.", name); - return -1; - } - - MSGLN("Test succ !"); - - return 0; -} - -/* open two files and test write */ -static int cmd_t4(int argc, char *argv[]) -{ - int fd1 = -1, fd2 = -1; - - MSGLN("open /a ..."); - if ((fd1 = uffs_open("/a", UO_RDWR | UO_CREATE)) < 0) { - MSGLN("Can't open /a"); - goto fail_exit; - } - - MSGLN("open /b ..."); - if ((fd2 = uffs_open("/b", UO_RDWR | UO_CREATE)) < 0) { - MSGLN("Can't open /b"); - uffs_close(fd1); - goto fail_exit; - } - - MSGLN("write (1) to /a ..."); - uffs_write(fd1, "Hello,", 6); - MSGLN("write (1) to /b ..."); - uffs_write(fd2, "Hello,", 6); - MSGLN("write (2) to /a ..."); - uffs_write(fd1, "World.", 6); - MSGLN("write (2) to /b ..."); - uffs_write(fd2, "World.", 6); - MSGLN("close /a ..."); - uffs_close(fd1); - MSGLN("close /b ..."); - uffs_close(fd2); - - return 0; - -fail_exit: - return -1; -} - -/* test appending file */ -static int cmd_t5(int argc, char *argv[]) -{ - int fd = -1; - URET ret; - char buf[100]; - const char *name; - - if (argc < 2) { - return CLI_INVALID_ARG; - } - - name = argv[1]; - - fd = uffs_open(name, UO_RDWR|UO_APPEND); - if (fd < 0) { - MSGLN("Can't open %s", name); - goto fail; - } - - sprintf(buf, "append test..."); - ret = uffs_write(fd, buf, strlen(buf)); - if (ret != strlen(buf)) { - MSGLN("write file failed, %d/%d", ret, strlen(buf)); - ret = -1; - } - else { - MSGLN("write %d bytes to file, content: %s", ret, buf); - ret = 0; - } - - uffs_close(fd); - - return ret; -fail: - return -1; -} - - -/* usage: t_pgrw - * - * This test case test page read/write - */ -static int cmd_TestPageReadWrite(int argc, char *argv[]) -{ - TreeNode *node = NULL; - uffs_Device *dev; - uffs_Tags local_tag; - uffs_Tags *tag = &local_tag; - int ret; - u16 block; - u16 page; - uffs_Buf *buf = NULL; - - u32 i; - int rc = -1; - - dev = uffs_GetDeviceFromMountPoint("/"); - if (!dev) - goto ext; - - buf = uffs_BufClone(dev, NULL); - if (!buf) - goto ext; - - node = uffs_TreeGetErasedNode(dev); - if (!node) { - MSGLN("no free block ?"); - goto ext; - } - - for (i = 0; i < dev->com.pg_data_size; i++) { - buf->data[i] = i & 0xFF; - } - - block = node->u.list.block; - page = 1; - - TAG_DIRTY_BIT(tag) = TAG_DIRTY; - TAG_VALID_BIT(tag) = TAG_VALID; - TAG_DATA_LEN(tag) = dev->com.pg_data_size; - TAG_TYPE(tag) = UFFS_TYPE_DATA; - TAG_PAGE_ID(tag) = 3; - TAG_PARENT(tag) = 100; - TAG_SERIAL(tag) = 10; - TAG_BLOCK_TS(tag) = 1; - SEAL_TAG(tag); - - ret = uffs_FlashWritePageCombine(dev, block, page, buf, tag); - if (UFFS_FLASH_HAVE_ERR(ret)) { - MSGLN("Write page error: %d", ret); - goto ext; - } - - ret = uffs_FlashReadPage(dev, block, page, buf, U_FALSE); - if (UFFS_FLASH_HAVE_ERR(ret)) { - MSGLN("Read page error: %d", ret); - goto ext; - } - - for (i = 0; i < dev->com.pg_data_size; i++) { - if (buf->data[i] != (i & 0xFF)) { - MSGLN("Data verify fail at: %d", i); - goto ext; - } - } - - ret = uffs_FlashReadPageTag(dev, block, page, tag); - if (UFFS_FLASH_HAVE_ERR(ret)) { - MSGLN("Read tag (page spare) error: %d", ret); - goto ext; - } - - // verify tag: - if (!TAG_IS_SEALED(tag)) { - MSGLN("not sealed ? Tag verify fail!"); - goto ext; - } - - if (!TAG_IS_DIRTY(tag)) { - MSGLN("not dirty ? Tag verify fail!"); - goto ext; - } - - if (!TAG_IS_VALID(tag)) { - MSGLN("not valid ? Tag verify fail!"); - goto ext; - } - - if (TAG_DATA_LEN(tag) != dev->com.pg_data_size || - TAG_TYPE(tag) != UFFS_TYPE_DATA || - TAG_PAGE_ID(tag) != 3 || - TAG_PARENT(tag) != 100 || - TAG_SERIAL(tag) != 10 || - TAG_BLOCK_TS(tag) != 1) { - - MSGLN("Tag verify fail!"); - goto ext; - } - - MSGLN("Page read/write test succ."); - rc = 0; - -ext: - if (node) { - uffs_FlashEraseBlock(dev, node->u.list.block); - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, node); - else - uffs_TreeInsertToErasedListTail(dev, node); - } - - if (dev) - uffs_PutDevice(dev); - - if (buf) - uffs_BufFreeClone(dev, buf); - - return rc; -} - -/* t_format : test format partition */ -static int cmd_TestFormat(int argc, char *argv[]) -{ - URET ret; - const char *mount = "/"; - uffs_Device *dev; - UBOOL force = U_FALSE; - const char *test_file = "/a.txt"; - int fd; - int rc = -1; - - if (argc > 1) { - mount = argv[1]; - if (argc > 2 && strcmp(argv[2], "-f") == 0) - force = U_TRUE; - } - - fd = uffs_open(test_file, UO_RDWR | UO_CREATE); - if (fd < 0) { - MSGLN("can't create test file %s", test_file); - goto ext; - } - - MSGLN("Formating %s ... ", mount); - - dev = uffs_GetDeviceFromMountPoint(mount); - if (dev == NULL) { - MSGLN("Can't get device from mount point."); - goto ext; - } - else { - ret = uffs_FormatDevice(dev, force); - if (ret != U_SUCC) { - MSGLN("Format fail."); - } - else { - MSGLN("Format succ."); - rc = 0; - } - uffs_PutDevice(dev); - } - - uffs_close(fd); // this should fail on signature check ! -ext: - return rc; -} - - - -/** - * usage: t_pfs <start> <n> - * - * for example: t_pfs /x/ 100 - * - * This test case performs: - * 1) create <n> files under <start>, write full file name as file content - * 2) list files under <start>, check files are all listed once - * 3) check file content aganist file name - * 4) delete files on success - */ -static int cmd_TestPopulateFiles(int argc, char *argv[]) -{ - const char *start = "/"; - int count = 80; - int i, fd, num; - char name[128]; - char buf[128]; - uffs_DIR *dirp; - struct uffs_dirent *ent; - unsigned long bitmap[50] = {0}; // one bit per file, maximu 32*50 = 1600 files - UBOOL succ = U_TRUE; - -#define SBIT(n) bitmap[(n)/(sizeof(bitmap[0]) * 8)] |= (1 << ((n) % (sizeof(bitmap[0]) * 8))) -#define GBIT(n) (bitmap[(n)/(sizeof(bitmap[0]) * 8)] & (1 << ((n) % (sizeof(bitmap[0]) * 8)))) - - if (argc > 1) { - start = argv[1]; - if (argc > 2) { - count = strtol(argv[2], NULL, 10); - } - } - - if (count > sizeof(bitmap) * 8) - count = sizeof(bitmap) * 8; - - for (i = 0, fd = -1; i < count; i++) { - sprintf(name, "%sFile%03d", start, i); - fd = uffs_open(name, UO_RDWR|UO_CREATE|UO_TRUNC); - if (fd < 0) { - MSGLN("Create file %s failed", name); - break; - } - if (uffs_write(fd, name, strlen(name)) != strlen(name)) { // write full path name to file - MSGLN("Write to file %s failed", name); - uffs_close(fd); - break; - } - uffs_close(fd); - } - - if (i < count) { - // not success, need to clean up - for (; i >= 0; i--) { - sprintf(name, "%sFile%03d", start, i); - if (uffs_remove(name) < 0) - MSGLN("Delete file %s failed", name); - } - succ = U_FALSE; - goto ext; - } - - MSGLN("%d files created.", count); - - // list files - dirp = uffs_opendir(start); - if (dirp == NULL) { - MSGLN("Can't open dir %s !", start); - succ = U_FALSE; - goto ext; - } - ent = uffs_readdir(dirp); - while (ent && succ) { - - if (!(ent->d_type & FILE_ATTR_DIR) && // not a dir - ent->d_namelen == strlen("File000") && // check file name length - memcmp(ent->d_name, "File", strlen("File")) == 0) { // file name start with "File" - - MSGLN("List entry %s", ent->d_name); - - num = strtol(ent->d_name + 4, NULL, 10); - if (GBIT(num)) { - // file already listed ? - MSGLN("File %d listed twice !", ent->d_name); - succ = U_FALSE; - break; - } - SBIT(num); - - // check file content - sprintf(name, "%s%s", start, ent->d_name); - fd = uffs_open(name, UO_RDONLY); - if (fd < 0) { - MSGLN("Open file %d for read failed !", name); - } - else { - memset(buf, 0, sizeof(buf)); - num = uffs_read(fd, buf, sizeof(buf)); - if (num != strlen(name)) { - MSGLN("%s Read data length expect %d but got %d !", name, strlen(name), num); - succ = U_FALSE; - } - else { - if (memcmp(name, buf, num) != 0) { - MSGLN("File %s have wrong content '%s' !", name, buf); - succ = U_FALSE; - } - } - uffs_close(fd); - } - } - ent = uffs_readdir(dirp); - } - uffs_closedir(dirp); - - // check absent files - for (i = 0; i < count; i++) { - if (GBIT(i) == 0) { - sprintf(name, "%sFile%03d", start, i); - MSGLN("File %s not listed !", name); - succ = U_FALSE; - } - } - - // delete files if pass the test - for (i = 0; succ && i < count; i++) { - sprintf(name, "%sFile%03d", start, i); - if (uffs_remove(name) < 0) { - MSGLN("Delete file %s failed", name); - succ = U_FALSE; - } - } - -ext: - MSGLN("Populate files test %s !", succ ? "SUCC" : "FAILED"); - return succ ? 0 : -1; - -} - -/** - * Open <file> with <oflag>, save fd to $1 - * - * t_open <oflag> <file> - */ -static int cmd_topen(int argc, char *argv[]) -{ - int fd; - const char *name; - char *p; - int oflag = 0; - - CHK_ARGC(3, 3); - - name = argv[2]; - p = argv[1]; - while(*p) { - switch(*p++) { - case 'a': - oflag |= UO_APPEND; - break; - case 'c': - oflag |= UO_CREATE; - break; - case 't': - oflag |= UO_TRUNC; - break; - case 'w': - oflag |= UO_RDWR; - break; - case 'r': - oflag |= UO_RDONLY; - break; - } - } - - fd = uffs_open(name, oflag); - - if (fd >= 0) { - cli_env_set('1', fd); - return 0; - } - else { - return -1; - } -} - -/** - * seek file pointer - * t_seek <fd> <offset> [<origin>] - * if success, $1 = file position after seek - */ -static int cmd_tseek(int argc, char *argv[]) -{ - int origin = USEEK_SET; - int offset; - int fd; - int ret; - - CHK_ARGC(3, 4); - - if (sscanf(argv[1], "%d", &fd) != 1 || - sscanf(argv[2], "%d", &offset) != 1) - { - return CLI_INVALID_ARG; - } - - if (argc > 3) { - switch(argv[3][0]) { - case 's': - origin = USEEK_SET; - break; - case 'c': - origin = USEEK_CUR; - break; - case 'e': - origin = USEEK_END; - break; - default: - return CLI_INVALID_ARG; - } - } - - ret = uffs_seek(fd, offset, origin); - if (ret >= 0) { - cli_env_set('1', ret); - return 0; - } - else { - return -1; - } -} - -/** - * close file - * t_close <fd> - */ -static int cmd_tclose(int argc, char *argv[]) -{ - int fd; - - CHK_ARGC(2, 2); - - if (sscanf(argv[1], "%d", &fd) == 1) { - return uffs_close(fd); - } - else - return -1; -} - -/** - * write file - * t_write <fd> <txt> [..] - */ -static int cmd_twrite(int argc, char *argv[]) -{ - int fd; - int i, len = 0; - int ret = 0; - - CHK_ARGC(3, 0); - if (sscanf(argv[1], "%d", &fd) != 1) { - return -1; - } - else { - for (i = 2; i < argc; i++) { - len = strlen(argv[i]); - if (uffs_write(fd, argv[i], len) != len) { - ret = -1; - break; - } - } - } - - if (ret == 0) - cli_env_set('1', len); - - return ret; -} - -/** - * read and check seq file - * t_check_seq <fd> <size> - */ -static int cmd_tcheck_seq(int argc, char *argv[]) -{ - int fd; - int len, size; - int ret = 0, r_ret = 0; - long pos; - u8 buf[MAX_TEST_BUF_LEN]; - int i; - u8 x; - - CHK_ARGC(3, 3); - - if (sscanf(argv[1], "%d", &fd) != 1) { - return -1; - } - - if (sscanf(argv[2], "%d", &len) != 1) { - return -1; - } - - pos = uffs_tell(fd); - while (len > 0) { - size = (len > sizeof(buf) ? sizeof(buf) : len); - if ((r_ret = uffs_read(fd, buf, size)) < 0) { - MSGLN("Read fail! fd = %d, size = %d, pos = %ld", fd, size, pos); - ret = -1; - break; - } - - // check seq - for (i = 0; i < r_ret; i++) { - x = (pos + SEQ_INIT + i) % SEQ_MOD_LEN; - if (buf[i] != x) { - MSGLN("Check fail! fd = %d, pos = %ld (expect 0x%02x but 0x%02x)\n", fd, pos + i, x, buf[i]); - ret = -1; - break; - } - } - - if (ret < 0) - break; - - len -= r_ret; - pos += r_ret; - } - - return ret; -} - - - -/** - * write random seq to file - * t_write_seq <fd> <size> - */ -static int cmd_twrite_seq(int argc, char *argv[]) -{ - int fd; - int len = 0, size = 0; - long pos = 0; - int ret = 0, w_ret = 0; - u8 buf[MAX_TEST_BUF_LEN]; - - CHK_ARGC(3, 3); - if (sscanf(argv[1], "%d", &fd) != 1) { - return -1; - } - - if (sscanf(argv[2], "%d", &len) != 1) { - return -1; - } - - pos = uffs_tell(fd); - while (len > 0) { - size = (len < sizeof(buf) ? len : sizeof(buf)); - memcp_seq(buf, size, pos); - if ((w_ret = uffs_write(fd, buf, size)) < 0) { - MSGLN("write fail! fd = %d, size = %d, pos = %ld", fd, size, pos); - ret = -1; - break; - } - pos += w_ret; - len -= w_ret; - } - - if (ret == 0) - cli_env_set('1', len); - - return ret; -} - - -/** - * read and check file - * t_read <fd> <txt> - */ -static int cmd_tread(int argc, char *argv[]) -{ - int fd; - int len, n; - int ret = 0; - char buf[64]; - char *p; - - CHK_ARGC(3, 3); - - if (sscanf(argv[1], "%d", &fd) != 1) { - return -1; - } - else { - len = strlen(argv[2]); - n = 0; - p = argv[2]; - while (n < len) { - n = (len > sizeof(buf) ? sizeof(buf) : len); - if (uffs_read(fd, buf, n) != n || - memcmp(buf, p, n) != 0) { - ret = -1; - break; - } - len -= n; - p += n; - } - } - - return ret; -} - - -static void do_dump_page(uffs_Device *dev, uffs_Buf *buf) -{ - int i, j; - const int line = 16; - struct uffs_MiniHeaderSt *header = (struct uffs_MiniHeaderSt *)buf->header; - MSG(" header.status = %d\n", header->status); - if (header->status != 0xFF) { - for (i = 0; i < 64; i += line) { - MSG(" "); - for (j = 0; j < line; j++) - MSG("%02X ", buf->header[i+j]); - MSG("\n"); - } - MSG("\n"); - } -} - -static void do_dump_tag(uffs_Device *dev, uffs_Tags *tag) -{ - MSG(" tag sealed: %s\n", TAG_IS_SEALED(tag) ? "yes" : "no"); - if (TAG_IS_GOOD(tag)) { - if (TAG_IS_DIRTY(tag)) { - MSG(" block_ts = %d\n", tag->s.block_ts); - MSG(" type = %d\n", tag->s.type); - MSG(" dirty = %d\n", tag->s.dirty); - MSG(" page_id = %d\n", tag->s.page_id); - MSG(" serial = %d\n", tag->s.serial); - MSG(" parent = %d\n", tag->s.parent); - MSG(" data_len = %d\n", tag->s.data_len); - } - else { - MSG(" tag is GOOD but NOT DIRTY !!!???\n"); - } - } - else if (TAG_IS_SEALED(tag)) { - MSG(" tag is INVALID\n"); - } -} - -static void do_dump_device(uffs_Device *dev) -{ - URET ret; - int block, page; - uffs_Tags tag; - uffs_Buf *buf; - - buf = uffs_BufClone(dev, NULL); - if (buf == NULL) { - MSGLN("Can't clone buf"); - return; - } - - for (block = dev->par.start; block <= dev->par.end; block++) { - MSG("---- block %d ----\n", block); - for (page = 0; page < dev->attr->pages_per_block; page++) { - MSG(" == page %d ==\n", page); - ret = uffs_FlashReadPage(dev, block, page, buf, U_FALSE); - if (UFFS_FLASH_HAVE_ERR(ret)) { - MSG(" !!! Read page failed, ret = %d !!!\n", ret); - } - else { - do_dump_page(dev, buf); - if (buf->header[0] != 0xFF) { - ret = uffs_FlashReadPageTag(dev, block, page, &tag); - if (UFFS_FLASH_HAVE_ERR(ret)) { - MSG(" !!! Read TAG failed, ret = %d !!!\n", ret); - } - else { - do_dump_tag(dev, &tag); - } - } - } - } - } - uffs_BufFreeClone(dev, buf); -} - -static int cmd_dump(int argc, char *argv[]) -{ - const char *mount = "/"; - uffs_Device *dev; - - if (argc > 1) { - mount = argv[1]; - } - - MSGLN("Dumping %s ... ", mount); - - dev = uffs_GetDeviceFromMountPoint(mount); - if (dev == NULL) { - MSGLN("Can't get device from mount point."); - } - else { - do_dump_device(dev); - uffs_PutDevice(dev); - } - - return 0; -} - -static int cmd_apisrv(int argc, char *argv[]) -{ - return api_server_start(); -} - -static const struct cli_command test_cmds[] = -{ - { cmd_t1, "t1", "<name>", "test 1" }, - { cmd_t2, "t2", NULL, "test 2" }, - { cmd_t3, "t3", "<name> [<noecc>]", "test 3" }, - { cmd_t4, "t4", NULL, "test 4" }, - { cmd_t5, "t5", "<name>", "test 5" }, - { cmd_TestPageReadWrite, "t_pgrw", NULL, "test page read/write" }, - { cmd_TestFormat, "t_format", NULL, "test format file system" }, - { cmd_TestPopulateFiles, "t_pfs", "[<start> [<n>]]", "test populate <n> files under <start>" }, - { cmd_VerifyFile, "t_vf", "<file> [<noecc>]", "verify file" }, - - { cmd_topen, "t_open", "<oflg> <file>", "open file, fd save to $1", }, - { cmd_tread, "t_read", "<fd> <txt>", "read <fd> and check against <txt>", }, - { cmd_tcheck_seq, "t_check_seq", "<fd> <size>", "read seq file <fd> and check", }, - { cmd_twrite, "t_write", "<fd> <txt> [...]", "write <fd>", }, - { cmd_twrite_seq, "t_write_seq", "<fd> <size>", "write seq file <fd>", }, - { cmd_tseek, "t_seek", "<fd> <offset> [<origin>]", "seek <fd> file pointer to <offset> from <origin>", }, - { cmd_tclose, "t_close", "<fd>", "close <fd>", }, - { cmd_dump, "dump", "<mount>", "dump <mount>", }, - - { cmd_apisrv, "apisrv", NULL, "start API test server", }, - - { NULL, NULL, NULL, NULL } -}; - -static struct cli_commandset test_cmdset = { - test_cmds, -}; - -struct cli_commandset * get_test_cmds() -{ - return &test_cmdset; -}; - - - diff --git a/components/dfs/filesystems/uffs/src/emu/uffs_fileem.c b/components/dfs/filesystems/uffs/src/emu/uffs_fileem.c deleted file mode 100644 index 1f66cdf846..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/uffs_fileem.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fileem.c - * \brief emulate uffs file system - * \author Ricky Zheng, created 9th May, 2005 - */ - - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_device.h" -#include "uffs_fileem.h" - -#define PFX "femu: " -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - - -static struct uffs_StorageAttrSt g_femu_storage = {0}; - -static struct uffs_FileEmuSt g_femu_private = {0}; - - -struct uffs_StorageAttrSt * femu_GetStorage() -{ - return &g_femu_storage; -} - -struct uffs_FileEmuSt *femu_GetPrivate() -{ - return &g_femu_private; -} - -URET femu_InitDevice(uffs_Device *dev) -{ - uffs_FileEmu *emu = femu_GetPrivate(); - - // setup device storage attr and private data structure. - // all femu partition share one storage attribute - - dev->attr = femu_GetStorage(); - dev->attr->_private = (void *) emu; - - // setup flash driver operations, according to the ecc option. - switch(dev->attr->ecc_opt) { - case UFFS_ECC_NONE: - case UFFS_ECC_SOFT: - dev->ops = &g_femu_ops_ecc_soft; - break; - case UFFS_ECC_HW: - dev->ops = &g_femu_ops_ecc_hw; - break; - case UFFS_ECC_HW_AUTO: - dev->ops = &g_femu_ops_ecc_hw_auto; - break; - default: - break; - } - -#ifdef UFFS_FEMU_ENABLE_INJECTION - // setup wrap functions, for inject ECC errors, etc. - // check wrap_inited so that multiple devices can share the same driver - if (!emu->wrap_inited) { - femu_setup_wrapper_functions(dev); - emu->wrap_inited = U_TRUE; - } -#endif - - return U_SUCC; -} - -/* Nothing to do here */ -URET femu_ReleaseDevice(uffs_Device *dev) -{ - return U_SUCC; -} - - -///////////////////////////////////////////////////////////////////////////////// diff --git a/components/dfs/filesystems/uffs/src/emu/uffs_fileem.h b/components/dfs/filesystems/uffs/src/emu/uffs_fileem.h deleted file mode 100644 index 8be7f3e838..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/uffs_fileem.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fileem.h - * \brief Emulate NAND flash with host file. - * \author Ricky Zheng - */ - -#ifndef _UFFS_FILEEM_H_ -#define _UFFS_FILEEM_H_ - -#include "uffs/uffs_device.h" - -#define UFFS_FEMU_FILE_NAME "uffsemfile.bin" - -#define UFFS_FEMU_MAX_BLOCKS (1024 * 16) // maximum 16K blocks - -#define UFFS_FEMU_ENABLE_INJECTION // enable bad block & ecc error injection - -extern struct uffs_FlashOpsSt g_femu_ops_ecc_soft; // for software ECC or no ECC. -extern struct uffs_FlashOpsSt g_femu_ops_ecc_hw; // for hardware ECC -extern struct uffs_FlashOpsSt g_femu_ops_ecc_hw_auto; // for auto hardware ECC - -#define PAGE_DATA_WRITE_COUNT_LIMIT 1 -#define PAGE_SPARE_WRITE_COUNT_LIMIT 1 - -typedef struct uffs_FileEmuSt { - int initCount; - FILE *fp; - FILE *dump_fp; - u8 *em_monitor_page; // page write monitor - u8 * em_monitor_spare; // spare write monitor - u32 *em_monitor_block; // block erease monitor - const char *emu_filename; -#ifdef UFFS_FEMU_ENABLE_INJECTION - struct uffs_FlashOpsSt ops_orig; - UBOOL wrap_inited; -#endif -} uffs_FileEmu; - -/* file emulator device init/release entry */ -URET femu_InitDevice(uffs_Device *dev); -URET femu_ReleaseDevice(uffs_Device *dev); - -struct uffs_StorageAttrSt * femu_GetStorage(void); -struct uffs_FileEmuSt * femu_GetPrivate(void); - -#ifdef UFFS_FEMU_ENABLE_INJECTION -void femu_setup_wrapper_functions(uffs_Device *dev); -#endif - -/* internal used functions, shared by all ecc option implementations */ -int femu_InitFlash(uffs_Device *dev); -int femu_ReleaseFlash(uffs_Device *dev); -int femu_EraseBlock(uffs_Device *dev, u32 blockNumber); - -#endif - diff --git a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw.c b/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw.c deleted file mode 100644 index c7781ebe66..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2010 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fileem_ecc_hw.c - * \brief emulate uffs file system for hardware ECC. - * - * In this emulator, we call 'uffs_FlashMakeSpare()' to do the layout job - * and call 'uffs_EccMake()' to calculate ECC. - * - * \author Ricky Zheng @ Oct, 2010 - */ - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_device.h" -#include "uffs_fileem.h" -#include "uffs/uffs_ecc.h" - -#define PFX "femu: " -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - -static int femu_hw_WritePageWithLayout(uffs_Device *dev, u32 block, u32 page, - const u8 *data, int data_len, const u8 *ecc, const uffs_TagStore *ts) -{ - int written; - int abs_page; - int full_page_size; - uffs_FileEmu *emu; - struct uffs_StorageAttrSt *attr = dev->attr; - u8 spare[UFFS_MAX_SPARE_SIZE]; - u8 ecc_buf[UFFS_MAX_ECC_SIZE]; - int spare_len; - - - emu = (uffs_FileEmu *)(dev->attr->_private); - - if (!emu || !(emu->fp)) { - goto err; - } - - abs_page = attr->pages_per_block * block + page; - full_page_size = attr->page_data_size + attr->spare_size; - - if (data && data_len > 0) { - if (data_len > attr->page_data_size) - goto err; - - emu->em_monitor_page[abs_page]++; - if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) { - MSG("Warrning: block %d page %d exceed it's maximum write time!", block, page); - goto err; - } - - fseek(emu->fp, abs_page * full_page_size, SEEK_SET); - - written = fwrite(data, 1, data_len, emu->fp); - - if (written != data_len) { - MSG("write page I/O error ?"); - goto err; - } - - dev->st.page_write_count++; - dev->st.io_write += written; - - } - - if (ts) { - - emu->em_monitor_spare[abs_page]++; - if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) { - MSG("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page); - goto err; - } - - if (!uffs_Assert(data != NULL, "BUG: Write spare without data ?")) - goto err; - - uffs_EccMake(data, data_len, ecc_buf); - uffs_FlashMakeSpare(dev, ts, ecc_buf, spare); - spare_len = dev->mem.spare_data_size; - - fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET); - written = fwrite(spare, 1, spare_len, emu->fp); - if (written != spare_len) { - MSG("write spare I/O error ?"); - goto err; - } - - dev->st.spare_write_count++; - dev->st.io_write += written; - } - - if (data == NULL && ts == NULL) { - // mark bad block - fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET); - written = fwrite("\0", 1, 1, emu->fp); - if (written != 1) { - MSG("write bad block mark I/O error ?"); - goto err; - } - dev->st.io_write++; - } - - fflush(emu->fp); - return UFFS_FLASH_NO_ERR; -err: - fflush(emu->fp); - return UFFS_FLASH_IO_ERR; -} - - -static URET femu_hw_ReadPageWithLayout(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc, - uffs_TagStore *ts, u8 *ecc_store) -{ - int nread; - uffs_FileEmu *emu; - int abs_page; - int full_page_size; - struct uffs_StorageAttrSt *attr = dev->attr; - unsigned char status; - u8 spare[UFFS_MAX_SPARE_SIZE]; - int spare_len; - - emu = (uffs_FileEmu *)(dev->attr->_private); - - if (!emu || !(emu->fp)) { - goto err; - } - - abs_page = attr->pages_per_block * block + page; - full_page_size = attr->page_data_size + attr->spare_size; - - if (data && data_len > 0) { - if (data_len > attr->page_data_size) - goto err; - - fseek(emu->fp, abs_page * full_page_size, SEEK_SET); - nread = fread(data, 1, data_len, emu->fp); - - if (nread != data_len) { - MSG("read page I/O error ?"); - goto err; - } - dev->st.io_read += nread; - dev->st.page_read_count++; - - if (ecc) { - // calculate ECC for data - uffs_EccMake(data, data_len, ecc); - } - } - - if (ts) { - - spare_len = dev->mem.spare_data_size; - fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET); - nread = fread(spare, 1, spare_len, emu->fp); - - if (nread != spare_len) { - MSG("read page spare I/O error ?"); - goto err; - } - - // unload ts and ecc from spare - uffs_FlashUnloadSpare(dev, spare, ts, ecc_store); - - dev->st.io_read += nread; - dev->st.spare_read_count++; - } - - if (data == NULL && ts == NULL) { - // read bad block mark - fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET); - nread = fread(&status, 1, 1, emu->fp); - - if (nread != 1) { - MSG("read badblock mark I/O error ?"); - goto err; - } - dev->st.io_read++; - - return status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK; - } - - return UFFS_FLASH_NO_ERR; -err: - return UFFS_FLASH_IO_ERR; -} - - -uffs_FlashOps g_femu_ops_ecc_hw = { - femu_InitFlash, // InitFlash() - femu_ReleaseFlash, // ReleaseFlash() - NULL, // ReadPage() - femu_hw_ReadPageWithLayout, // ReadPageWithLayout() - NULL, // WritePage() - femu_hw_WritePageWithLayout,// WritePageWithLayout() - NULL, // IsBadBlock(), let UFFS take care of it. - NULL, // MarkBadBlock(), let UFFS take care of it. - femu_EraseBlock, // EraseBlock() -}; diff --git a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw_auto.c b/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw_auto.c deleted file mode 100644 index 31fbb28c95..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_hw_auto.c +++ /dev/null @@ -1,356 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2010 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fileem_ecc_hw_auto.c - * - * \brief Emulate uffs file system for auto hardware ECC or RS error collection. - * - * This emulator emulate LPC32x0 MLC NAND controller which generate 10 bytes - * Reed-Solomon error correction code (RS-ECC) for every 518 bytes data. - * - * For small page MLC have 16 bytes spare area leves only 6 bytes for 'meta-data', - * no enough room for UFFS's 8 bytes tag and bad block mark. For this reason, - * we adjust page data/spare boundary to 508/20. - * - * This emulator does not calculate real RS-ECC code, instead, we use software ECC - * to calculate 6 bytes ECC code, so this solution does not have the same error - * correcting cabability of RS-ECC. - * - * Note: the MLC controller strictly require sequencial access to serial data buffer. - * - * \author Ricky Zheng @ Oct, 2010 - */ - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_ecc.h" -#include "uffs_fileem.h" - -#define PFX "femu: " -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - -#define RS_ECC_SIZE 10 -#define PAGE_DATA_SIZE 508 -#define PAGE_SPARE_SIZE 20 -#define PAGE_FULL_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE) -static u8 g_sdata_buf[PAGE_FULL_SIZE]; // emulating LPC32x0's 528-bytes serial data buffer - -static int g_sdata_buf_pointer = 0; - -static void start_sdata_access() -{ - g_sdata_buf_pointer = 0; -} - -static void feed_sdata(const u8 *data, int len) -{ - if (!uffs_Assert(g_sdata_buf_pointer + len <= sizeof(g_sdata_buf), "BUG: Serial Data Buffer overflow !!")) - return; - - if (data) - memcpy(g_sdata_buf + g_sdata_buf_pointer, data, len); - g_sdata_buf_pointer += len; -} - -static void feed_sdata_constant(u8 val, int num) -{ - if (!uffs_Assert(g_sdata_buf_pointer + num <= sizeof(g_sdata_buf), "BUG: Serial Data Buffer overflow !!")) - return; - - memset(g_sdata_buf + g_sdata_buf_pointer, val, num); - g_sdata_buf_pointer += num; -} - -static void drain_sdata(u8 *data, int len) -{ - if (!uffs_Assert( (int)sizeof(g_sdata_buf) - g_sdata_buf_pointer >= len, "BUG: Serial Data Buffer overdrain !!")) - return; - - if (data) - memcpy(data, g_sdata_buf + g_sdata_buf_pointer, len); - g_sdata_buf_pointer += len; -} - -static int load_sdata(uffs_Device *dev, int block, int page) -{ - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - int abs_page; - struct uffs_StorageAttrSt *attr = dev->attr; - int nread; - int ret; - u8 ecc_buf[RS_ECC_SIZE]; - u8 *ecc_store; - - abs_page = attr->pages_per_block * block + page; - - fseek(emu->fp, abs_page * PAGE_FULL_SIZE, SEEK_SET); - nread = fread(g_sdata_buf, 1, PAGE_FULL_SIZE, emu->fp); - g_sdata_buf_pointer = 0; - - ret = ((nread == PAGE_FULL_SIZE) ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR); - - if (ret == UFFS_FLASH_NO_ERR) { - - // Perform ECC check & correction - // In the real world, this is done by MLC controller hardware - memset(ecc_buf, 0xFF, RS_ECC_SIZE); - uffs_EccMake(g_sdata_buf, attr->page_data_size, ecc_buf); - - ecc_store = g_sdata_buf + PAGE_FULL_SIZE - RS_ECC_SIZE; - - ret = uffs_EccCorrect(g_sdata_buf, attr->page_data_size, ecc_store, ecc_buf); - - ret = (ret < 0 ? UFFS_FLASH_ECC_FAIL : - (ret > 0 ? UFFS_FLASH_ECC_OK : UFFS_FLASH_NO_ERR)); - - } - - return ret; -} - -static int program_sdata(uffs_Device *dev, int block, int page) -{ - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - int abs_page; - struct uffs_StorageAttrSt *attr = dev->attr; - u8 ecc_buf[RS_ECC_SIZE]; - int writtern = 0; - - // In the real world, MLC controller will generate RS-ECC code in serial data buffer - // and might start auto programing NAND flash. Here, we use software ECC to emulate RS-ECC. - memset(ecc_buf, 0xFF, sizeof(ecc_buf)); - uffs_EccMake(g_sdata_buf, attr->page_data_size, ecc_buf); - feed_sdata(ecc_buf, RS_ECC_SIZE); - - if (!uffs_Assert(g_sdata_buf_pointer == PAGE_FULL_SIZE, "Serial Data Buffer is not fully filled !!")) - goto ext; - - abs_page = attr->pages_per_block * block + page; - - fseek(emu->fp, abs_page * PAGE_FULL_SIZE, SEEK_SET); - writtern = fwrite(g_sdata_buf, 1, PAGE_FULL_SIZE, emu->fp); -ext: - return (writtern == PAGE_FULL_SIZE) ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR; -} - - -static int femu_hw_auto_InitFlash(uffs_Device *dev) -{ - struct uffs_StorageAttrSt *attr = dev->attr; - - // now this is a good chance to adjust page data/spare boundary - if (attr->page_data_size + attr->spare_size != PAGE_FULL_SIZE) { - MSGLN("This emulator emulates only for page size %d bytes !", PAGE_FULL_SIZE); - return -1; - } - if (attr->spare_size < PAGE_SPARE_SIZE) { - attr->page_data_size -= (PAGE_SPARE_SIZE - attr->spare_size); - attr->spare_size = PAGE_SPARE_SIZE; - MSGLN("Adjust page data/spare boundary to %d/%d", attr->page_data_size, attr->spare_size); - } - - // and fix ECC size - attr->ecc_size = RS_ECC_SIZE; - MSGLN("Adjust ECC size to %d bytes", attr->ecc_size); - - return femu_InitFlash(dev); -} - - -static int femu_hw_auto_WritePageWithLayout(uffs_Device *dev, u32 block, u32 page, - const u8 *data, int data_len, const u8 *ecc, const uffs_TagStore *ts) -{ - int abs_page; - uffs_FileEmu *emu; - struct uffs_StorageAttrSt *attr = dev->attr; - u8 spare[PAGE_SPARE_SIZE]; - int ret = UFFS_FLASH_IO_ERR; - - emu = (uffs_FileEmu *)(dev->attr->_private); - - if (!emu || !(emu->fp)) { - goto err; - } - - abs_page = attr->pages_per_block * block + page; - - start_sdata_access(); - - dev->st.page_write_count++; - dev->st.spare_write_count++; - dev->st.io_write += PAGE_FULL_SIZE; - - if (data || ts) { - // normal page write - if (data && data_len > 0) { - if (data_len > attr->page_data_size) - goto err; - - emu->em_monitor_page[abs_page]++; - if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) { - MSGLN("Warrning: block %d page %d exceed it's maximum write time!", block, page); - goto err; - } - - // Copy data to serial data buffer - feed_sdata(data, data_len); - - // Pad the rest data as 0xFF - feed_sdata_constant(0xFF, attr->page_data_size - data_len); - - } - else { - // We still need to feed data to serial data buffer to make MLC controller happy - // The current UFFS won't write ts only, so we'll never run to here. - feed_sdata_constant(0xFF, attr->page_data_size); - } - - if (ts) { - - emu->em_monitor_spare[abs_page]++; - if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) { - MSGLN("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page); - goto err; - } - - memset(spare, 0xFF, sizeof(spare)); - uffs_FlashMakeSpare(dev, ts, NULL, spare); // do not pack ECC, as MLC controller will - // automatically write RS-ECC to the latest 10 bytes. - - // feed spare data to serial data buffer - feed_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE); - } - } - else { - // mark bad block - - // feed data to serial data buffer to make MLC controller happy - feed_sdata_constant(0xFF, attr->page_data_size); - - memset(spare, 0xFF, sizeof(spare)); - spare[attr->block_status_offs] = 0; - - // feed spare data to serial data buffer - feed_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE); - - dev->st.io_write++; - } - - // now, program serial data buffer to NAND flash - ret = program_sdata(dev, block, page); - - fflush(emu->fp); - return ret; -err: - fflush(emu->fp); - return ret; -} - - -static URET femu_hw_auto_ReadPageWithLayout(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc, - uffs_TagStore *ts, u8 *ecc_store) -{ - uffs_FileEmu *emu; - int abs_page; - struct uffs_StorageAttrSt *attr = dev->attr; - unsigned char status; - u8 spare[PAGE_SPARE_SIZE]; - int ret = UFFS_FLASH_IO_ERR; - - emu = (uffs_FileEmu *)(dev->attr->_private); - - if (!emu || !(emu->fp)) { - goto ext; - } - - abs_page = attr->pages_per_block * block + page; - - // now load full page to serial data buffer - ret = load_sdata(dev, block, page); - if (ret != UFFS_FLASH_NO_ERR) - goto ext; - - start_sdata_access(); - - dev->st.io_read += PAGE_FULL_SIZE; - dev->st.page_read_count++; - dev->st.spare_read_count++; - - if (data || ts) { - - if (data && data_len > 0) { - if (data_len > attr->page_data_size) - goto ext; - - drain_sdata(data, data_len); - } - - if (ts) { - if (g_sdata_buf_pointer < attr->page_data_size) - drain_sdata(NULL, attr->page_data_size - g_sdata_buf_pointer); - - drain_sdata(spare, PAGE_SPARE_SIZE - RS_ECC_SIZE); - - // unload ts from spare - uffs_FlashUnloadSpare(dev, spare, ts, NULL); - } - } - else { - // read bad block mark - drain_sdata(NULL, attr->page_data_size + attr->block_status_offs - 1); - drain_sdata(&status, 1); - - ret = (status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK); - } - -ext: - return ret; -} - - -uffs_FlashOps g_femu_ops_ecc_hw_auto = { - femu_hw_auto_InitFlash, // InitFlash() - femu_ReleaseFlash, // ReleaseFlash() - NULL, // ReadPage() - femu_hw_auto_ReadPageWithLayout, // ReadPageWithLayout() - NULL, // WritePage() - femu_hw_auto_WritePageWithLayout, // WritePageWithLayout() - NULL, // IsBadBlock(), let UFFS take care of it. - NULL, // MarkBadBlock(), let UFFS take care of it. - femu_EraseBlock, // EraseBlock() -}; diff --git a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_soft.c b/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_soft.c deleted file mode 100644 index 0a24c1cf3b..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_ecc_soft.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2010 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fileem_ecc_soft.c - * \brief emulate uffs file system for software ECC - * \author Ricky Zheng @ Oct, 2010 - */ - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_flash.h" -#include "uffs_fileem.h" - -#define PFX "femu: " -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - -static int femu_WritePage(uffs_Device *dev, u32 block, u32 page_num, - const u8 *data, int data_len, const u8 *spare, int spare_len) -{ - int written; - int abs_page; - int full_page_size; - uffs_FileEmu *emu; - struct uffs_StorageAttrSt *attr = dev->attr; - - emu = (uffs_FileEmu *)(dev->attr->_private); - - if (!emu || !(emu->fp)) { - goto err; - } - - abs_page = attr->pages_per_block * block + page_num; - full_page_size = attr->page_data_size + attr->spare_size; - - if (data && data_len > 0) { - if (data_len > attr->page_data_size) - goto err; - - emu->em_monitor_page[abs_page]++; - if (emu->em_monitor_page[abs_page] > PAGE_DATA_WRITE_COUNT_LIMIT) { - MSGLN("Warrning: block %d page %d exceed it's maximum write time!", block, page_num); - goto err; - } - - fseek(emu->fp, abs_page * full_page_size, SEEK_SET); - - written = fwrite(data, 1, data_len, emu->fp); - - if (written != data_len) { - MSGLN("write page I/O error ?"); - goto err; - } - - dev->st.page_write_count++; - dev->st.io_write += written; - } - - if (spare && spare_len > 0) { - if (spare_len > attr->spare_size) - goto err; - - emu->em_monitor_spare[abs_page]++; - if (emu->em_monitor_spare[abs_page] > PAGE_SPARE_WRITE_COUNT_LIMIT) { - MSGLN("Warrning: block %d page %d (spare) exceed it's maximum write time!", block, page_num); - goto err; - } - - fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET); - written = fwrite(spare, 1, spare_len, emu->fp); - if (written != spare_len) { - MSGLN("write spare I/O error ?"); - goto err; - } - - dev->st.spare_write_count++; - dev->st.io_write += written; - } - - if (data == NULL && spare == NULL) { - // mark bad block - fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET); - written = fwrite("\0", 1, 1, emu->fp); - if (written != 1) { - MSGLN("write bad block mark I/O error ?"); - goto err; - } - dev->st.io_write++; - } - - fflush(emu->fp); - return UFFS_FLASH_NO_ERR; -err: - fflush(emu->fp); - return UFFS_FLASH_IO_ERR; -} - - -static URET femu_ReadPage(uffs_Device *dev, u32 block, u32 page_num, u8 *data, int data_len, u8 *ecc, - u8 *spare, int spare_len) -{ - int nread; - uffs_FileEmu *emu; - int abs_page; - int full_page_size; - struct uffs_StorageAttrSt *attr = dev->attr; - unsigned char status; - - emu = (uffs_FileEmu *)(dev->attr->_private); - - if (!emu || !(emu->fp)) { - goto err; - } - - abs_page = attr->pages_per_block * block + page_num; - full_page_size = attr->page_data_size + attr->spare_size; - - if (data && data_len > 0) { - if (data_len > attr->page_data_size) - goto err; - - fseek(emu->fp, abs_page * full_page_size, SEEK_SET); - nread = fread(data, 1, data_len, emu->fp); - - if (nread != data_len) { - MSGLN("read page I/O error ?"); - goto err; - } - dev->st.io_read += nread; - dev->st.page_read_count++; - } - - if (spare && spare_len > 0) { - if (spare_len > attr->spare_size) - goto err; - - fseek(emu->fp, abs_page * full_page_size + attr->page_data_size, SEEK_SET); - nread = fread(spare, 1, spare_len, emu->fp); - - if (nread != spare_len) { - MSGLN("read page spare I/O error ?"); - goto err; - } - dev->st.io_read += nread; - dev->st.spare_read_count++; - } - - if (data == NULL && spare == NULL) { - // read bad block mark - fseek(emu->fp, abs_page * full_page_size + attr->page_data_size + attr->block_status_offs, SEEK_SET); - nread = fread(&status, 1, 1, emu->fp); - - if (nread != 1) { - MSGLN("read badblock mark I/O error ?"); - goto err; - } - dev->st.io_read++; - - return status == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK; - } - - return UFFS_FLASH_NO_ERR; -err: - return UFFS_FLASH_IO_ERR; -} - - -uffs_FlashOps g_femu_ops_ecc_soft = { - femu_InitFlash, // InitFlash() - femu_ReleaseFlash, // ReleaseFlash() - femu_ReadPage, // ReadPage() - NULL, // ReadPageWithLayout - femu_WritePage, // WritePage() - NULL, // WritePageWithLayout - NULL, // IsBadBlock(), let UFFS take care of it. - NULL, // MarkBadBlock(), let UFFS take care of it. - femu_EraseBlock, // EraseBlock() -}; diff --git a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_share.c b/components/dfs/filesystems/uffs/src/emu/uffs_fileem_share.c deleted file mode 100644 index 6bd759bb82..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_share.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fileem_share.c - * \brief emulate uffs file system, shared functions - * \author Ricky Zheng, created Nov, 2010 - */ - - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_device.h" -#include "uffs_fileem.h" - -#define PFX "femu: " - -/****************************************************************/ -/* Shared flash driver functions: */ -/* */ -/* femu_InitFlash(), femu_ReleaseFlash(), femu_EraseBlock() */ -/* */ -/****************************************************************/ - -static u8 g_page_buf[UFFS_MAX_PAGE_SIZE + UFFS_MAX_SPARE_SIZE]; - -/* - * Create emulator disk, initialise monitors, inject manufacture bad blocks, etc. - * - */ -int femu_InitFlash(uffs_Device *dev) -{ - int i; - int fSize; - int written; - u8 * p = g_page_buf; - uffs_FileEmu *emu; - - struct uffs_StorageAttrSt *attr = dev->attr; - - int full_page_size = attr->page_data_size + attr->spare_size; - int total_pages = attr->total_blocks * attr->pages_per_block; - - emu = (uffs_FileEmu *)(dev->attr->_private); - - if (emu->initCount > 0) { - emu->initCount++; - return 0; - } - - if (emu->emu_filename == NULL) - emu->emu_filename = UFFS_FEMU_FILE_NAME; - - uffs_Perror(UFFS_MSG_NORMAL, "femu device init."); - - emu->em_monitor_page = (u8 *) malloc(sizeof(emu->em_monitor_page[0]) * total_pages); - if (!emu->em_monitor_page) - return -1; - emu->em_monitor_spare = (u8 *) malloc(sizeof(emu->em_monitor_spare[0]) * total_pages); - if (!emu->em_monitor_spare) - return -1; - - emu->em_monitor_block = (u32 *) malloc(sizeof(emu->em_monitor_block[0]) * attr->total_blocks); - if (!emu->em_monitor_block) - return -1; - - //clear monitor - memset(emu->em_monitor_page, 0, sizeof(emu->em_monitor_page[0]) * total_pages); - memset(emu->em_monitor_spare, 0, sizeof(emu->em_monitor_spare[0]) * total_pages); - memset(emu->em_monitor_block, 0, sizeof(emu->em_monitor_block[0]) * attr->total_blocks); - - emu->fp = fopen(emu->emu_filename, "rb"); - if (emu->fp == NULL) { - emu->fp = fopen(emu->emu_filename, "ab+"); - if (emu->fp == NULL) { - printf(PFX"Failed to create uffs emulation file."); - return -1; - } - - fseek(emu->fp, 0, SEEK_END); - fSize = ftell(emu->fp); - - if (fSize < total_pages * full_page_size) { - printf("Creating uffs emulation file\n"); - fseek(emu->fp, 0, SEEK_SET); - memset(p, 0xff, full_page_size); - for (i = 0; i < total_pages; i++) { - written = fwrite(p, 1, full_page_size, emu->fp); - if (written != full_page_size) { - printf("Write failed\n"); - fclose(emu->fp); - emu->fp = NULL; - return -1; - } - } - } - } - - fflush(emu->fp); - fclose(emu->fp); - - emu->fp = fopen(emu->emu_filename, "rb+"); - if (emu->fp == NULL) { - printf(PFX"Can't open emulation file.\n"); - return -1; - } - - emu->initCount++; - - return 0; -} - -/* - * Release resources - */ -int femu_ReleaseFlash(uffs_Device *dev) -{ - uffs_FileEmu *emu; - - emu = (uffs_FileEmu *)(dev->attr->_private); - - emu->initCount--; - - if (emu->initCount == 0) { - - uffs_Perror(UFFS_MSG_NORMAL, "femu device release."); - - if (emu->fp) { - fclose(emu->fp); - emu->fp = NULL; - } - - if (emu->em_monitor_page) - free(emu->em_monitor_page); - if (emu->em_monitor_spare) - free(emu->em_monitor_spare); - if (emu->em_monitor_block) - free(emu->em_monitor_block); - emu->em_monitor_page = NULL; - emu->em_monitor_spare = NULL; - emu->em_monitor_block = NULL; - } - - return 0; -} - -int femu_EraseBlock(uffs_Device *dev, u32 blockNumber) -{ - - int i; - u8 * pg = g_page_buf; - int pg_size, pgd_size, sp_size, blks, blk_pgs, blk_size; - uffs_FileEmu *emu; - emu = (uffs_FileEmu *)(dev->attr->_private); - if (!emu || !(emu->fp)) - goto err; - - pg_size = dev->attr->page_data_size + dev->attr->spare_size; - pgd_size = dev->attr->page_data_size; - sp_size = dev->attr->spare_size; - blk_pgs = dev->attr->pages_per_block; - blks = dev->attr->total_blocks; - blk_size = dev->attr->page_data_size * dev->attr->pages_per_block; - - printf("femu: erase block %d\n", blockNumber); - - if ((int)blockNumber >= blks) { - printf("Attempt to erase non-existant block %d\n",blockNumber); - goto err; - } - else { - - //clear this block monitors - memset(emu->em_monitor_page + (blockNumber * blk_pgs), - 0, - blk_pgs * sizeof(u8)); - memset(emu->em_monitor_spare + (blockNumber * blk_pgs), - 0, - blk_pgs * sizeof(u8)); - - emu->em_monitor_block[blockNumber]++; - - memset(pg, 0xff, (pgd_size + sp_size)); - - fseek(emu->fp, blockNumber * blk_pgs * (pgd_size + sp_size), SEEK_SET); - - for (i = 0; i < blk_pgs; i++) { - fwrite(pg, 1, (pgd_size + sp_size), emu->fp); - } - - fflush(emu->fp); - dev->st.block_erase_count++; - } - - return UFFS_FLASH_NO_ERR; -err: - return UFFS_FLASH_IO_ERR; - -} - diff --git a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_wrap.c b/components/dfs/filesystems/uffs/src/emu/uffs_fileem_wrap.c deleted file mode 100644 index 9893aa2eda..0000000000 --- a/components/dfs/filesystems/uffs/src/emu/uffs_fileem_wrap.c +++ /dev/null @@ -1,311 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fileem_wrap.c - * - * \brief file emulator wrapper functions for injecting bad blocks or ECC errors. - * - * \author Ricky Zheng, created Nov, 2010 - */ - -#include <sys/types.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_device.h" -#include "uffs_fileem.h" - -#define PFX "femu: " -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - -// #define UFFS_FEMU_SHOW_FLASH_IO - -#ifdef UFFS_FEMU_ENABLE_INJECTION - -struct uffs_FileEmuBitFlip { - int block; - int page; - int offset; - u8 mask; -}; - -/* simulate bad blocks */ -#define FILEEMU_STOCK_BAD_BLOCKS {5, 180} // bad block come from manufacture -#define FILEEMU_ERASE_BAD_BLOCKS {100, 150} // new bad block discovered when erasing - -/* simulating bit flip */ -#define FILEEMU_WRITE_BIT_FLIP \ - { \ - {20, 2, 10, 1 << 4}, /* block 20, page 2, offset 10, bit 4 */ \ - {24, 4, -3, 1 << 2}, /* block 24, page 4, spare offset 3, bit 2*/ \ - {60, 1, 5, 1 << 3}, /* block 60, page 1, offset 5, bit 3 */ \ - {66, 1, 15, 1 << 7}, /* block 66, page 1, offset 300, bit 7 */ \ - {80, 2, 2, 1 << 1}, /* block 80, page 2, offset 2, bit 1 */ \ - {88, 2, 100, 1 << 5}, /* block 88, page 2, offset 100, bit 5 */ \ - } - - -static int femu_InitFlash_wrap(uffs_Device *dev); - -static int femu_ReadPage_wrap(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc, - u8 *spare, int spare_len); -static int femu_ReadPageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc, - uffs_TagStore *ts, u8 *ecc_store); -static int femu_WritePage_wrap(uffs_Device *dev, u32 block, u32 page, - const u8 *data, int data_len, const u8 *spare, int spare_len); -static int femu_WritePageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, const u8* data, int data_len, const u8 *ecc, - const uffs_TagStore *ts); -static int femu_EraseBlock_wrap(uffs_Device *dev, u32 blockNumber); - - -///////////////////////////////////////////////////////////////////////////////// - -void femu_setup_wrapper_functions(uffs_Device *dev) -{ - uffs_FileEmu *emu; - emu = (uffs_FileEmu *)(dev->attr->_private); - - // setup wrap functions, for inject ECC errors, etc. - - memcpy(&emu->ops_orig, dev->ops, sizeof(struct uffs_FlashOpsSt)); - - if (dev->ops->InitFlash) - dev->ops->InitFlash = femu_InitFlash_wrap; - if (dev->ops->EraseBlock) - dev->ops->EraseBlock = femu_EraseBlock_wrap; - if (dev->ops->ReadPage) - dev->ops->ReadPage = femu_ReadPage_wrap; - if (dev->ops->ReadPageWithLayout) - dev->ops->ReadPageWithLayout = femu_ReadPageWithLayout_wrap; - if (dev->ops->WritePage) - dev->ops->WritePage = femu_WritePage_wrap; - if (dev->ops->WritePageWithLayout) - dev->ops->WritePageWithLayout = femu_WritePageWithLayout_wrap; -} - -static int femu_InitFlash_wrap(uffs_Device *dev) -{ - int ret; - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - -#ifdef FILEEMU_STOCK_BAD_BLOCKS - u32 bad_blocks[] = FILEEMU_STOCK_BAD_BLOCKS; - int j; - u8 x = 0; - struct uffs_StorageAttrSt *attr = dev->attr; - int full_page_size = attr->page_data_size + attr->spare_size; - int blk_size = full_page_size * attr->pages_per_block; -#endif - - if (emu->initCount == 0) { - ret = emu->ops_orig.InitFlash(dev); -#ifdef FILEEMU_STOCK_BAD_BLOCKS - if (ret >= 0) { - for (j = 0; j < ARRAY_SIZE(bad_blocks); j++) { - if (bad_blocks[j] < dev->attr->total_blocks) { - printf(" --- manufacture bad block %d ---\n", bad_blocks[j]); - fseek(emu->fp, bad_blocks[j] * blk_size + attr->page_data_size + dev->attr->block_status_offs, SEEK_SET); - fwrite(&x, 1, 1, emu->fp); - } - } - } -#endif - } - else { - ret = emu->ops_orig.InitFlash(dev); - } - - return ret; -} - -static int femu_ReadPage_wrap(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc, - u8 *spare, int spare_len) -{ - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - -#ifdef UFFS_FEMU_SHOW_FLASH_IO - if (data || spare) { - MSG(PFX " Read block %d page %d", block, page); - if (data) - MSG(" DATA[%d]", data_len); - if (spare) - MSG(" SPARE[%d]", spare_len); - MSG(TENDSTR); - } -#endif - return emu->ops_orig.ReadPage(dev, block, page, data, data_len, ecc, spare, spare_len); -} - -static int femu_ReadPageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc, - uffs_TagStore *ts, u8 *ecc_store) -{ - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - -#ifdef UFFS_FEMU_SHOW_FLASH_IO - if (data || ts) { - MSG(PFX " Read block %d page %d", block, page); - if (data) - MSG(" DATA[%d]", data_len); - if (ts) - MSG(" TS"); - MSG(TENDSTR); - } -#endif - return emu->ops_orig.ReadPageWithLayout(dev, block, page, data, data_len, ecc, ts, ecc_store); -} - - -////////////////////// wraper functions /////////////////////////// - -static void InjectBitFlip(uffs_Device *dev, u32 block, u32 page) -{ -#ifdef FILEEMU_WRITE_BIT_FLIP - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - struct uffs_FileEmuBitFlip flips[] = FILEEMU_WRITE_BIT_FLIP; - struct uffs_FileEmuBitFlip *x; - u8 buf[UFFS_MAX_PAGE_SIZE + UFFS_MAX_SPARE_SIZE]; - u8 *data = buf; - u8 *spare = buf + dev->attr->page_data_size; - int full_page_size = dev->attr->page_data_size + dev->attr->spare_size; - int blk_size = full_page_size * dev->attr->pages_per_block; - int page_offset = block * blk_size + full_page_size * page; - - int i; - u8 *p; - - fseek(emu->fp, page_offset, SEEK_SET); - fread(buf, 1, full_page_size, emu->fp); - - p = NULL; - for (i = 0; i < ARRAY_SIZE(flips); i++) { - x = &flips[i]; - if (x->block == block && x->page == page) { - if (x->offset >= 0) { - printf(" --- Inject data bit flip at block%d, page%d, offset%d, mask%d --- \n", block, page, x->offset, x->mask); - p = (u8 *)(data + x->offset); - } - else { - printf(" --- Inject spare bit flip at block%d, page%d, offset%d, mask%d --- \n", block, page, -x->offset, x->mask); - p = (u8 *)(spare - x->offset); - } - *p = (*p & ~x->mask) | (~(*p & x->mask) & x->mask); - } - } - - if (p) { - fseek(emu->fp, page_offset, SEEK_SET); - fwrite(buf, 1, full_page_size, emu->fp); - } -#endif -} - -static int femu_WritePage_wrap(uffs_Device *dev, u32 block, u32 page, - const u8 *data, int data_len, const u8 *spare, int spare_len) -{ - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - int ret; - -#ifdef UFFS_FEMU_SHOW_FLASH_IO - if (data || spare) { - MSG(PFX " Write block %d page %d", block, page); - if (data) - MSG(" DATA[%d]", data_len); - if (spare) - MSG(" SPARE[%d]", spare_len); - MSG(TENDSTR); - } -#endif - - ret = emu->ops_orig.WritePage(dev, block, page, data, data_len, spare, spare_len); - - InjectBitFlip(dev, block, page); - - return ret; -} - -static int femu_WritePageWithLayout_wrap(uffs_Device *dev, u32 block, u32 page, const u8* data, int data_len, const u8 *ecc, - const uffs_TagStore *ts) -{ - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - int ret; - -#ifdef UFFS_FEMU_SHOW_FLASH_IO - if (data || ts) { - MSG(PFX " Write block %d page %d", block, page); - if (data) - MSG(" DATA[%d]", data_len); - if (ts) - MSG(" TS"); - MSG(TENDSTR); - } -#endif - - ret = emu->ops_orig.WritePageWithLayout(dev, block, page, data, data_len, ecc, ts); - - InjectBitFlip(dev, block, page); - - return ret; -} - - -static int femu_EraseBlock_wrap(uffs_Device *dev, u32 blockNumber) -{ - uffs_FileEmu *emu = (uffs_FileEmu *)(dev->attr->_private); - -#ifdef FILEEMU_ERASE_BAD_BLOCKS - int blocks[] = FILEEMU_ERASE_BAD_BLOCKS; - int i; - URET ret; - ret = emu->ops_orig.EraseBlock(dev, blockNumber); - - for (i = 0; i < ARRAY_SIZE(blocks); i++) { - if (blockNumber == blocks[i]) { - printf(" --- Inject bad block%d when erasing --- \n", blockNumber); - ret = UFFS_FLASH_BAD_BLK; - } - } - - return ret; - -#else - - return emu->ops_orig.EraseBlock(dev, blockNumber); - -#endif -} - -#endif // UFFS_FEMU_ENABLE_INJECTION - -///////////////////////////////////////////////////////////////////////////////// diff --git a/components/dfs/filesystems/uffs/src/example/CMakeLists.txt b/components/dfs/filesystems/uffs/src/example/CMakeLists.txt deleted file mode 100644 index 18cb307157..0000000000 --- a/components/dfs/filesystems/uffs/src/example/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -IF (UNIX) - INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/posix) -ENDIF() -IF (WIN32) - INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/win32) -ENDIF() -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc) -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/emu) - -LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/emu) -LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/uffs) - -SET(static_mem_SRCS static-mem-allocate.c) -SET(flash_if_SRCS flash-interface-example.c) -ADD_EXECUTABLE(static-mem-example ${static_mem_SRCS}) -ADD_EXECUTABLE(flash-if-example ${flash_if_SRCS}) -TARGET_LINK_LIBRARIES(static-mem-example emu uffs emu platform apitest_server) -TARGET_LINK_LIBRARIES(flash-if-example emu uffs emu platform) -IF (UNIX) - TARGET_LINK_LIBRARIES(static-mem-example pthread) -ENDIF () - diff --git a/components/dfs/filesystems/uffs/src/example/flash-interface-example.c b/components/dfs/filesystems/uffs/src/example/flash-interface-example.c deleted file mode 100644 index ff26beb281..0000000000 --- a/components/dfs/filesystems/uffs/src/example/flash-interface-example.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ -/** - * \file flash-interface-example.c - * \brief example for using flash driver and multiple partitions, with static memory allocator. - * \author Ricky Zheng, created at 27 Nov, 2007 - */ - -#include <string.h> -#include "uffs_config.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_flash.h" -#include "uffs/uffs_mtb.h" -#include "uffs/uffs_fs.h" - -#define PFX "ndrv: " - -struct my_nand_chip { - void *IOR_ADDR; - void *IOW_ADDR; - UBOOL inited; - // ... -}; - -/* - * Standard NAND flash commands - */ -#define NAND_CMD_READ0 0 -#define NAND_CMD_READ1 1 -#define NAND_CMD_RNDOUT 5 -#define NAND_CMD_PAGEPROG 0x10 -#define NAND_CMD_READOOB 0x50 -#define NAND_CMD_ERASE1 0x60 -#define NAND_CMD_STATUS 0x70 -#define NAND_CMD_STATUS_MULTI 0x71 -#define NAND_CMD_SEQIN 0x80 -#define NAND_CMD_RNDIN 0x85 -#define NAND_CMD_READID 0x90 -#define NAND_CMD_ERASE2 0xd0 -#define NAND_CMD_RESET 0xff - - -/* impelent the following functions for your NAND flash */ -#define CHIP_SET_CLE(chip) { chip = chip; } -#define CHIP_CLR_CLE(chip) {} -#define CHIP_SET_ALE(chip) {} -#define CHIP_CLR_ALE(chip) {} -#define CHIP_SET_NCS(chip) {} -#define CHIP_CLR_NCS(chip) {} -#define CHIP_BUSY(chip) {} -#define CHIP_READY(chip) {} -#define WRITE_COMMAND(chip, cmd) {} -#define WRITE_DATA_ADDR(chip, block, page, offset) {} -#define WRITE_ERASE_ADDR(chip, block) {} -#define WRITE_DATA(chip, data, len) {} -#define READ_DATA(chip, data, len) {} - -#define PARSE_STATUS(v) (UFFS_FLASH_NO_ERR) // parse status to UFFS_FLASH_NO_ERR or UFFS_FLASH_BAD_BLK - - - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0 -int main() -{ - uffs_Perror(UFFS_MSG_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1"); - return 0; -} -#else - - -static int nand_read_page(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc, - u8 *spare, int spare_len) -{ - u8 val = 0; - int ret = UFFS_FLASH_NO_ERR; - struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private; - - CHIP_CLR_NCS(chip); - if (data && data_len > 0) { - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_READ0); - CHIP_CLR_CLE(chip); - CHIP_SET_ALE(chip); - WRITE_DATA_ADDR(chip, block, page, 0); - CHIP_CLR_ALE(chip); - READ_DATA(chip, data, data_len); - - // for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver - memset(data, 0xFF, data_len); - } - - if (spare && spare_len > 0) { - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_READOOB); - CHIP_CLR_CLE(chip); - CHIP_SET_ALE(chip); - WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size); - CHIP_CLR_ALE(chip); - READ_DATA(chip, spare, spare_len); - - // for now, we return all 0xFF to pass UFFS mount, you should remove this at your driver - memset(spare, 0xFF, spare_len); - } - - if (data == NULL && spare == NULL) { - // read bad block mark - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_READOOB); - CHIP_CLR_CLE(chip); - CHIP_SET_ALE(chip); - WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs); - CHIP_CLR_ALE(chip); - READ_DATA(chip, &val, 1); - ret = (val == 0xFF ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK); - - // for now, we return UFFS_FLASH_NO_ERR to pass UFFS mount, you should remove this at your driver - ret = UFFS_FLASH_NO_ERR; - } - - CHIP_SET_NCS(chip); - - return ret; -} - -static int nand_write_page(uffs_Device *dev, u32 block, u32 page, - const u8 *data, int data_len, const u8 *spare, int spare_len) -{ - u8 val = 0; - int ret = UFFS_FLASH_NO_ERR; - UBOOL fall_through = FALSE; - struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private; - - CHIP_CLR_NCS(chip); - - if (data && data_len > 0) { - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_READ0); - WRITE_COMMAND(chip, NAND_CMD_SEQIN); - CHIP_CLR_CLE(chip); - CHIP_SET_ALE(chip); - WRITE_DATA_ADDR(chip, block, page, 0); - CHIP_CLR_ALE(chip); - CHIP_BUSY(chip); - WRITE_DATA(chip, data, data_len); - if (data_len == dev->attr->page_data_size) - fall_through = U_TRUE; - else { - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_PAGEPROG); - WRITE_COMMAND(chip, NAND_CMD_STATUS); - CHIP_CLR_CLE(chip); - CHIP_READY(chip); - READ_DATA(chip, &val, 1); - ret = PARSE_STATUS(val); - } - } - - if (ret != UFFS_FLASH_NO_ERR) - goto ext; - - if (spare && spare_len > 0) { - if (!fall_through) { - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_READOOB); - WRITE_COMMAND(chip, NAND_CMD_SEQIN); - CHIP_CLR_CLE(chip); - CHIP_SET_ALE(chip); - WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size); - CHIP_CLR_ALE(chip); - CHIP_BUSY(chip); - } - WRITE_DATA(chip, spare, spare_len); - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_PAGEPROG); - WRITE_COMMAND(chip, NAND_CMD_STATUS); - CHIP_CLR_CLE(chip); - CHIP_READY(chip); - READ_DATA(chip, &val, 1); - ret = PARSE_STATUS(val); - } - - if (data == NULL && spare == NULL) { - // mark bad block - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_READOOB); - WRITE_COMMAND(chip, NAND_CMD_SEQIN); - CHIP_CLR_CLE(chip); - CHIP_SET_ALE(chip); - WRITE_DATA_ADDR(chip, block, page, dev->attr->page_data_size + attr->block_status_offs); - CHIP_CLR_ALE(chip); - CHIP_BUSY(chip); - val = 0; - WRITE_DATA(chip, &val, 1); - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_PAGEPROG); - WRITE_COMMAND(chip, NAND_CMD_STATUS); - CHIP_CLR_CLE(chip); - CHIP_READY(chip); - READ_DATA(chip, &val, 1); - ret = PARSE_STATUS(val); - } - -ext: - CHIP_SET_NCS(chip); - - return ret; -} - -static int nand_erase_block(uffs_Device *dev, u32 block) -{ - u8 val = 0; - struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private; - - CHIP_CLR_NCS(chip); - - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_ERASE1); - CHIP_CLR_CLE(chip); - CHIP_SET_ALE(chip); - WRITE_ERASE_ADDR(chip, blcok); - CHIP_CLR_ALE(chip); - CHIP_SET_CLE(chip); - WRITE_COMMAND(chip, NAND_CMD_ERASE2); - WRITE_COMMAND(chip, NAND_CMD_STATUS); - CHIP_CLR_CLE(chip); - CHIP_READY(chip); - READ_DATA(chip, &val, 1); - - CHIP_SET_NCS(chip); - - val = val; // just for eliminating warning - - return PARSE_STATUS(val); -} - - -static int nand_init_flash(uffs_Device *dev) -{ - // initialize your hardware here ... - struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private; - - if (!chip->inited) { - // setup chip I/O address, setup NAND flash controller ... etc. - // chip->IOR_ADDR = 0xF0000000 - // chip->IOW_ADDR = 0xF0000000 - chip->inited = U_TRUE; - } - return 0; -} - -static int nand_release_flash(uffs_Device *dev) -{ - // release your hardware here - struct my_nand_chip *chip = (struct my_nand_chip *) dev->attr->_private; - - chip = chip; - - return 0; -} - -static uffs_FlashOps g_my_nand_ops = { - nand_init_flash, // InitFlash() - nand_release_flash, // ReleaseFlash() - nand_read_page, // ReadPage() - NULL, // ReadPageWithLayout - nand_write_page, // WritePage() - NULL, // WritePageWithLayout - NULL, // IsBadBlock(), let UFFS take care of it. - NULL, // MarkBadBlock(), let UFFS take care of it. - nand_erase_block, // EraseBlock() -}; - -///////////////////////////////////////////////////////////////////////////////// - -// change these parameters to fit your nand flash specification - -#define TOTAL_BLOCKS 1024 -#define PAGE_DATA_SIZE 512 -#define PAGE_SPARE_SIZE 16 -#define PAGES_PER_BLOCK 32 -#define PAGE_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE) -#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE * PAGES_PER_BLOCK) - -#define NR_PARTITION 2 /* total partitions */ -#define PAR_1_BLOCKS 100 /* partition 1 */ -#define PAR_2_BLOCKS (TOTAL_BLOCKS - PAR_1_BLOCKS) /* partition 2 */ - -struct my_nand_chip g_nand_chip = {0}; -static struct uffs_StorageAttrSt g_my_flash_storage = {0}; - -/* define mount table */ -static uffs_Device demo_device_1 = {0}; -static uffs_Device demo_device_2 = {0}; - -static uffs_MountTable demo_mount_table[] = { - { &demo_device_1, 0, PAR_1_BLOCKS - 1, "/data/" }, - { &demo_device_2, PAR_1_BLOCKS, PAR_1_BLOCKS + PAR_2_BLOCKS - 1, "/" }, - { NULL, 0, 0, NULL } -}; - -/* static alloc the memory for each partition */ -static int static_buffer_par1[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_1_BLOCKS) / sizeof(int)]; -static int static_buffer_par2[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, PAR_2_BLOCKS) / sizeof(int)];; - -static void init_nand_chip(struct my_nand_chip *chip) -{ - // init chip IO address, etc. -} - -static void setup_flash_storage(struct uffs_StorageAttrSt *attr) -{ - memset(attr, 0, sizeof(struct uffs_StorageAttrSt)); - - // setup NAND flash attributes. - attr->total_blocks = TOTAL_BLOCKS; /* total blocks */ - attr->page_data_size = PAGE_DATA_SIZE; /* page data size */ - attr->pages_per_block = PAGES_PER_BLOCK; /* pages per block */ - attr->spare_size = PAGE_SPARE_SIZE; /* page spare size */ - attr->block_status_offs = 4; /* block status offset is 5th byte in spare */ - attr->ecc_opt = UFFS_ECC_SOFT; /* ecc option */ - attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */ -} - -static URET my_InitDevice(uffs_Device *dev) -{ - dev->attr = &g_my_flash_storage; // NAND flash attributes - dev->attr->_private = (void *) &g_nand_chip;// hook nand_chip data structure to attr->_private - dev->ops = &g_my_nand_ops; // NAND driver - - init_nand_chip(&g_nand_chip); - - return U_SUCC; -} - -static URET my_ReleaseDevice(uffs_Device *dev) -{ - return U_SUCC; -} - - -static int my_init_filesystem(void) -{ - uffs_MountTable *mtbl = &(demo_mount_table[0]); - - /* setup nand storage attributes */ - setup_flash_storage(&g_my_flash_storage); - - /* setup memory allocator */ - uffs_MemSetupStaticAllocator(&demo_device_1.mem, static_buffer_par1, sizeof(static_buffer_par1)); - uffs_MemSetupStaticAllocator(&demo_device_2.mem, static_buffer_par2, sizeof(static_buffer_par2)); - - /* register mount table */ - while(mtbl->dev) { - // setup device init/release entry - mtbl->dev->Init = my_InitDevice; - mtbl->dev->Release = my_ReleaseDevice; - uffs_RegisterMountTable(mtbl); - mtbl++; - } - - // mount partitions - for (mtbl = &(demo_mount_table[0]); mtbl->mount != NULL; mtbl++) { - uffs_Mount(mtbl->mount); - } - - return uffs_InitFileSystemObjects() == U_SUCC ? 0 : -1; -} - -static int my_release_filesystem(void) -{ - uffs_MountTable *mtb; - int ret = 0; - - // unmount parttions - for (mtb = &(demo_mount_table[0]); ret == 0 && mtb->mount != NULL; mtb++) { - ret = uffs_UnMount(mtb->mount); - } - - // release objects - if (ret == 0) - ret = (uffs_ReleaseFileSystemObjects() == U_SUCC ? 0 : -1); - - return ret; -} - -/* application entry */ -int main() -{ - uffs_SetupDebugOutput(); // setup debug output as early as possible - - my_init_filesystem(); - - // ... my application codes .... - // read/write/create/delete files ... - - my_release_filesystem(); - - return 0; -} - -#endif - - -///////////////////////////////////////////////////////////////////////////////// diff --git a/components/dfs/filesystems/uffs/src/example/static-mem-allocate.c b/components/dfs/filesystems/uffs/src/example/static-mem-allocate.c deleted file mode 100644 index 59aff8e63d..0000000000 --- a/components/dfs/filesystems/uffs/src/example/static-mem-allocate.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file static-mem-allocate.c - * \brief demostrate how to use static memory allocation. This example use - * file emulated NAND flash, one partition only. - * \author Ricky Zheng - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_fs.h" -#include "uffs/uffs_utils.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs_mtb.h" -#include "cmdline.h" -#include "uffs_fileem.h" - -#define PFX "sexp: " - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR == 0 -int main() -{ - uffs_Perror(UFFS_MSG_NORMAL, "This example need CONFIG_USE_STATIC_MEMORY_ALLOCATOR = 1"); - return 0; -} -#else - -extern struct cli_commandset * get_helper_cmds(void); -extern struct cli_commandset * get_test_cmds(void); - -#define PAGE_DATA_SIZE 512 -#define PAGE_SPARE_SIZE 16 -#define PAGES_PER_BLOCK 32 -#define TOTAL_BLOCKS 128 - -#define PAGE_SIZE (PAGE_DATA_SIZE + PAGE_SPARE_SIZE) -#define BLOCK_DATA_SIZE (PAGES_PER_BLOCK * PAGE_DATA_SIZE) -#define TOTAL_DATA_SIZE (TOTAL_BLOCKS * BLOCK_DATA_SIZE) -#define BLOCK_SIZE (PAGES_PER_BLOCK * PAGE_SIZE) -#define TOTAL_SIZE (BLOCK_SIZE * TOTAL_BLOCKS) - -#define MAX_MOUNT_TABLES 10 -#define MAX_MOUNT_POINT_NAME 32 - -static uffs_Device demo_device = {0}; -static struct uffs_MountTableEntrySt demo_mount = { - &demo_device, - 0, /* start from block 0 */ - -1, /* use whole chip */ - "/", /* mount point */ - NULL -}; - -/* static alloc the memory */ -static int static_buffer_pool[UFFS_STATIC_BUFF_SIZE(PAGES_PER_BLOCK, PAGE_SIZE, TOTAL_BLOCKS) / sizeof(int)]; - - -static void setup_storage(struct uffs_StorageAttrSt *attr) -{ - attr->total_blocks = TOTAL_BLOCKS; /* total blocks */ - attr->page_data_size = PAGE_DATA_SIZE; /* page data size */ - attr->spare_size = PAGE_SPARE_SIZE; /* page spare size */ - attr->pages_per_block = PAGES_PER_BLOCK; /* pages per block */ - attr->block_status_offs = 4; /* block status offset is 5th byte in spare */ - attr->ecc_opt = UFFS_ECC_SOFT; /* use UFFS software ecc */ - attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS do the spare layout */ -} - -static void setup_device(uffs_Device *dev) -{ - // using file emulator device - dev->Init = femu_InitDevice; - dev->Release = femu_ReleaseDevice; - dev->attr = femu_GetStorage(); -} - -static int init_uffs_fs(void) -{ - struct uffs_MountTableEntrySt *mtbl = &demo_mount; - - /* setup flash storage attributes */ - setup_storage(femu_GetStorage()); - - /* setup memory allocator */ - uffs_MemSetupStaticAllocator(&mtbl->dev->mem, static_buffer_pool, sizeof(static_buffer_pool)); - - /* setup device: init, release, attr */ - setup_device(mtbl->dev); - - /* register mount table */ - uffs_RegisterMountTable(mtbl); - - /* mount it */ - uffs_Mount("/"); - - return uffs_InitFileSystemObjects() == U_SUCC ? 0 : -1; -} - -static int release_uffs_fs(void) -{ - uffs_UnMount("/"); - - return uffs_ReleaseFileSystemObjects(); -} - -int main(int argc, char *argv[]) -{ - int ret; - - uffs_SetupDebugOutput(); // setup debug output as early as possible - - ret = init_uffs_fs(); - - if (ret != 0) { - printf ("Init file system fail: %d\n", ret); - return -1; - } - - cli_add_commandset(get_helper_cmds()); - cli_add_commandset(get_test_cmds()); - cli_main_entry(); - - release_uffs_fs(); - - return 0; -} - -#endif - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs.h deleted file mode 100644 index 12121cd1ab..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ -/** - * \file uffs.h - * \brief uffs basic defines - * \author Ricky Zheng - */ - -#ifndef _UFFS_H_ -#define _UFFS_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#define UO_RDONLY 0x0000 /** read only */ -#define UO_WRONLY 0x0001 /** write only */ -#define UO_RDWR 0x0002 /** read and write */ -#define UO_APPEND 0x0008 /** append */ - -#define UO_BINARY 0x0000 /** no used in uffs */ - -#define UO_CREATE 0x0100 -#define UO_TRUNC 0x0200 -#define UO_EXCL 0x0400 - -#define UO_NOECC 0x0800 /** skip ECC when reading file data from media */ - - -#define UO_DIR 0x1000 /** open a directory */ - - - -#define UENOERR 0 /** no error */ -#define UEACCES 1 /** Tried to open read-only file - for writing, or files sharing mode - does not allow specified operations, - or given path is directory */ - -#define UEEXIST 2 /** _O_CREAT and _O_EXCL flags specified, - but filename already exists */ -#define UEINVAL 3 /** Invalid oflag or pmode argument */ -#define UEMFILE 4 /** No more file handles available - (too many open files) */ -#define UENOENT 5 /** file or path not found */ -#define UETIME 6 /** can't set file time */ -#define UEBADF 9 /** invalid file handle */ -#define UENOMEM 10 /** no enough memory */ -#define UEIOERR 11 /** I/O error from lower level flash operation */ -#define UENOTDIR 12 /** Not a directory */ -#define UEISDIR 13 /** Is a directory */ - -#define UEUNKNOWN_ERR 100 /** unknown error */ - - - -#define _SEEK_CUR 0 /** seek from current position */ -#define _SEEK_SET 1 /** seek from beginning of file */ -#define _SEEK_END 2 /** seek from end of file */ - -#define USEEK_CUR _SEEK_CUR -#define USEEK_SET _SEEK_SET -#define USEEK_END _SEEK_END - - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_badblock.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_badblock.h deleted file mode 100644 index b44bbb8170..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_badblock.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ -/** - * \file uffs_badblock.h - * \brief bad block management - * \author Ricky Zheng - */ - -#ifndef _UFFS_BADBLOCK_H_ -#define _UFFS_BADBLOCK_H_ - -#include "uffs/uffs_public.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_core.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - -#define HAVE_BADBLOCK(dev) (dev->bad.block != UFFS_INVALID_BLOCK) - -/** initialize bad block management data structures for uffs device */ -void uffs_BadBlockInit(uffs_Device *dev); - -/** processing bad block: erase bad block, - mark it as 'bad' and put it to bad block list */ -void uffs_BadBlockProcess(uffs_Device *dev, TreeNode *node); - -/** processing bad block: erase bad block, - mark it as 'bad' and put it to suspend block list */ -void uffs_BadBlockProcessSuspend(uffs_Device *dev, TreeNode *node); - -/** try to recover data from a new discovered bad block */ -void uffs_BadBlockRecover(uffs_Device *dev); - -/** put a new block to the bad block waiting list */ -void uffs_BadBlockAdd(uffs_Device *dev, int block); - - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_blockinfo.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_blockinfo.h deleted file mode 100644 index dfd3a9be7c..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_blockinfo.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ -/** - * \file uffs_blockinfo.h - * \brief data structure for operating block information - * \author Ricky Zheng - */ - -#ifndef _UFFS_BLOCKINFO_H_ -#define _UFFS_BLOCKINFO_H_ - -#include "uffs/uffs_types.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_core.h" - -#ifdef __cplusplus -extern "C"{ -#endif -/** - * \struct uffs_PageSpareSt - * \brief this structure is for storing uffs tag and more. - */ -struct uffs_PageSpareSt { - uffs_Tags tag; //!< page tag - int expired:1; -}; - -/** - * \struct uffs_BlockInfoSt - * \brief block information data. Block info is frequently accessed, - UFFS use a cache system to speed up block info access. - */ -struct uffs_BlockInfoSt { - struct uffs_BlockInfoSt *next; - struct uffs_BlockInfoSt *prev; - u16 block; //!< block number - struct uffs_PageSpareSt *spares; //!< page spare info array - int expired_count; //!< how many pages expired in this block ? - int ref_count; //!< reference counter, it's safe to reuse this block memory when the counter is 0. -}; - -/** get tag from block info */ -#define GET_TAG(bc, page) (&(bc)->spares[page].tag) - - -/** initialize block info caches */ -URET uffs_BlockInfoInitCache(uffs_Device *dev, int maxCachedBlocks); - -/** release block info caches */ -URET uffs_BlockInfoReleaseCache(uffs_Device *dev); - -/** load page spare to block info cache */ -URET uffs_BlockInfoLoad(uffs_Device *dev, uffs_BlockInfo *work, int page); - -/** find block info cache */ -uffs_BlockInfo * uffs_BlockInfoFindInCache(uffs_Device *dev, int block); - -/** get block info cache, load it on demand */ -uffs_BlockInfo * uffs_BlockInfoGet(uffs_Device *dev, int block); - -/** put info cache back to pool, should be called with #uffs_BlockInfoGet in pairs. */ -void uffs_BlockInfoPut(uffs_Device *dev, uffs_BlockInfo *p); - -/** explicitly expire a block info cache */ -void uffs_BlockInfoExpire(uffs_Device *dev, uffs_BlockInfo *p, int page); - -/** no one hold any block info cache ? safe to release block info caches */ -UBOOL uffs_BlockInfoIsAllFree(uffs_Device *dev); - -/** explicitly expire all block info caches */ -void uffs_BlockInfoExpireAll(uffs_Device *dev); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_buf.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_buf.h deleted file mode 100644 index b5c99f6d5e..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_buf.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_buf.h - * \brief page buffers - * \author Ricky Zheng - */ - -#ifndef UFFS_BUF_H -#define UFFS_BUF_H - -#include "uffs/uffs_types.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_tree.h" -#include "uffs/uffs_core.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -#define CLONE_BUF_MARK 0xffff //!< set uffs_BufSt::ref_count to this for a 'cloned' buffer - -/** for uffs_BufSt::mark */ -#define UFFS_BUF_EMPTY 0 //!< buffer is empty -#define UFFS_BUF_VALID 1 //!< buffer is holding valid data -#define UFFS_BUF_DIRTY 2 //!< buffer data is modified - -/** for uffs_BufSt::ext_mark */ -#define UFFS_BUF_EXT_MARK_TRUNC_TAIL 1 //!< the last page of file (when truncating a file) - -/** uffs page buffer */ -struct uffs_BufSt{ - struct uffs_BufSt *next; //!< link to next buffer - struct uffs_BufSt *prev; //!< link to previous buffer - struct uffs_BufSt *next_dirty; //!< link to next dirty buffer - struct uffs_BufSt *prev_dirty; //!< link to previous dirty buffer - u8 type; //!< #UFFS_TYPE_DIR or #UFFS_TYPE_FILE or #UFFS_TYPE_DATA - u8 ext_mark; //!< extension mark. - u16 parent; //!< parent serial - u16 serial; //!< serial - u16 page_id; //!< page id - u16 mark; //!< #UFFS_BUF_EMPTY or #UFFS_BUF_VALID, or #UFFS_BUF_DIRTY ? - u16 ref_count; //!< reference counter, or #CLONE_BUF_MARK for a cloned buffer - u16 data_len; //!< length of data - u16 check_sum; //!< checksum field - u8 * data; //!< data buffer - u8 * header; //!< header -}; - -#define uffs_BufIsFree(buf) (buf->ref_count == 0 ? U_TRUE : U_FALSE) - -/** initialize page buffers */ -URET uffs_BufInit(struct uffs_DeviceSt *dev, int buf_max, int dirty_buf_max); - -/** release page buffers */ -URET uffs_BufReleaseAll(struct uffs_DeviceSt *dev); - -/** find the page buffer, move to link list head if found */ -uffs_Buf * uffs_BufGet(struct uffs_DeviceSt *dev, u16 parent, u16 serial, u16 page_id); -uffs_Buf *uffs_BufGetEx(struct uffs_DeviceSt *dev, u8 type, TreeNode *node, u16 page_id, int oflag); - -/** alloc a new page buffer */ -uffs_Buf *uffs_BufNew(struct uffs_DeviceSt *dev, u8 type, u16 parent, u16 serial, u16 page_id); - -/** find the page buffer (not affect the reference counter) */ -uffs_Buf * uffs_BufFind(uffs_Device *dev, u16 parent, u16 serial, u16 page_id); - -/** find the page buffer from #start (not affect the reference counter) */ -uffs_Buf * uffs_BufFindFrom(uffs_Device *dev, uffs_Buf *start, - u16 parent, u16 serial, u16 page_id); - -/** put page buffer back to pool, called in pair with #uffs_Get,#uffs_GetEx or #uffs_BufNew */ -URET uffs_BufPut(uffs_Device *dev, uffs_Buf *buf); - -/** increase buffer references */ -void uffs_BufIncRef(uffs_Buf *buf); - -/** decrease buffer references */ -void uffs_BufDecRef(uffs_Buf *buf); - -/** write data to a page buffer */ -URET uffs_BufWrite(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len); - -/** read data from a page buffer */ -URET uffs_BufRead(struct uffs_DeviceSt *dev, uffs_Buf *buf, void *data, u32 ofs, u32 len); - -/** mark buffer as #UFFS_BUF_EMPTY if ref_count == 0, and discard all data it holds */ -void uffs_BufMarkEmpty(uffs_Device *dev, uffs_Buf *buf); - -/** if there is no free dirty group slot, flush the most dirty group */ -URET uffs_BufFlush(struct uffs_DeviceSt *dev); -URET uffs_BufFlushEx(struct uffs_DeviceSt *dev, UBOOL force_block_recover); - -/** flush dirty group */ -URET uffs_BufFlushGroup(struct uffs_DeviceSt *dev, u16 parent, u16 serial); -URET uffs_BufFlushGroupEx(struct uffs_DeviceSt *dev, u16 parent, u16 serial, UBOOL force_block_recover); - -/** find free dirty group slot */ -int uffs_BufFindFreeGroupSlot(struct uffs_DeviceSt *dev); - -/** find the dirty group slot */ -int uffs_BufFindGroupSlot(struct uffs_DeviceSt *dev, u16 parent, u16 serial); - -/** lock dirty group */ -URET uffs_BufLockGroup(struct uffs_DeviceSt *dev, int slot); - -/** unlock dirty group */ -URET uffs_BufUnLockGroup(struct uffs_DeviceSt *dev, int slot); - -/** flush most dirty group */ -URET uffs_BufFlushMostDirtyGroup(struct uffs_DeviceSt *dev); - -/** flush all groups under the same parent number */ -URET uffs_BufFlushGroupMatchParent(struct uffs_DeviceSt *dev, u16 parent); - -/** flush all page buffers */ -URET uffs_BufFlushAll(struct uffs_DeviceSt *dev); - -/** no one holding any page buffer ? safe to release page buffers */ -UBOOL uffs_BufIsAllFree(struct uffs_DeviceSt *dev); - -/** are all page buffer marked with #UFFS_BUF_EMPTY ? */ -UBOOL uffs_BufIsAllEmpty(struct uffs_DeviceSt *dev); - -/** mark all page buffer as #UFFS_BUF_EMPTY */ -URET uffs_BufSetAllEmpty(struct uffs_DeviceSt *dev); - -/** clone a page buffer */ -uffs_Buf * uffs_BufClone(struct uffs_DeviceSt *dev, uffs_Buf *buf); - -/** release a cloned page buffer, call in pair with #uffs_BufClone */ -URET uffs_BufFreeClone(uffs_Device *dev, uffs_Buf *buf); - -/** load physical storage data to page buffer */ -URET uffs_BufLoadPhyData(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page); - -/** load physical storage data to page buffer withouth checking ECC */ -URET uffs_LoadPhyDataToBufEccUnCare(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page); - -/** showing page buffers info, for debug only */ -void uffs_BufInspect(uffs_Device *dev); - -#ifdef __cplusplus -} -#endif - - -#endif diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_core.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_core.h deleted file mode 100644 index 1f18007f0f..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_core.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -#ifndef _UFFS_CORE_H_ -#define _UFFS_CORE_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -/** \typedef uffs_Device */ -typedef struct uffs_DeviceSt uffs_Device; -/** \typedef uffs_FlashOps */ -typedef struct uffs_FlashOpsSt uffs_FlashOps; - -typedef struct uffs_BlockInfoSt uffs_BlockInfo; -typedef struct uffs_PageSpareSt uffs_PageSpare; -typedef struct uffs_TagsSt uffs_Tags; //!< UFFS page tags -typedef struct uffs_TagStoreSt uffs_TagStore; //!< UFFS page tags physical store structure - -typedef struct uffs_BufSt uffs_Buf; - - -#ifdef __cplusplus -} -#endif - - - -#endif diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_crc.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_crc.h deleted file mode 100644 index a31bb21c91..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_crc.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_crc.h - * \author Ricky Zheng, created 23 Nov, 2011 - */ - -#ifndef _UFFS_CRC_H_ -#define _UFFS_CRC_H_ - -#include "uffs/uffs_types.h" - -u16 uffs_crc16update(const void *data, int length, u16 crc); -u16 uffs_crc16sum(const void *data, int length); - -#endif diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_device.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_device.h deleted file mode 100644 index 22614528a3..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_device.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_device.h - * \brief uffs device structures definition - * \author Ricky Zheng - */ - -#ifndef UFFS_DEVICE_H -#define UFFS_DEVICE_H - -#include "uffs/uffs_types.h" -#include "uffs/uffs_buf.h" -#include "uffs/uffs_blockinfo.h" -#include "uffs/uffs_pool.h" -#include "uffs/uffs_tree.h" -#include "uffs/uffs_mem.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs_flash.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/** - * \def MAX_DIRTY_BUF_GROUPS - */ -#define MAX_DIRTY_BUF_GROUPS 3 - - -/** - * \struct uffs_BlockInfoCacheSt - * \brief block information structure, used to manager block information caches - */ -struct uffs_BlockInfoCacheSt { - uffs_BlockInfo *head; //!< buffer head of block info(spares) - uffs_BlockInfo *tail; //!< buffer tail - void *mem_pool; //!< internal memory pool, used for release whole buffer -}; - -/** - * \struct uffs_PartitionSt - * \brief partition basic information - */ -struct uffs_PartitionSt { - u16 start; //!< start block number of partition - u16 end; //!< end block number of partition -}; - -/** - * \struct uffs_LockSt - * \brief lock stuffs - */ -struct uffs_LockSt { - OSSEM sem; - int task_id; - int counter; -}; - -/** - * \struct uffs_DirtyGroupSt - * \brief manager dirty page buffers - */ -struct uffs_DirtyGroupSt { - int count; //!< dirty buffers count - int lock; //!< dirty group lock (0: unlocked, >0: locked) - uffs_Buf *dirty; //!< dirty buffer list -}; - -/** - * \struct uffs_PageBufDescSt - * \brief uffs page buffers descriptor - */ -struct uffs_PageBufDescSt { - uffs_Buf *head; //!< head of buffers - uffs_Buf *tail; //!< tail of buffers - struct uffs_DirtyGroupSt dirtyGroup[MAX_DIRTY_BUF_GROUPS]; //!< dirty buffer groups - int buf_max; //!< maximum buffers - int dirty_buf_max; //!< maximum dirty buffer allowed - void *pool; //!< memory pool for buffers -}; - - -/** - * \struct uffs_PageCommInfoSt - * \brief common data for device, should be initialised at early - * \note it is possible that pg_size is smaller than physical page size, but normally they are the same. - * \note page data layout: [HEADER] + [DATA] - */ -struct uffs_PageCommInfoSt { - u16 pg_data_size; //!< page data size - u16 header_size; //!< header size - u16 pg_size; //!< page size -}; - -/** - * \struct uffs_NewBadBlockSt - * \brief holding new discovered bad block - */ -struct uffs_NewBadBlockSt { - u16 block; //!< bad block, FIX ME to process more than one bad block -}; - -/** - * \struct uffs_FlashStatSt - * \typedef uffs_FlashStat - * \brief statistic data of flash read/write/erase activities - */ -typedef struct uffs_FlashStatSt { - int block_erase_count; - int page_write_count; - int page_read_count; - int page_header_read_count; - int spare_write_count; - int spare_read_count; - unsigned long io_read; - unsigned long io_write; -} uffs_FlashStat; - - -/** - * \struct uffs_ConfigSt - * \typedef uffs_Config - * \brief uffs config parameters - */ -typedef struct uffs_ConfigSt { - int bc_caches; - int page_buffers; - int dirty_pages; - int dirty_groups; - int reserved_free_blocks; -} uffs_Config; - - -/** - * \struct uffs_DeviceSt - * \brief The core data structure of UFFS, all information needed by manipulate UFFS object - * \note one partition corresponding one uffs device. - */ -struct uffs_DeviceSt { - URET (*Init)(uffs_Device *dev); //!< low level initialisation - URET (*Release)(uffs_Device *dev); //!< low level release - void *_private; //!< private data for device - - struct uffs_StorageAttrSt *attr; //!< storage attribute - struct uffs_PartitionSt par; //!< partition information - struct uffs_FlashOpsSt *ops; //!< flash operations - struct uffs_BlockInfoCacheSt bc; //!< block info cache - struct uffs_LockSt lock; //!< lock data structure - struct uffs_PageBufDescSt buf; //!< page buffers - struct uffs_PageCommInfoSt com; //!< common information - struct uffs_TreeSt tree; //!< tree list of block - struct uffs_NewBadBlockSt bad; //!< new discovered bad block - struct uffs_FlashStatSt st; //!< statistic (counters) - struct uffs_memAllocatorSt mem; //!< uffs memory allocator - struct uffs_ConfigSt cfg; //!< uffs config - u32 ref_count; //!< device reference count - int dev_num; //!< device number (partition number) -}; - - -/** create the lock for uffs device */ -void uffs_DeviceInitLock(uffs_Device *dev); - -/** delete the lock of uffs device */ -void uffs_DeviceReleaseLock(uffs_Device *dev); - -/** lock uffs device */ -void uffs_DeviceLock(uffs_Device *dev); - -/** unlock uffs device */ -void uffs_DeviceUnLock(uffs_Device *dev); - - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_ecc.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_ecc.h deleted file mode 100644 index 18fbd92a38..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_ecc.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_ecc.h - * \brief file handle operations - * \author Ricky Zheng, created 8th Jun, 2005 - */ - -#ifndef _UFFS_ECC_H_ -#define _UFFS_ECC_H_ - -#include <string.h> - -#include "uffs/uffs_fs.h" -#include "uffs/uffs_core.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - - -#define MAX_ECC_LENGTH 24 //!< 2K page ecc length is 24 bytes. - -/** - * calculate ECC - * \return length of generated ECC. (3 bytes ECC per 256 data) - */ -int uffs_EccMake(const void *data, int data_len, void *ecc); - -/** - * correct data by ECC. - * - * return: 0 -- no error - * -1 -- can not be corrected - * >0 -- how many bits are corrected - */ -int uffs_EccCorrect(void *data, int data_len, void *read_ecc, const void *test_ecc); - - -/** - * generate 12 bit ecc for maximum 8 bytes data - */ -u16 uffs_EccMake8(const void *data, int data_len); - -/** - * correct maximum 8 bytes data from 12 bits ECC - * - * return: 0 -- no error - * -1 -- can not be corrected - * >0 -- how many bits are corrected - */ -int uffs_EccCorrect8(void *data, u16 read_ecc, u16 test_ecc, int errtop); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_fd.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_fd.h deleted file mode 100644 index c5d8159074..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_fd.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fd.h - * \brief PISIX like file operations - * \author Ricky Zheng, created 8th Jun, 2005 - */ - -#ifndef _UFFS_FD_H_ -#define _UFFS_FD_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - -#include "uffs/uffs.h" - -/** - * \brief definitions for uffs_stat::st_mode - */ -#define US_IFMT 0xF000 /* file type make */ -#define US_IFREG 0x8000 /* regular */ -#define US_IFLNK 0xA000 /* symbolic link */ -#define US_IFDIR 0x4000 /* directory */ -#define US_IREAD 0000400 /* read permission */ -#define US_IWRITE 0000200 /* write permission */ - -#define US_IRWXU 00700 /* RWX owner */ -#define US_IRUSR 00400 /* R owner */ -#define US_IWUSR 00200 /* W owner */ -#define US_IXUSR 00100 /* X owner */ -#define US_IRWXG 00070 /* RWX group */ -#define US_IRGRP 00040 /* R group */ -#define US_IWGRP 00020 /* W group */ -#define US_IXGRP 00010 /* X group */ -#define US_IRWXO 00007 /* RWX other */ -#define US_IROTH 00004 /* R other */ -#define US_IWOTH 00002 /* W other */ -#define US_IXOTH 00001 /* X other */ - -/** - * \brief POSIX dirent - */ -struct uffs_dirent { - int d_ino; /* inode number (serial number of this object) */ - int d_off; /* offset to this dirent */ - unsigned short int d_reclen; /* length of this uffs_dirent */ - unsigned short int d_namelen; /* length of this d_name */ - unsigned char d_type; /* type of this record */ - char d_name[256]; /* name of this object */ -}; - -struct uffs_dirSt; -typedef struct uffs_dirSt uffs_DIR; - -/** - * \brief POSIX stat - */ -struct uffs_stat { - int st_dev; /* ID of device containing file */ - int st_ino; /* inode number */ - int st_mode; /* protection */ - int st_nlink; /* number of hard links */ - int st_uid; /* user ID of owner */ - int st_gid; /* group ID of owner */ - int st_rdev; /* device ID (if special file) */ - long st_size; /* total size, in bytes */ - int st_blksize; /* blocksize for filesystem I/O */ - int st_blocks; /* number of blocks allocated */ - unsigned int st_atime; /* time of last access */ - unsigned int st_mtime; /* time of last modification */ - unsigned int st_ctime; /* time of last status change */ -}; - -/* POSIX complaint file system APIs */ - -int uffs_open(const char *name, int oflag, ...); -int uffs_close(int fd); -int uffs_read(int fd, void *data, int len); -int uffs_write(int fd, const void *data, int len); -long uffs_seek(int fd, long offset, int origin); -long uffs_tell(int fd); -int uffs_eof(int fd); -int uffs_flush(int fd); -int uffs_rename(const char *old_name, const char *new_name); -int uffs_remove(const char *name); -int uffs_ftruncate(int fd, long remain); - -int uffs_mkdir(const char *name, ...); -int uffs_rmdir(const char *name); - -int uffs_stat(const char *name, struct uffs_stat *buf); -int uffs_lstat(const char *name, struct uffs_stat *buf); -int uffs_fstat(int fd, struct uffs_stat *buf); - -int uffs_closedir(uffs_DIR *dirp); -uffs_DIR * uffs_opendir(const char *path); -struct uffs_dirent * uffs_readdir(uffs_DIR *dirp); - -void uffs_rewinddir(uffs_DIR *dirp); - - -int uffs_get_error(void); -int uffs_set_error(int err); - -int uffs_version(void); -int uffs_format(const char *mount_point); - -long uffs_space_total(const char *mount_point); -long uffs_space_used(const char *mount_point); -long uffs_space_free(const char *mount_point); - -void uffs_flush_all(const char *mount_point); - -#ifdef __cplusplus -} -#endif -#endif - - - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_find.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_find.h deleted file mode 100644 index 3408cf33c6..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_find.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_find.h - * \brief find objects under dir - * \author Ricky Zheng - */ - -#ifndef _UFFS_FIND_H_ -#define _UFFS_FIND_H_ - -#include "uffs/uffs_fs.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -typedef struct uffs_FindInfoSt { - uffs_Device *dev; //!< the device to be searched - u16 serial; //!< the dir serial number - int step; //!< step: 0 - working on dir entries, - // 1 - working on file entries, - // 2 - stoped. - int hash; //!< hash entry, internal used - TreeNode *work; //!< working node, internal used. - int pos; //!< current position -} uffs_FindInfo; - - -URET uffs_GetObjectInfo(uffs_Object *obj, uffs_ObjectInfo *info, int *err); -URET uffs_FindObjectOpen(uffs_FindInfo *find_handle, uffs_Object *dir); -URET uffs_FindObjectOpenEx(uffs_FindInfo *f, uffs_Device *dev, int dir); -URET uffs_FindObjectFirst(uffs_ObjectInfo *info, uffs_FindInfo *find_handle); -URET uffs_FindObjectNext(uffs_ObjectInfo *info, uffs_FindInfo *find_handle); -URET uffs_FindObjectRewind(uffs_FindInfo *find_handle); -URET uffs_FindObjectClose(uffs_FindInfo * find_handle); - - -#ifdef __cplusplus -} -#endif - - -#endif - - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_flash.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_flash.h deleted file mode 100644 index 844d8ea231..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_flash.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_public.h - * \brief flash interface for UFFS - * \author Ricky Zheng - */ - -#ifndef _UFFS_FLASH_H_ -#define _UFFS_FLASH_H_ - -#include "uffs/uffs_types.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_fs.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - -/** ECC options (uffs_StorageAttrSt.ecc_opt) */ -#define UFFS_ECC_NONE 0 //!< do not use ECC -#define UFFS_ECC_SOFT 1 //!< UFFS calculate the ECC -#define UFFS_ECC_HW 2 //!< Flash driver(or by hardware) calculate the ECC -#define UFFS_ECC_HW_AUTO 3 //!< Hardware calculate the ECC and automatically write to spare. - -#define UFFS_ECC_OPTION_STRING \ - { "none", "soft", "hw", "auto" } // index is the ecc option value. - -/** spare layout options (uffs_StorageAttrSt.layout_opt) */ -#define UFFS_LAYOUT_UFFS 0 //!< do layout by dev->attr information -#define UFFS_LAYOUT_FLASH 1 //!< flash driver do the layout - -#define UFFS_SPARE_LAYOUT_SIZE 16 //!< maximum spare layout array size, 2 segments - -/** flash operation return code */ -#define UFFS_FLASH_NO_ERR 0 //!< no error -#define UFFS_FLASH_ECC_OK 1 //!< bit-flip found, but corrected by ECC -#define UFFS_FLASH_NOT_SEALED 2 //!< page spare area is not sealed properly (only for ReadPageWithLayout()) -#define UFFS_FLASH_IO_ERR -1 //!< I/O error -#define UFFS_FLASH_ECC_FAIL -2 //!< ECC failed -#define UFFS_FLASH_BAD_BLK -3 //!< bad block -#define UFFS_FLASH_CRC_ERR -4 //!< CRC failed -#define UFFS_FLASH_UNKNOWN_ERR -100 //!< unkown error? - -#define UFFS_FLASH_HAVE_ERR(e) ((e) < 0) - -#if defined(CONFIG_BAD_BLOCK_POLICY_STRICT) -# define UFFS_FLASH_IS_BAD_BLOCK(e) \ - ((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_ECC_OK || (e) == UFFS_FLASH_BAD_BLK || (e) == UFFS_FLASH_CRC_ERR) -#else -# define UFFS_FLASH_IS_BAD_BLOCK(e) \ - ((e) == UFFS_FLASH_ECC_FAIL || (e) == UFFS_FLASH_BAD_BLK || (e) == UFFS_FLASH_CRC_ERR) -#endif - - -/** defines for page info (data length and data sum) */ -#define UFFS_PAGE_INFO_CLEAN 0xFFFFFFFF -#define UFFS_PAGE_INFO_IOERR 0xDEADFFFF -#define UFFS_PAGE_GET_LEN(info) (info & 0xFFFF) -#define UFFS_PAGE_GET_DSUM(info) (info >> 16) -#define UFFS_PAGE_MAKE_INFO(d_len, d_sum) ((d_sum << 16) | d_len) - -/** - * \struct uffs_StorageAttrSt - * \brief uffs device storage attribute, provide by nand specific file - */ -struct uffs_StorageAttrSt { - u32 total_blocks; //!< total blocks in this chip - u16 page_data_size; //!< page data size (physical page data size, e.g. 512) - u16 pages_per_block; //!< pages per block - u8 spare_size; //!< page spare size (physical page spare size, e.g. 16) - u8 block_status_offs; //!< block status byte offset in spare - int ecc_opt; //!< ecc option ( #UFFS_ECC_[NONE|SOFT|HW|HW_AUTO] ) - int layout_opt; //!< layout option (#UFFS_LAYOUT_UFFS or #UFFS_LAYOUT_FLASH) - int ecc_size; //!< ecc size in bytes - const u8 *ecc_layout; //!< page data ECC layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0] - const u8 *data_layout; //!< spare data layout: [ofs1, size1, ofs2, size2, ..., 0xFF, 0] - u8 _uffs_ecc_layout[UFFS_SPARE_LAYOUT_SIZE]; //!< uffs spare ecc layout - u8 _uffs_data_layout[UFFS_SPARE_LAYOUT_SIZE]; //!< uffs spare data layout - void *_private; //!< private data for storage attribute -}; - - -/** - * \struct uffs_FlashOpsSt - * \brief low level flash operations, should be implement in flash driver - */ -struct uffs_FlashOpsSt { - /** - * Initilize flash driver, called once when UFFS initilize partition - * - * \return 0 if no error, return -1 when failed. - * - * \note This function is optional. - */ - int (*InitFlash)(uffs_Device *dev); - - /** - * Release flash driver, called once when UFFS unmount partition - * - * \return 0 if no error, return -1 when failed. - * - * \note This function is optional. - */ - int (*ReleaseFlash)(uffs_Device *dev); - - /** - * Read a full nand page, UFFS do the layout. - * - * \param[out] ecc ecc of page data - * if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return ecc of data(if ecc != NULL). - * if ecc_opt is UFFS_ECC_HW_AUTO, flash driver do ecc correction before return data and flash driver do not need to return ecc. - * if ecc_opt is UFFS_ECC_NONE or UFFS_ECC_SOFT, flash driver do not need to calculate data ecc and return ecc. - * - * \return #UFFS_FLASH_NO_ERR: success and/or has no flip bits. - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_ECC_FAIL: page data has flip bits and ecc correct failed (when ecc_opt == UFFS_ECC_HW_AUTO) - * #UFFS_FLASH_ECC_OK: page data has flip bits and corrected by ecc (when ecc_opt == UFFS_ECC_HW_AUTO) - * #UFFS_FLASH_BAD_BLK: if the block is a bad block (e.g., the bad block mark byte is not 0xFF). - * - * \note if data is NULL, do not return data; if spare is NULL, do not return spare; if both data and spare are all NULL, - * then read bad block mark and return UFFS_FLASH_BAD_BLK if bad block mark is not 0xFF. - * - * \note pad 0xFF for calculating ECC if len < page_data_size - */ - int (*ReadPage)(uffs_Device *dev, u32 block, u32 page, u8 *data, int data_len, u8 *ecc, - u8 *spare, int spare_len); - - /** - * Read a full nand page, driver do the layout. - * - * \param[out] ecc ecc of page data - * if ecc_opt is UFFS_ECC_HW, flash driver must calculate and return ecc of data(if ecc != NULL). - * if ecc_opt is UFFS_ECC_HW_AUTO, flash driver do ecc correction before return data and flash driver do not need to return ecc. - * if ecc_opt is UFFS_ECC_NONE or UFFS_ECC_SOFT, flash driver do not need calculate data ecc and return ecc. - * - * \param[out] ecc_store ecc store on spare area - * if ecc_opt is UFFS_ECC_NONE or UFFS_ECC_HW_AUTO, do not need to return ecc_store. - * - * \note flash driver must provide this function if layout_opt is UFFS_LAYOUT_FLASH. - * UFFS will use this function (if exist) prio to 'ReadPageSpare()' - * - * \return #UFFS_FLASH_NO_ERR: success - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_ECC_FAIL: page data has flip bits and ecc correct failed (when ecc_opt == UFFS_ECC_HW_AUTO) - * #UFFS_FLASH_ECC_OK: page data has flip bits and corrected by ecc (when ecc_opt == UFFS_ECC_HW_AUTO) - * #UFFS_FLASH_BAD_BLK: if the block is a bad block (e.g., the bad block mark byte is not 0xFF) - * #UFFS_FLASH_NOT_SEALED: if the page spare is not sealed properly - * - * \note if data is NULL, do not return data; if ts is NULL, do not read tag; if both data and ts are NULL, - * then read bad block mark and return UFFS_FLASH_BAD_BLK if bad block mark is not 0xFF. - * - * \note flash driver DO NOT need to do ecc correction for tag, - * UFFS will take care of tag ecc. - */ - int (*ReadPageWithLayout)(uffs_Device *dev, u32 block, u32 page, u8* data, int data_len, u8 *ecc, - uffs_TagStore *ts, u8 *ecc_store); - - /** - * Write a full page, UFFS do the layout for spare area. - * - * \note If you have ecc_opt UFFS_ECC_HW or UFFS_ECC_HW_AUTO, you MUST implement WritePageWithLayout(). - * Implement WritePage() function if you have ecc_opt UFFS_ECC_NONE or UFFS_ECC_SOFT and - * WritePageWithLayout() is not implemented. - * - * \note If data == NULL && spare == NULL, driver should mark this block as a 'bad block'. - * - * \return #UFFS_FLASH_NO_ERR: success - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_BAD_BLK: a bad block detected. - */ - int (*WritePage)(uffs_Device *dev, u32 block, u32 page, - const u8 *data, int data_len, const u8 *spare, int spare_len); - - /** - * Write full page, flash driver do the layout for spare area. - * - * \note if layout_opt is UFFS_LAYOUT_FLASH or ecc_opt is UFFS_ECC_HW/UFFS_ECC_HW_AUTO, flash driver MUST implement - * this function. UFFS will use this function (if provided) prio to 'WritePage()' - * - * \param[in] ecc ecc of data. if ecc_opt is UFFS_ECC_SOFT and this function is implemented, - * UFFS will calculate page data ecc and pass it to WritePageWithLayout(). - * if ecc_opt is UFFS_ECC_NONE/UFFS_ECC_HW/UFFS_ECC_HW_AUTO, UFFS pass ecc = NULL. - * - * \note If data == NULL && ts == NULL, driver should mark this block as a 'bad block'. - * - * \return #UFFS_FLASH_NO_ERR: success - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_BAD_BLK: a bad block detected. - */ - int (*WritePageWithLayout)(uffs_Device *dev, u32 block, u32 page, - const u8 *data, int data_len, const u8 *ecc, const uffs_TagStore *ts); - - /** - * Check block status. - * - * \note flash driver may maintain a bad block table to speed up bad block checking or - * it will require one or two read spare I/O to check block status. - * - * \note if this function is not implented by driver, UFFS check the block_status byte in spare. - * - * \return 1 if it's a bad block, 0 if it's not. - */ - int (*IsBadBlock)(uffs_Device *dev, u32 block); - - /** - * Mark a new bad block. - * - * \note if this function is not implemented, UFFS mark bad block by call 'WritePage()/WritePageWithLayout()' - * with: data == NULL && spare == NULL && ts == NULL. - * - * \return 0 if success, otherwise return -1. - */ - int (*MarkBadBlock)(uffs_Device *dev, u32 block); - - /** - * Erase a block, driver MUST implement this function. - * - * \return #UFFS_FLASH_NO_ERR: success - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_BAD_BLK: a bad block detected. - */ - int (*EraseBlock)(uffs_Device *dev, u32 block); -}; - -/** make spare from tag store and ecc */ -void uffs_FlashMakeSpare(uffs_Device *dev, const uffs_TagStore *ts, const u8 *ecc, u8* spare); - -/** unload tag and ecc from spare */ -void uffs_FlashUnloadSpare(uffs_Device *dev, const u8 *spare, struct uffs_TagStoreSt *ts, u8 *ecc); - -/** read page spare and fill to tag */ -int uffs_FlashReadPageTag(uffs_Device *dev, int block, int page, uffs_Tags *tag); - -/** read page data to page buf and do ECC correct */ -int uffs_FlashReadPage(uffs_Device *dev, int block, int page, uffs_Buf *buf, UBOOL skip_ecc); - -/** write page data and spare */ -int uffs_FlashWritePageCombine(uffs_Device *dev, int block, int page, uffs_Buf *buf, uffs_Tags *tag); - -/** Mark this block as bad block */ -int uffs_FlashMarkBadBlock(uffs_Device *dev, int block); - -/** Is this block a bad block ? */ -UBOOL uffs_FlashIsBadBlock(uffs_Device *dev, int block); - -/** Erase flash block */ -int uffs_FlashEraseBlock(uffs_Device *dev, int block); - -/* mark a clean page as 'dirty' (and 'invalid') */ -int uffs_FlashMarkDirtyPage(uffs_Device *dev, uffs_BlockInfo *bc, int page); - -/* check if the block pages are all clean */ -URET uffs_FlashCheckErasedBlock(uffs_Device *dev, int block); - -/** - * get page head info - * - * \return #UFFS_PAGE_INFO_IOERR if I/O error, otherwise return page info - */ -u32 uffs_FlashGetPageInfo(uffs_Device *dev, int block, int page); - -/** load uffs_FileInfo from flash storage */ -URET uffs_FlashReadFileinfoPhy(uffs_Device *dev, int block, int page, uffs_FileInfo *info); - -/** - * Initialize UFFS flash interface - */ -URET uffs_FlashInterfaceInit(uffs_Device *dev); - -/** - * Release UFFS flash interface - */ -URET uffs_FlashInterfaceRelease(uffs_Device *dev); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_fs.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_fs.h deleted file mode 100644 index 7bda09052e..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_fs.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fs.h - * \brief uffs basic file operations - * \author Ricky Zheng - */ - -#ifndef _UFFS_FS_H_ -#define _UFFS_FS_H_ - -#include "uffs/uffs_types.h" -#include "uffs/uffs.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_core.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/** file object */ -struct uffs_ObjectSt { - /******* objects manager ********/ - int dev_lock_count; - int dev_get_count; - - /******** init level 0 ********/ - const char * name; //!< pointer to the start of name, for open or create - u32 name_len; //!< name length - u16 sum; //!< sum of name - uffs_Device *dev; //!< uffs device - u32 oflag; - u8 type; - u16 head_pages; //!< data pages on file head block - u16 parent; - - /******* init level 1 ********/ - TreeNode *node; //!< file entry node in tree - u16 serial; - - /******* output ******/ - int err; //!< error number - - /******* current *******/ - u32 pos; //!< current position in file - - /***** others *******/ - UBOOL attr_loaded; //!< attributes loaded ? - UBOOL open_succ; //!< U_TRUE or U_FALSE - -}; - -typedef struct uffs_ObjectSt uffs_Object; - - - -#define uffs_GetObjectErr(obj) ((obj)->err) -#define uffs_ClearObjectErr(obj) do { (obj)->err = UENOERR; } while (0) - -uffs_Pool * uffs_GetObjectPool(void); - -URET uffs_InitObjectBuf(void); -URET uffs_ReleaseObjectBuf(void); -int uffs_PutAllObjectBuf(uffs_Device *dev); -uffs_Object * uffs_GetObject(void); -void uffs_PutObject(uffs_Object *obj); -int uffs_GetObjectIndex(uffs_Object *obj); -uffs_Object * uffs_GetObjectByIndex(int idx); - - -/** - * Re-initialize an object. - * should call this function if you want to re-use an object. - */ -URET uffs_ReInitObject(uffs_Object *obj); - -URET uffs_ParseObject(uffs_Object *obj, const char *name); - -URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev, - int dir, const char *name, int name_len, int oflag); -URET uffs_OpenObjectEx(uffs_Object *obj, uffs_Device *dev, - int dir, const char *name, int name_len, int oflag); - -URET uffs_OpenObject(uffs_Object *obj, const char *fullname, int oflag); -URET uffs_TruncateObject(uffs_Object *obj, u32 remain); -URET uffs_CreateObject(uffs_Object *obj, const char *fullname, int oflag); - -URET uffs_CloseObject(uffs_Object *obj); -int uffs_WriteObject(uffs_Object *obj, const void *data, int len); -int uffs_ReadObject(uffs_Object *obj, void *data, int len); -long uffs_SeekObject(uffs_Object *obj, long offset, int origin); -int uffs_GetCurOffset(uffs_Object *obj); -int uffs_EndOfFile(uffs_Object *obj); -URET uffs_FlushObject(uffs_Object *obj); - -URET uffs_RenameObject(const char *old_name, const char *new_name, int *err); -URET uffs_DeleteObject(const char * name, int *err); - -int uffs_GetFreeObjectHandlers(void); - - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mem.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mem.h deleted file mode 100644 index ad9a38f458..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mem.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -#ifndef _UFFS_MEM_H_ -#define _UFFS_MEM_H_ - -#include "uffs/uffs_device.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/** uffs memory allocator */ -typedef struct uffs_memAllocatorSt { - URET (*init)(struct uffs_DeviceSt *dev); //!< init memory allocator, setup buffer sizes - URET (*release)(struct uffs_DeviceSt *dev); //!< release memory allocator (for dynamic memory allocation) - - void * (*malloc)(struct uffs_DeviceSt *dev, unsigned int size); //!< allocate memory (for dynamic memory allocation) - URET (*free)(struct uffs_DeviceSt *dev, void *p); //!< free memory (for dynamic memory allocation) - - void * blockinfo_pool_buf; //!< block info cache buffers - void * pagebuf_pool_buf; //!< page buffers - void * tree_nodes_pool_buf; //!< tree nodes buffer - void * spare_pool_buf; //!< spare buffers - - int blockinfo_pool_size; //!< block info cache buffers size - int pagebuf_pool_size; //!< page buffers size - int tree_nodes_pool_size; //!< tree nodes buffer size - int spare_pool_size; //!< spare buffer pool size - - uffs_Pool tree_pool; - uffs_Pool spare_pool; - - int spare_data_size; //!< spare size consumed by UFFS, - //!< calculated by UFFS according to the layout information. - - /* for static memory allocator */ - char *buf_start; - int buf_size; - int pos; - - -} uffs_MemAllocator; - -void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator); -void uffs_MemSetupStaticAllocator(uffs_MemAllocator *allocator, void *pool, int size); - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h deleted file mode 100644 index 41259e57e9..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_mtb.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_mtb.h - * \brief mount table related stuff - * \author Ricky Zheng - */ - -#ifndef _UFFS_MTB_H_ -#define _UFFS_MTB_H_ - -#include "uffs/uffs_types.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - -typedef struct uffs_MountTableEntrySt { - uffs_Device *dev; // UFFS 'device' - core internal data structure for partition - int start_block; // partition start block - int end_block; // partition end block ( if < 0, reserve space form the end of storage) - const char *mount; // mount point - struct uffs_MountTableEntrySt *prev; - struct uffs_MountTableEntrySt *next; -} uffs_MountTable; - -/** Register mount entry, will be put at 'unmounted' list */ -int uffs_RegisterMountTable(uffs_MountTable *mtb); - -/** Remove mount entry from the list */ -int uffs_UnRegisterMountTable(uffs_MountTable *mtb); - -/** mount partition */ -int uffs_Mount(const char *mount); - -/** unmount parttion */ -int uffs_UnMount(const char *mount); - -/** get mounted entry list */ -uffs_MountTable * uffs_MtbGetMounted(void); - -/** get unmounted entry list */ -uffs_MountTable * uffs_MtbGetUnMounted(void); - -/** get matched mount point from absolute path */ -int uffs_GetMatchedMountPointSize(const char *path); - -/** get uffs device from mount point */ -uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount); - -/** get uffs device from mount point */ -uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len); - -/** get mount point name from uffs device */ -const char * uffs_GetDeviceMountPoint(uffs_Device *dev); - -/** down crease uffs device references by uffs_GetDeviceXXX() */ -void uffs_PutDevice(uffs_Device *dev); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_os.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_os.h deleted file mode 100644 index b75e77bcc9..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_os.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -#ifndef _UFFS_OS_H_ -#define _UFFS_OS_H_ - -#include <rtthread.h> -#define RT_THREAD -#if !defined(RT_THREAD) -#include <stdarg.h> -#endif - -#ifdef __cplusplus -extern "C"{ -#endif - -#define UFFS_TASK_ID_NOT_EXIST -1 - -typedef void * OSSEM; -#define OSSEM_NOT_INITED (NULL) - -#if !defined(RT_THREAD) -struct uffs_DebugMsgOutputSt { - void (*output)(const char *msg); - void (*vprintf)(const char *fmt, va_list args); -}; - -void uffs_SetupDebugOutput(void); -#endif - -/* OS specific functions */ -int uffs_SemCreate(OSSEM *sem); -int uffs_SemWait(OSSEM sem); -int uffs_SemSignal(OSSEM sem); -int uffs_SemDelete(OSSEM *sem); - -int uffs_OSGetTaskId(void); //get current task id -unsigned int uffs_GetCurDateTime(void); - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_pool.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_pool.h deleted file mode 100644 index 78826fc246..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_pool.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_pool.h - * \brief Fast fixed size memory pool management. - * \author Ricky Zheng, Simon Kallweit - */ - -#ifndef _UFFS_POOL_H_ -#define _UFFS_POOL_H_ - - -#include "uffs/uffs_types.h" -#include "uffs/uffs_os.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -/** - * \struct uffs_PoolEntrySt - * \brief Helper type for free buffer entries. - */ -typedef struct uffs_PoolEntrySt { - struct uffs_PoolEntrySt *next; -} uffs_PoolEntry; - -/** - * \struct uffs_PoolSt - * \brief Memory pool. - */ -typedef struct uffs_PoolSt { - u8 *mem; //!< memory pool - u32 buf_size; //!< size of a buffer - u32 num_bufs; //!< number of buffers in the pool - uffs_PoolEntry *free_list; //!< linked list of free buffers - OSSEM sem; //!< buffer lock -} uffs_Pool; - -URET uffs_PoolInit(uffs_Pool *pool, void *mem, u32 mem_size, u32 buf_size, u32 num_bufs); -URET uffs_PoolRelease(uffs_Pool *pool); - -UBOOL uffs_PoolVerify(uffs_Pool *pool, void *p); - -void *uffs_PoolGet(uffs_Pool *pool); -void *uffs_PoolGetLocked(uffs_Pool *pool); - -int uffs_PoolPut(uffs_Pool *pool, void *p); -int uffs_PoolPutLocked(uffs_Pool *pool, void *p); - -void *uffs_PoolGetBufByIndex(uffs_Pool *pool, u32 index); -u32 uffs_PoolGetIndex(uffs_Pool *pool, void *p); -UBOOL uffs_PoolCheckFreeList(uffs_Pool *pool, void *p); - -void * uffs_PoolFindNextAllocated(uffs_Pool *pool, void *from); - -int uffs_PoolGetFreeCount(uffs_Pool *pool); -int uffs_PoolPutAll(uffs_Pool *pool); - -#ifdef __cplusplus -} -#endif - -#endif // _UFFS_POOL_H_ diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h deleted file mode 100644 index 9c22004898..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_public.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_public.h - * \brief public data structures for uffs - * \author Ricky Zheng - */ - -#ifndef _UFFS_PUBLIC_H_ -#define _UFFS_PUBLIC_H_ - -#include "uffs/uffs_types.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs.h" -#include "uffs/uffs_pool.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0])) -#endif - -#ifndef offsetof -# define offsetof(T, x) ((size_t) &((T *)0)->x) -#endif -#ifndef container_of -#define container_of(p, T, x) ((T *)((char *)(p) - offsetof(T,x))) -#endif - -/** - * \def MAX_FILENAME_LENGTH - * \note Be careful: it's part of the physical format (see: uffs_FileInfoSt.name) - * !!DO NOT CHANGE IT AFTER FILE SYSTEM IS FORMATED!! - */ -#define MAX_FILENAME_LENGTH 128 - -/** \note 8-bits attr goes to uffs_dirent::d_type */ -#define FILE_ATTR_DIR (1 << 7) //!< attribute for directory -#define FILE_ATTR_WRITE (1 << 0) //!< writable - - -/** - * \structure uffs_FileInfoSt - * \brief file/dir entry info in physical storage format - */ -struct uffs_FileInfoSt { - u32 attr; //!< file/dir attribute - u32 create_time; - u32 last_modify; - u32 access; - u32 reserved; - u32 name_len; //!< length of file/dir name - char name[MAX_FILENAME_LENGTH]; -}; //6*4 + sizeof(name) = 24 + 128 = 152 Bytes -typedef struct uffs_FileInfoSt uffs_FileInfo; - -/** - * \struct uffs_ObjectInfoSt - * \brief object info - */ -typedef struct uffs_ObjectInfoSt { - uffs_FileInfo info; - u32 len; //!< length of file - u16 serial; //!< object serial num -} uffs_ObjectInfo; - - -/** - * \struct uffs_TagStoreSt - * \brief uffs tag, 8 bytes, will be store in page spare area. - */ -struct uffs_TagStoreSt { - u32 dirty:1; //!< 0: dirty, 1: clear - u32 valid:1; //!< 0: valid, 1: invalid - u32 type:2; //!< block type: #UFFS_TYPE_DIR, #UFFS_TYPE_FILE, #UFFS_TYPE_DATA - u32 block_ts:2; //!< time stamp of block; - u32 data_len:12; //!< length of page data - u32 serial:14; //!< serial number - - u32 parent:10; //!< parent's serial number - u32 page_id:6; //!< page id - u32 reserved:4; //!< reserved, for UFFS2 - u32 tag_ecc:12; //!< tag ECC -}; - -#define TAG_ECC_DEFAULT (0xFFF) //!< 12-bit '1' - - -/** - * \struct uffs_TagsSt - */ -struct uffs_TagsSt { - struct uffs_TagStoreSt s; /* store must be the first member */ - - /** data_sum for file or dir name */ - u16 data_sum; - - /** internal used */ - u8 seal_byte; //!< seal byte. -}; - -/** - * \struct uffs_MiniHeaderSt - * \brief the mini header resides on the head of page data - */ -struct uffs_MiniHeaderSt { - u8 status; - u8 reserved; - u16 crc; -}; - - -/** uffs_TagsSt.dirty */ -#define TAG_VALID 0 -#define TAG_INVALID 1 - -/** uffs_TagsSt.valid */ -#define TAG_DIRTY 0 -#define TAG_CLEAR 1 - -#define TAG_IS_DIRTY(tag) (*((u32 *) &((tag)->s)) != 0xFFFFFFFF) // tag is dirty if first 4 bytes not all 0xFF -#define TAG_IS_VALID(tag) ((tag)->s.valid == TAG_VALID) -#define TAG_IS_SEALED(tag) ((tag)->seal_byte != 0xFF) - -#define TAG_IS_GOOD(tag) (TAG_IS_SEALED(tag) && TAG_IS_VALID(tag)) - -#define TAG_VALID_BIT(tag) (tag)->s.valid -#define TAG_DIRTY_BIT(tag) (tag)->s.dirty -#define TAG_SERIAL(tag) (tag)->s.serial -#define TAG_PARENT(tag) (tag)->s.parent -#define TAG_PAGE_ID(tag) (tag)->s.page_id -#define TAG_DATA_LEN(tag) (tag)->s.data_len -#define TAG_TYPE(tag) (tag)->s.type -#define TAG_BLOCK_TS(tag) (tag)->s.block_ts -#define SEAL_TAG(tag) (tag)->seal_byte = 0 - -int uffs_GetFirstBlockTimeStamp(void); -int uffs_GetNextBlockTimeStamp(int prev); -UBOOL uffs_IsSrcNewerThanObj(int src, int obj); - - -#include "uffs_device.h" - - - -/********************************** debug & error *************************************/ -#define UFFS_MSG_NOISY -1 -#define UFFS_MSG_NORMAL 0 -#define UFFS_MSG_SERIOUS 1 -#define UFFS_MSG_DEAD 2 -#define UFFS_MSG_NOMSG 100 - -#define TENDSTR "\n" - -#if !defined(RT_THREAD) -struct uffs_DebugMsgOutputSt; -URET uffs_InitDebugMessageOutput(struct uffs_DebugMsgOutputSt *ops, int msg_level); -void uffs_DebugSetMessageLevel(int msg_level); - -void uffs_DebugMessage(int level, const char *prefix, const char *suffix, const char *errFmt, ...); -void uffs_AssertCall(const char *file, int line, const char *msg, ...); -#else - -#define UFFS_DBG_LEVEL UFFS_MSG_NORMAL - -#ifdef CONFIG_ENABLE_UFFS_DEBUG_MSG -#define uffs_DebugMessage(level, prefix, suffix, errFmt, ...) do { \ - if (level >= UFFS_DBG_LEVEL) \ - rt_kprintf(prefix errFmt suffix, ##__VA_ARGS__); \ -} while(0) - -#define uffs_AssertCall(file, line, msg, ...) \ - rt_kprintf("ASSERT %s:%d - :" msg "\n", (const char *)file, (int)line, ##__VA_ARGS__) -#else -#define uffs_DebugMessage(level, prefix, suffix, errFmt, ...) -#define uffs_AssertCall(file, line, msg, ...) -#endif //CONFIG_ENABLE_UFFS_DEBUG_MSG -#endif //RT_THREAD - -#ifdef _COMPILER_DO_NOT_SUPPORT_MACRO_VALIST_REPLACE_ -/* For those compilers do not support valist parameter replace in macro define */ -void uffs_Perror(int level, const char *fmt, ...); -void uffs_PerrorRaw(int level, const char *fmt, ...); -UBOOL uffs_Assert(UBOOL expr, const char *fmt, ...); -#else - -#if !defined(RT_THREAD) -#define uffs_Perror(level, fmt, ... ) \ - uffs_DebugMessage(level, PFX, TENDSTR, fmt, ## __VA_ARGS__) - -#define uffs_PerrorRaw(level, fmt, ... ) \ - uffs_DebugMessage(level, NULL, NULL, fmt, ## __VA_ARGS__) - -#else - -#ifdef CONFIG_ENABLE_UFFS_DEBUG_MSG - -#define uffs_Perror(level, fmt, ... ) do{\ - if (level >= UFFS_DBG_LEVEL) \ - rt_kprintf(PFX fmt TENDSTR, ##__VA_ARGS__); \ -} while(0) - -#define uffs_PerrorRaw(level, fmt, ... ) do{\ - if (level >= UFFS_DBG_LEVEL) \ - rt_kprintf(fmt, ##__VA_ARGS__); \ -} while(0) -#else -#define uffs_Perror(level, fmt, ... ) -#define uffs_PerrorRaw(level, fmt, ... ) -#endif // CONFIG_ENABLE_UFFS_DEBUG_MSG -#endif // RT_THREAD - -#define uffs_Assert(expr, msg, ...) \ - ((expr) ? U_TRUE : (uffs_AssertCall(__FILE__, __LINE__, msg, ## __VA_ARGS__), U_FALSE)) - -#endif //_COMPILER_DO_NOT_SUPPORT_MACRO_VALIST_REPLACE_ - -#define uffs_Panic() \ - do { \ - uffs_AssertCall(__FILE__, __LINE__, "Bam !!\n"); \ - while(1); \ - } while(0) - -/********************************** NAND **********************************************/ -//NAND flash specific file must implement these interface -URET uffs_LoadPageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag); -URET uffs_WritePageSpare(uffs_Device *dev, int block, int page, uffs_Tags *tag); -URET uffs_MakePageValid(uffs_Device *dev, int block, int page, uffs_Tags *tag); -UBOOL uffs_IsBlockBad(uffs_Device *dev, uffs_BlockInfo *bc); - -/********************************** Public defines *****************************/ -/** - * \def UFFS_ALL_PAGES - * \brief UFFS_ALL_PAGES if this value presented, that means the objects are all pages in the block - */ -#define UFFS_ALL_PAGES (0xffff) - -/** - * \def UFFS_INVALID_PAGE - * \brief macro for invalid page number - */ -#define UFFS_INVALID_PAGE (0xfffe) - -/** - * \def UFFS_INVALID_BLOCK - * \brief macro for invalid block number - */ -#define UFFS_INVALID_BLOCK (0xfffe) - - -URET uffs_NewBlock(uffs_Device *dev, u16 block, uffs_Tags *tag, uffs_Buf *buf); -URET uffs_BlockRecover(uffs_Device *dev, uffs_BlockInfo *old, u16 newBlock); -URET uffs_PageRecover(uffs_Device *dev, - uffs_BlockInfo *bc, - u16 oldPage, - u16 newPage, - uffs_Buf *buf); -int uffs_FindFreePageInBlock(uffs_Device *dev, uffs_BlockInfo *bc); -u16 uffs_FindBestPageInBlock(uffs_Device *dev, uffs_BlockInfo *bc, u16 page); -u16 uffs_FindFirstFreePage(uffs_Device *dev, uffs_BlockInfo *bc, u16 pageFrom); -u16 uffs_FindPageInBlockWithPageId(uffs_Device *dev, uffs_BlockInfo *bc, u16 page_id); - -u8 uffs_MakeSum8(const void *p, int len); -u16 uffs_MakeSum16(const void *p, int len); -URET uffs_CreateNewFile(uffs_Device *dev, u16 parent, u16 serial, uffs_BlockInfo *bc, uffs_FileInfo *fi); - -int uffs_GetBlockFileDataLength(uffs_Device *dev, uffs_BlockInfo *bc, u8 type); -UBOOL uffs_IsPageErased(uffs_Device *dev, uffs_BlockInfo *bc, u16 page); -int uffs_GetFreePagesCount(uffs_Device *dev, uffs_BlockInfo *bc); -UBOOL uffs_IsDataBlockReguFull(uffs_Device *dev, uffs_BlockInfo *bc); -UBOOL uffs_IsThisBlockUsed(uffs_Device *dev, uffs_BlockInfo *bc); - -int uffs_GetBlockTimeStamp(uffs_Device *dev, uffs_BlockInfo *bc); - -int uffs_GetDeviceUsed(uffs_Device *dev); -int uffs_GetDeviceFree(uffs_Device *dev); -int uffs_GetDeviceTotal(uffs_Device *dev); - -URET uffs_LoadMiniHeader(uffs_Device *dev, int block, u16 page, struct uffs_MiniHeaderSt *header); - - -/* some functions from uffs_fd.c */ -void uffs_FdSignatureIncrease(void); -URET uffs_DirEntryBufInit(void); -URET uffs_DirEntryBufRelease(void); -uffs_Pool * uffs_DirEntryBufGetPool(void); -int uffs_DirEntryBufPutAll(uffs_Device *dev); - - -/************************************************************************/ -/* init functions */ -/************************************************************************/ -URET uffs_InitDevice(uffs_Device *dev); -URET uffs_ReleaseDevice(uffs_Device *dev); - -URET uffs_InitFileSystemObjects(void); -URET uffs_ReleaseFileSystemObjects(void); - - -#ifdef __cplusplus -} -#endif -#endif // _UFFS_PUBLIC_H_ - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h deleted file mode 100644 index 6a505a839f..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_tree.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -#ifndef _UFFS_TREE_H_ -#define _UFFS_TREE_H_ - -#include "uffs/uffs_types.h" -#include "uffs/uffs_pool.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_core.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -#define UFFS_TYPE_DIR 0 -#define UFFS_TYPE_FILE 1 -#define UFFS_TYPE_DATA 2 -#define UFFS_TYPE_RESV 3 -#define UFFS_TYPE_INVALID 0xFF - -struct uffs_NodeTypeNameMapSt { - int type; - const char *name; -}; - -#define UFFS_TYPE_NAME_MAP { \ - {UFFS_TYPE_DIR, "DIR"}, \ - {UFFS_TYPE_FILE, "FILE"}, \ - {UFFS_TYPE_DATA, "DATA"}, \ - {UFFS_TYPE_RESV, "RESV"}, \ - {UFFS_TYPE_INVALID, "INVALID"} \ -} - -struct BlockListSt { /* 12 bytes */ - struct uffs_TreeNodeSt * next; - struct uffs_TreeNodeSt * prev; - u16 block; - union { - u16 serial; /* for suspended block list */ - u8 need_check; /* for erased block list */ - } u; -}; - -struct DirhSt { /* 8 bytes */ - u16 checksum; /* check sum of dir name */ - u16 block; - u16 parent; - u16 serial; -}; - - -struct FilehSt { /* 12 bytes */ - u16 block; - u16 checksum; /* check sum of file name */ - u16 parent; - u16 serial; - u32 len; /* file length total */ -}; - -struct FdataSt { /* 10 bytes */ - u16 block; - u16 parent; - u32 len; /* file data length on this block */ - u16 serial; -}; - -//UFFS TreeNode (14 or 16 bytes) -typedef struct uffs_TreeNodeSt { - union { - struct BlockListSt list; - struct DirhSt dir; - struct FilehSt file; - struct FdataSt data; - } u; - u16 hash_next; - u16 hash_prev; -} TreeNode; - - -//TODO: UFFS2 Tree structures -/* -struct FdataSt { - u32 len; -}; - -struct filebSt { - u16 bls; //how many blocks this file contents ... - u8 offs; //the offset of this file header on FILE block - u8 sum; //short sum of file name -}; - -//Extra data structure for storing file length information -struct FilehSt { - u32 len; -}; - -//UFFS2 TreeNode (12 bytes) -typedef struct uffs_TreeNodeSt { - u16 nextIdx; - u16 block; - u16 parent; - u16 serial; - union { - struct FilehSt h; - struct filedSt file; - struct data; - } u; -} TreeNode; - -*/ - - -#define EMPTY_NODE 0xffff //!< special index num of empty node. - -#define ROOT_DIR_SERIAL 0 //!< serial num of root dir -#define MAX_UFFS_FSN 0x3ff //!< maximum dir|file serial number (uffs_TagStore#parent: 10 bits) -#define MAX_UFFS_FDN 0x3fff //!< maximum file data block serial numbers (uffs_TagStore#serial: 14 bits) -#define PARENT_OF_ROOT 0xfffd //!< parent of ROOT ? kidding me ... -#define INVALID_UFFS_SERIAL 0xffff //!< invalid serial num - -#define DIR_NODE_HASH_MASK 0x1f -#define DIR_NODE_ENTRY_LEN (DIR_NODE_HASH_MASK + 1) - -#define FILE_NODE_HASH_MASK 0x3f -#define FILE_NODE_ENTRY_LEN (FILE_NODE_HASH_MASK + 1) - -#define DATA_NODE_HASH_MASK 0x1ff -#define DATA_NODE_ENTRY_LEN (DATA_NODE_HASH_MASK + 1) -#define FROM_IDX(idx, pool) ((TreeNode *)uffs_PoolGetBufByIndex(pool, idx)) -#define TO_IDX(p, pool) ((u16)uffs_PoolGetIndex(pool, (void *) p)) - - -#define GET_FILE_HASH(serial) (serial & FILE_NODE_HASH_MASK) -#define GET_DIR_HASH(serial) (serial & DIR_NODE_HASH_MASK) -#define GET_DATA_HASH(parent, serial) ((parent + serial) & DATA_NODE_HASH_MASK) - - -struct uffs_TreeSt { - TreeNode *erased; //!< erased block list head - TreeNode *erased_tail; //!< erased block list tail - TreeNode *suspend; //!< suspended block list - int erased_count; //!< erased block counter - TreeNode *bad; //!< bad block list - int bad_count; //!< bad block count - u16 dir_entry[DIR_NODE_ENTRY_LEN]; - u16 file_entry[FILE_NODE_ENTRY_LEN]; - u16 data_entry[DATA_NODE_ENTRY_LEN]; - u16 max_serial; -}; - - -URET uffs_TreeInit(uffs_Device *dev); -URET uffs_TreeRelease(uffs_Device *dev); -URET uffs_BuildTree(uffs_Device *dev); -u16 uffs_FindFreeFsnSerial(uffs_Device *dev); -TreeNode * uffs_TreeFindFileNode(uffs_Device *dev, u16 serial); -TreeNode * uffs_TreeFindFileNodeWithParent(uffs_Device *dev, u16 parent); -TreeNode * uffs_TreeFindDirNode(uffs_Device *dev, u16 serial); -TreeNode * uffs_TreeFindDirNodeWithParent(uffs_Device *dev, u16 parent); -TreeNode * uffs_TreeFindFileNodeByName(uffs_Device *dev, const char *name, u32 len, u16 sum, u16 parent); -TreeNode * uffs_TreeFindDirNodeByName(uffs_Device *dev, const char *name, u32 len, u16 sum, u16 parent); -TreeNode * uffs_TreeFindDataNode(uffs_Device *dev, u16 parent, u16 serial); - - -TreeNode * uffs_TreeFindDirNodeByBlock(uffs_Device *dev, u16 block); -TreeNode * uffs_TreeFindFileNodeByBlock(uffs_Device *dev, u16 block); -TreeNode * uffs_TreeFindDataNodeByBlock(uffs_Device *dev, u16 block); -TreeNode * uffs_TreeFindErasedNodeByBlock(uffs_Device *dev, u16 block); -TreeNode * uffs_TreeFindBadNodeByBlock(uffs_Device *dev, u16 block); - -void uffs_TreeSuspendAdd(uffs_Device *dev, TreeNode *node); -TreeNode * uffs_TreeFindSuspendNode(uffs_Device *dev, u16 serial); -void uffs_TreeRemoveSuspendNode(uffs_Device *dev, TreeNode *node); - -#define SEARCH_REGION_DIR 1 -#define SEARCH_REGION_FILE 2 -#define SEARCH_REGION_DATA 4 -#define SEARCH_REGION_BAD 8 -#define SEARCH_REGION_ERASED 16 -TreeNode * uffs_TreeFindNodeByBlock(uffs_Device *dev, u16 block, int *region); - - - -UBOOL uffs_TreeCompareFileName(uffs_Device *dev, const char *name, u32 len, u16 sum, TreeNode *node, int type); - -TreeNode * uffs_TreeGetErasedNode(uffs_Device *dev); - -void uffs_InsertNodeToTree(uffs_Device *dev, u8 type, TreeNode *node); -void uffs_InsertToErasedListHead(uffs_Device *dev, TreeNode *node); -void uffs_TreeInsertToErasedListTail(uffs_Device *dev, TreeNode *node); -void uffs_TreeInsertToErasedListTailEx(uffs_Device *dev, TreeNode *node, int need_check); -void uffs_TreeInsertToBadBlockList(uffs_Device *dev, TreeNode *node); - -void uffs_BreakFromEntry(uffs_Device *dev, u8 type, TreeNode *node); - -void uffs_TreeSetNodeBlock(u8 type, TreeNode *node, u16 block); - - -#ifdef __cplusplus -} -#endif - - - -#endif - - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_types.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_types.h deleted file mode 100644 index c81b37970b..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_types.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -#ifndef _UFFS_TYPES_H_ -#define _UFFS_TYPES_H_ - -#ifdef __CDT_PARSER__ -#undef __cplusplus -#endif - -#ifdef __cplusplus -extern "C"{ -#endif - -#ifdef _UBASE_ -#include <sys/utypes.h> -#endif - -/** - * \file uffs_types.h - * \brief basic types used on uffs - * \author Ricky Zheng - */ - -/* basic types */ - -/** \typedef i8 - * \brief 8 bit integer - */ -typedef char i8; - -/** \typedef u8 - * \brief 8 bit unsigned integer - */ -typedef unsigned char u8; - -/** \typedef i16 - * \brief 16 bit integer - */ -typedef short int i16; - - -/** \typedef u16 - * \brief 16 bit unsigned integer - */ -typedef unsigned short int u16; - - -/** \typedef i32 - * \brief 32 bit integer - */ -typedef int i32; - -/** \typedef u32 - * \brief 32 bit unsigned integer - */ -typedef unsigned int u32; - - -#ifndef _UBASE_ - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - -/* boolean type */ - -/** \typedef UBOOL - * \brief boolean type for uffs, the value would be: #U_TRUE or #U_FALSE - */ -typedef int UBOOL; - -/** \def U_TRUE - * \brief boolean true for uffs - */ -#define U_TRUE (TRUE) - - -/** \def U_FALSE - * \brief boolean false for uffs - */ -#define U_FALSE (FALSE) - - -/** \typedef URET - * \brief return type for uffs, should be #U_FAIL or #U_SUCC - */ -typedef int URET; - -/** \def U_FAIL - * \brief indicator of fail - */ -#define U_FAIL -1 - -/** \def U_SUCC - * \brief indicator of successful - */ -#define U_SUCC 0 - -/** \def IS_SUCC(ret) - * \brief is it successful ? - */ -#define IS_SUCC(ret) (ret >= 0 ? U_TRUE : U_FALSE) - - -/** \def IS_FAIL(ret) - * \brief is it fail ? - */ -#define IS_FAIL(ret) (ret < 0 ? U_TRUE : U_FALSE) - -#ifndef NULL -/** \def NULL - * \brief zero for pointer - */ -#define NULL 0 -#endif - -#endif // _UBASE_ - - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_utils.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_utils.h deleted file mode 100644 index ae03cb4ab1..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_utils.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -#ifndef _UFFS_UTILS_H_ -#define _UFFS_UTILS_H_ - -#include "uffs/uffs_types.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_core.h" - -#ifdef __cplusplus -extern "C"{ -#endif - - -//get UFFS disk version, if fail, return 0 -int uffs_GetUFFSVersion(struct uffs_DeviceSt *dev); - -void uffs_InitGlobalFsLock(void); -void uffs_ReleaseGlobalFsLock(void); -void uffs_GlobalFsLockLock(void); -void uffs_GlobalFsLockUnlock(void); - -URET uffs_FormatDevice(uffs_Device *dev, UBOOL force); - -#ifdef __cplusplus -} -#endif - -typedef void dump_msg_cb(struct uffs_DeviceSt *dev, const char *fmt, ...); - -void uffs_DumpDevice(struct uffs_DeviceSt *dev, dump_msg_cb *dump); - -#endif - diff --git a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_version.h b/components/dfs/filesystems/uffs/src/inc/uffs/uffs_version.h deleted file mode 100644 index 9ea3154205..0000000000 --- a/components/dfs/filesystems/uffs/src/inc/uffs/uffs_version.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -#ifndef _UFFS_VERSION_H_ -#define _UFFS_VERSION_H_ - -#ifdef __cplusplus -extern "C"{ -#endif - - -#define UFFS_VERSION 0x01030400 //"01.03.0400" - -const char * uffs_Version2Str(int ver); -int uffs_GetVersion(void); -int uffs_GetMainVersion(int ver); -int uffs_GetMinorVersion(int ver); -int uffs_GetTrivialVersion(int ver); - -#ifdef __cplusplus -} -#endif - - -#endif - diff --git a/components/dfs/filesystems/uffs/src/platform/CMakeLists.txt b/components/dfs/filesystems/uffs/src/platform/CMakeLists.txt deleted file mode 100644 index dd33c737e5..0000000000 --- a/components/dfs/filesystems/uffs/src/platform/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -IF (UNIX) - SET (libplatform_SRCS posix/uffs_os.c posix/uffs_config.h) - INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/posix) -ENDIF() - -IF (WIN32) - SET (libplatform_SRCS win32/uffs_os.c win32/uffs_config.h) - INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/win32) -ENDIF() - -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc) -ADD_LIBRARY(platform STATIC ${libplatform_SRCS} ) - diff --git a/components/dfs/filesystems/uffs/src/platform/posix/uffs_config.h b/components/dfs/filesystems/uffs/src/platform/posix/uffs_config.h deleted file mode 100644 index 2f0b6992bb..0000000000 --- a/components/dfs/filesystems/uffs/src/platform/posix/uffs_config.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_config.h - * \brief basic configuration of uffs - * \author Ricky Zheng - */ - -#ifndef _UFFS_CONFIG_H_ -#define _UFFS_CONFIG_H_ - -/** - * \def UFFS_MAX_PAGE_SIZE - * \note maximum page size UFFS support - */ -#define UFFS_MAX_PAGE_SIZE 2048 - -/** - * \def UFFS_MAX_SPARE_SIZE - */ -#define UFFS_MAX_SPARE_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 8) - -/** - * \def UFFS_MAX_ECC_SIZE - */ -#define UFFS_MAX_ECC_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 5) - -/** - * \def MAX_CACHED_BLOCK_INFO - * \note uffs cache the block info for opened directories and files, - * a practical value is 5 ~ MAX_OBJECT_HANDLE - */ -#define MAX_CACHED_BLOCK_INFO 50 - -/** - * \def MAX_PAGE_BUFFERS - * \note the bigger value will bring better read/write performance. - * but few writing performance will be improved when this - * value is become larger than 'max pages per block' - */ -#define MAX_PAGE_BUFFERS 40 - - -/** - * \def CLONE_BUFFER_THRESHOLD - * \note reserve buffers for clone. 1 or 2 should be enough. - */ -#define CLONE_BUFFERS_THRESHOLD 2 - -/** - * \def MAX_SPARE_BUFFERS - * \note spare buffers are used for lower level flash operations, - * 5 should be enough. - */ -#define MAX_SPARE_BUFFERS 5 - - -/** - * \def MAX_DIRTY_PAGES_IN_A_BLOCK - * \note this value should be between '2' and the lesser of - * 'max pages per block' and (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1). - * - * the smaller the value the frequently the buffer will be flushed. - */ -#define MAX_DIRTY_PAGES_IN_A_BLOCK 32 - -/** - * \def MAX_DIRTY_BUF_GROUPS - */ -#define MAX_DIRTY_BUF_GROUPS 3 - -/** - * \def CONFIG_ENABLE_UFFS_DEBUG_MSG - * \note Enable debug message output. You must call uffs_InitDebugMessageOutput() - * to initialize debug apart from enable debug feature. - */ -#define CONFIG_ENABLE_UFFS_DEBUG_MSG - -/** - * \def CONFIG_USE_GLOBAL_FS_LOCK - * \note use global lock instead of per-device lock. - * this is required if you use fd APIs in multi-thread environment. - */ -#define CONFIG_USE_GLOBAL_FS_LOCK - - -/** - * \def CONFIG_USE_PER_DEVICE_LOCK - * \note use per-device lock. - * this is required if you use fs APIs in multi-thread environment. - */ -//#define CONFIG_USE_PER_DEVICE_LOCK - - - -/** - * \def CONFIG_USE_STATIC_MEMORY_ALLOCATOR - * \note uffs will use static memory allocator if this is defined. - * to use static memory allocator, you need to provide memory - * buffer when creating uffs_Device. - * - * use UFFS_STATIC_BUFF_SIZE() to calculate memory buffer size. - */ -#define CONFIG_USE_STATIC_MEMORY_ALLOCATOR 0 - -/** - * \def CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR - * \note using system platform's 'malloc' and 'free'. - */ -#define CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR 1 - - - -/** - * \def CONFIG_FLUSH_BUF_AFTER_WRITE - * \note UFFS will write all data directly into flash in - * each 'write' call if you enable this option. - * (which means lesser data lost when power failure but - * poorer writing performance). - * It's not recommended to open this define for normal applications. - */ -#define CONFIG_FLUSH_BUF_AFTER_WRITE - - -/** - * \def CONFIG_UFFS_AUTO_LAYOUT_MTD_COMP - * \note Use Linux MTD compatiable spare placement for UFFS_LAYOUT_AUTO, - * only valid for page data size 512 or 2048. - */ -//#define CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME - - -/** - * \def MAX_OBJECT_HANDLE - * maximum number of object handle - */ -#define MAX_OBJECT_HANDLE 50 -#define FD_SIGNATURE_SHIFT 6 - - -/** - * \def MAX_DIR_HANDLE - * maximum number of uffs_DIR - */ -#define MAX_DIR_HANDLE 10 - -/** - * \def MINIMUN_ERASED_BLOCK - * UFFS will not allow appending or creating new files when the free/erased block - * is lower then MINIMUN_ERASED_BLOCK. - */ -#define MINIMUN_ERASED_BLOCK 2 - -/** - * \def CONFIG_CHANGE_MODIFY_TIME - * \note If defined, closing a file which is opened for writing/appending will - * update the file's modify time as well. Disable this feature will save a - * lot of writing activities if you frequently open files for write and close it. - */ -//#define CONFIG_CHANGE_MODIFY_TIME - - -/** - * \def CONFIG_ENABLE_BAD_BLOCK_VERIFY - * \note allow erase and verify block marked as 'bad' when format UFFS partition. - * it's not recommended for most NAND flash. - */ -#define CONFIG_ENABLE_BAD_BLOCK_VERIFY - -/** - * \def CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD - * \note erase block again before mark bad block - */ -//#define CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD - -/** - * \def CONFIG_PAGE_WRITE_VERIFY - * \note verify page data after write, for extra safe data storage. - */ -#define CONFIG_PAGE_WRITE_VERIFY - -/** - * \def CONFIG_BAD_BLOCK_POLICY_STRICT - * \note If this is enabled, UFFS will report the block as 'bad' if any bit-flips found; - * otherwise, UFFS report bad block only when ECC failed or reported - * by low level flash driver. - * - * \note Enable this will ensure your data always be stored on completely good blocks. - */ -#define CONFIG_BAD_BLOCK_POLICY_STRICT - - -/** - * \def CONFIG_ENABLE_PAGE_DATA_CRC - * \note If this is enabled, UFFS save page data CRC16 sum in mini header, - * it provides extra protection for data integrity. - */ -#define CONFIG_ENABLE_PAGE_DATA_CRC - - -/** micros for calculating buffer sizes */ - -/** - * \def UFFS_BLOCK_INFO_BUFFER_SIZE - * \brief calculate memory bytes for block info caches - */ -#define UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) \ - ( \ - ( \ - sizeof(uffs_BlockInfo) + \ - sizeof(uffs_PageSpare) * n_pages_per_block \ - ) * MAX_CACHED_BLOCK_INFO \ - ) - -/** - * \def UFFS_PAGE_BUFFER_SIZE - * \brief calculate memory bytes for page buffers - */ -#define UFFS_PAGE_BUFFER_SIZE(n_page_size) \ - ( \ - ( \ - sizeof(uffs_Buf) + n_page_size \ - ) * MAX_PAGE_BUFFERS \ - ) - -/** - * \def UFFS_TREE_BUFFER_SIZE - * \brief calculate memory bytes for tree nodes - */ -#define UFFS_TREE_BUFFER_SIZE(n_blocks) (sizeof(TreeNode) * n_blocks) - - -#define UFFS_SPARE_BUFFER_SIZE (MAX_SPARE_BUFFERS * UFFS_MAX_SPARE_SIZE) - - -/** - * \def UFFS_STATIC_BUFF_SIZE - * \brief calculate total memory usage of uffs system - */ -#define UFFS_STATIC_BUFF_SIZE(n_pages_per_block, n_page_size, n_blocks) \ - ( \ - UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) + \ - UFFS_PAGE_BUFFER_SIZE(n_page_size) + \ - UFFS_TREE_BUFFER_SIZE(n_blocks) + \ - UFFS_SPARE_BUFFER_SIZE \ - ) - - - -/* config check */ -#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD) < 3 -#error "MAX_PAGE_BUFFERS is too small" -#endif - -#if (MAX_DIRTY_PAGES_IN_A_BLOCK < 2) -#error "MAX_DIRTY_PAGES_IN_A_BLOCK should >= 2" -#endif - -#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1 < MAX_DIRTY_PAGES_IN_A_BLOCK) -#error "MAX_DIRTY_PAGES_IN_A_BLOCK should < (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD)" -#endif - -#if defined(CONFIG_PAGE_WRITE_VERIFY) && (CLONE_BUFFERS_THRESHOLD < 2) -#error "CLONE_BUFFERS_THRESHOLD should >= 2 when CONFIG_PAGE_WRITE_VERIFY is enabled." -#endif - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 1 -#error "Please enable ONLY one memory allocator" -#endif - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR == 0 -#error "Please enable ONE of memory allocators" -#endif - -#if defined(CONFIG_USE_GLOBAL_FS_LOCK) && defined(CONFIG_USE_PER_DEVICE_LOCK) -#error "enable either CONFIG_USE_GLOBAL_FS_LOCK or CONFIG_USE_PER_DEVICE_LOCK, not both" -#endif - -#if (MAX_OBJECT_HANDLE > (1 << FD_SIGNATURE_SHIFT)) -#error "Please increase FD_SIGNATURE_SHIFT !" -#endif - -#ifdef WIN32 -# pragma warning(disable : 4996) -# pragma warning(disable : 4244) -# pragma warning(disable : 4214) -# pragma warning(disable : 4127) -# pragma warning(disable : 4389) -# pragma warning(disable : 4100) -#endif - -#endif diff --git a/components/dfs/filesystems/uffs/src/platform/posix/uffs_os.c b/components/dfs/filesystems/uffs/src/platform/posix/uffs_os.c deleted file mode 100644 index 170c457ad4..0000000000 --- a/components/dfs/filesystems/uffs/src/platform/posix/uffs_os.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_os_posix.c - * \brief Emulation on POSIX host. This is just a dumb implementation, does not really create semaphores. - * \author Ricky Zheng - */ - -#include "uffs_config.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" -#include <memory.h> -#include <stdlib.h> -#include <time.h> -#include <stdio.h> -#include <pthread.h> - -#define PFX "os : " - -int uffs_SemCreate(OSSEM *sem) -{ - pthread_mutex_t *mutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t)); - int ret = -1; - - if (mutex) { - ret = pthread_mutex_init(mutex, NULL /* default attr */); - if (ret == 0) { - *sem = (OSSEM *)mutex; - } - else { - free(mutex); - } - } - - return ret; -} - -int uffs_SemWait(OSSEM sem) -{ - return pthread_mutex_lock((pthread_mutex_t *)sem); -} - -int uffs_SemSignal(OSSEM sem) -{ - return pthread_mutex_unlock((pthread_mutex_t *)sem);; -} - -int uffs_SemDelete(OSSEM *sem) -{ - pthread_mutex_t *mutex = (pthread_mutex_t *) (*sem); - int ret = -1; - - if (mutex) { - ret = pthread_mutex_destroy(mutex); - if (ret == 0) { - free(mutex); - *sem = 0; - } - } - return ret; -} - -int uffs_OSGetTaskId(void) -{ - //TODO: ... return current task ID ... - return 0; -} - -unsigned int uffs_GetCurDateTime(void) -{ - // FIXME: return system time, please modify this for your platform ! - // or just return 0 if you don't care about file time. - time_t tvalue; - - tvalue = time(NULL); - - return (unsigned int)tvalue; -} - -#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0 -static void * sys_malloc(struct uffs_DeviceSt *dev, unsigned int size) -{ - dev = dev; - uffs_Perror(UFFS_MSG_NORMAL, "system memory alloc %d bytes", size); - return malloc(size); -} - -static URET sys_free(struct uffs_DeviceSt *dev, void *p) -{ - dev = dev; - free(p); - return U_SUCC; -} - -void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator) -{ - allocator->malloc = sys_malloc; - allocator->free = sys_free; -} -#endif - - -/* debug message output throught 'printf' */ -static void output_dbg_msg(const char *msg); -static struct uffs_DebugMsgOutputSt m_dbg_ops = { - output_dbg_msg, - NULL, -}; - -static void output_dbg_msg(const char *msg) -{ - printf("%s", msg); -} - -void uffs_SetupDebugOutput(void) -{ - uffs_InitDebugMessageOutput(&m_dbg_ops, UFFS_MSG_NOISY); -} diff --git a/components/dfs/filesystems/uffs/src/platform/win32/uffs_config.h b/components/dfs/filesystems/uffs/src/platform/win32/uffs_config.h deleted file mode 100644 index 3f9daa9cd4..0000000000 --- a/components/dfs/filesystems/uffs/src/platform/win32/uffs_config.h +++ /dev/null @@ -1,317 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_config.h - * \brief basic configuration of uffs - * \author Ricky Zheng - */ - -#ifndef _UFFS_CONFIG_H_ -#define _UFFS_CONFIG_H_ - -/** - * \def UFFS_MAX_PAGE_SIZE - * \note maximum page size UFFS support - */ -#define UFFS_MAX_PAGE_SIZE 2048 - -/** - * \def UFFS_MAX_SPARE_SIZE - */ -#define UFFS_MAX_SPARE_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 8) - -/** - * \def UFFS_MAX_ECC_SIZE - */ -#define UFFS_MAX_ECC_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 5) - -/** - * \def MAX_CACHED_BLOCK_INFO - * \note uffs cache the block info for opened directories and files, - * a practical value is 5 ~ MAX_OBJECT_HANDLE - */ -#define MAX_CACHED_BLOCK_INFO 50 - -/** - * \def MAX_PAGE_BUFFERS - * \note the bigger value will bring better read/write performance. - * but few writing performance will be improved when this - * value is become larger than 'max pages per block' - */ -#define MAX_PAGE_BUFFERS 40 - - -/** - * \def CLONE_BUFFER_THRESHOLD - * \note reserve buffers for clone. 1 or 2 should be enough. - */ -#define CLONE_BUFFERS_THRESHOLD 2 - -/** - * \def MAX_SPARE_BUFFERS - * \note spare buffers are used for lower level flash operations, - * 5 should be enough. - */ -#define MAX_SPARE_BUFFERS 5 - - -/** - * \def MAX_DIRTY_PAGES_IN_A_BLOCK - * \note this value should be between '2' and the lesser of - * 'max pages per block' and (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1). - * - * the smaller the value the frequently the buffer will be flushed. - */ -#define MAX_DIRTY_PAGES_IN_A_BLOCK 32 - -/** - * \def CONFIG_ENABLE_UFFS_DEBUG_MSG - * \note Enable debug message output. You must call uffs_InitDebugMessageOutput() - * to initialize debug apart from enable debug feature. - */ -#define CONFIG_ENABLE_UFFS_DEBUG_MSG - -/** - * \def CONFIG_USE_GLOBAL_FS_LOCK - * \note use global lock instead of per-device lock. - * this is required if you use fd APIs in multi-thread environment. - */ -#define CONFIG_USE_GLOBAL_FS_LOCK - - -/** - * \def CONFIG_USE_PER_DEVICE_LOCK - * \note use per-device lock. - * this is required if you use fs APIs in multi-thread environment. - */ -//#define CONFIG_USE_PER_DEVICE_LOCK - - - -/** - * \def CONFIG_USE_STATIC_MEMORY_ALLOCATOR - * \note uffs will use static memory allocator if this is defined. - * to use static memory allocator, you need to provide memory - * buffer when creating uffs_Device. - * - * use UFFS_STATIC_BUFF_SIZE() to calculate memory buffer size. - */ -#define CONFIG_USE_STATIC_MEMORY_ALLOCATOR 0 - -/** - * \def CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR - * \note using system platform's 'malloc' and 'free'. - */ -#define CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR 1 - - - -/** - * \def CONFIG_FLUSH_BUF_AFTER_WRITE - * \note UFFS will write all data directly into flash in - * each 'write' call if you enable this option. - * (which means lesser data lost when power failure but - * poorer writing performance). - * It's not recommended to open this define for normal applications. - */ -//#define CONFIG_FLUSH_BUF_AFTER_WRITE - - -/** - * \def CONFIG_UFFS_AUTO_LAYOUT_MTD_COMP - * \note Use Linux MTD compatiable spare placement for UFFS_LAYOUT_AUTO, - * only valid for page data size 512 or 2048. - */ -//#define CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME - - -/** - * \def MAX_OBJECT_HANDLE - * maximum number of object handle - */ -#define MAX_OBJECT_HANDLE 50 -#define FD_SIGNATURE_SHIFT 6 - - -/** - * \def MAX_DIR_HANDLE - * maximum number of uffs_DIR - */ -#define MAX_DIR_HANDLE 10 - -/** - * \def MINIMUN_ERASED_BLOCK - * UFFS will not allow appending or creating new files when the free/erased block - * is lower then MINIMUN_ERASED_BLOCK. - */ -#define MINIMUN_ERASED_BLOCK 2 - -/** - * \def CONFIG_CHANGE_MODIFY_TIME - * \note If defined, closing a file which is opened for writing/appending will - * update the file's modify time as well. Disable this feature will save a - * lot of writing activities if you frequently open files for write and close it. - */ -//#define CONFIG_CHANGE_MODIFY_TIME - - -/** - * \def CONFIG_ENABLE_BAD_BLOCK_VERIFY - * \note allow erase and verify block marked as 'bad' when format UFFS partition. - * it's not recommended for most NAND flash. - */ -#define CONFIG_ENABLE_BAD_BLOCK_VERIFY - -/** - * \def CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD - * \note erase block again before mark bad block - */ -//#define CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD - -/** - * \def CONFIG_PAGE_WRITE_VERIFY - * \note verify page data after write, for extra safe data storage. - */ -#define CONFIG_PAGE_WRITE_VERIFY - -/** - * \def CONFIG_BAD_BLOCK_POLICY_STRICT - * \note If this is enabled, UFFS will report the block as 'bad' if any bit-flips found; - * otherwise, UFFS report bad block only when ECC failed or reported - * by low level flash driver. - * - * \note Enable this will ensure your data always be stored on completely good blocks. - */ -#define CONFIG_BAD_BLOCK_POLICY_STRICT - - -/** - * \def CONFIG_ENABLE_PAGE_DATA_CRC - * \note If this is enabled, UFFS save page data CRC16 sum in mini header, - * it provides extra protection for data integrity. - */ -//#define CONFIG_ENABLE_PAGE_DATA_CRC - - -/** micros for calculating buffer sizes */ - -/** - * \def UFFS_BLOCK_INFO_BUFFER_SIZE - * \brief calculate memory bytes for block info caches - */ -#define UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) \ - ( \ - ( \ - sizeof(uffs_BlockInfo) + \ - sizeof(uffs_PageSpare) * n_pages_per_block \ - ) * MAX_CACHED_BLOCK_INFO \ - ) - -/** - * \def UFFS_PAGE_BUFFER_SIZE - * \brief calculate memory bytes for page buffers - */ -#define UFFS_PAGE_BUFFER_SIZE(n_page_size) \ - ( \ - ( \ - sizeof(uffs_Buf) + n_page_size \ - ) * MAX_PAGE_BUFFERS \ - ) - -/** - * \def UFFS_TREE_BUFFER_SIZE - * \brief calculate memory bytes for tree nodes - */ -#define UFFS_TREE_BUFFER_SIZE(n_blocks) (sizeof(TreeNode) * n_blocks) - - -#define UFFS_SPARE_BUFFER_SIZE (MAX_SPARE_BUFFERS * UFFS_MAX_SPARE_SIZE) - - -/** - * \def UFFS_STATIC_BUFF_SIZE - * \brief calculate total memory usage of uffs system - */ -#define UFFS_STATIC_BUFF_SIZE(n_pages_per_block, n_page_size, n_blocks) \ - ( \ - UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) + \ - UFFS_PAGE_BUFFER_SIZE(n_page_size) + \ - UFFS_TREE_BUFFER_SIZE(n_blocks) + \ - UFFS_SPARE_BUFFER_SIZE \ - ) - - - -/* config check */ -#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD) < 3 -#error "MAX_PAGE_BUFFERS is too small" -#endif - -#if (MAX_DIRTY_PAGES_IN_A_BLOCK < 2) -#error "MAX_DIRTY_PAGES_IN_A_BLOCK should >= 2" -#endif - -#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1 < MAX_DIRTY_PAGES_IN_A_BLOCK) -#error "MAX_DIRTY_PAGES_IN_A_BLOCK should < (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD)" -#endif - -#if defined(CONFIG_PAGE_WRITE_VERIFY) && (CLONE_BUFFERS_THRESHOLD < 2) -#error "CLONE_BUFFERS_THRESHOLD should >= 2 when CONFIG_PAGE_WRITE_VERIFY is enabled." -#endif - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 1 -#error "Please enable ONLY one memory allocator" -#endif - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR == 0 -#error "Please enable ONE of memory allocators" -#endif - -#if defined(CONFIG_USE_GLOBAL_FS_LOCK) && defined(CONFIG_USE_PER_DEVICE_LOCK) -#error "enable either CONFIG_USE_GLOBAL_FS_LOCK or CONFIG_USE_PER_DEVICE_LOCK, not both" -#endif - -#if (MAX_OBJECT_HANDLE > (1 << FD_SIGNATURE_SHIFT)) -#error "Please increase FD_SIGNATURE_SHIFT !" -#endif - -#ifdef WIN32 -# pragma warning(disable : 4996) -# pragma warning(disable : 4244) -# pragma warning(disable : 4214) -# pragma warning(disable : 4127) -# pragma warning(disable : 4389) -# pragma warning(disable : 4100) -#endif - -#endif diff --git a/components/dfs/filesystems/uffs/src/platform/win32/uffs_os.c b/components/dfs/filesystems/uffs/src/platform/win32/uffs_os.c deleted file mode 100644 index d05c44abb9..0000000000 --- a/components/dfs/filesystems/uffs/src/platform/win32/uffs_os.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_os.c - * \brief Emulation on win32 host - * \author Ricky Zheng - */ - -#include "uffs_config.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" -#include <memory.h> -#include <stdlib.h> -#include <time.h> -#include <stdio.h> -#include <windows.h> - -#define PFX "os : " - -int uffs_SemCreate(OSSEM *sem) -{ - HANDLE mutex = CreateMutex( - NULL, // default security attributes - FALSE, // initially not owned - NULL); // unnamed mutex - - if (mutex == NULL) { - printf("Create mutex failed !\n"); - return -1; - } - else { - *sem = (OSSEM)mutex; - } - - return 0; -} - -int uffs_SemWait(OSSEM sem) -{ - DWORD result; - - result = WaitForSingleObject( - (HANDLE)sem, // handle to mutex - INFINITE); // no time-out interval - - return result == WAIT_ABANDONED ? -1 : 0; -} - -int uffs_SemSignal(OSSEM sem) -{ - return ReleaseMutex((HANDLE)sem) ? 0 : -1; -} - -int uffs_SemDelete(OSSEM *sem) -{ - if (CloseHandle((HANDLE)(*sem))) { - *sem = 0; - return 0; - } - else - return -1; -} - -int uffs_OSGetTaskId(void) -{ - return 0; -} - -unsigned int uffs_GetCurDateTime(void) -{ - // FIXME: return system time, please modify this for your platform ! - // or just return 0 if you don't care about file time. - time_t tvalue; - - tvalue = time(NULL); - - return (unsigned int)tvalue; -} - -#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0 -static void * sys_malloc(struct uffs_DeviceSt *dev, unsigned int size) -{ - dev = dev; - uffs_Perror(UFFS_MSG_NORMAL, "system memory alloc %d bytes", size); - return malloc(size); -} - -static URET sys_free(struct uffs_DeviceSt *dev, void *p) -{ - dev = dev; - free(p); - return U_SUCC; -} - -void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator) -{ - allocator->malloc = sys_malloc; - allocator->free = sys_free; -} -#endif - - -/* debug message output throught 'printf' */ -static void output_dbg_msg(const char *msg); -static struct uffs_DebugMsgOutputSt m_dbg_ops = { - output_dbg_msg, - NULL, -}; - -static void output_dbg_msg(const char *msg) -{ - printf("%s", msg); -} - -void uffs_SetupDebugOutput(void) -{ - uffs_InitDebugMessageOutput(&m_dbg_ops, UFFS_MSG_NOISY); -} diff --git a/components/dfs/filesystems/uffs/src/uffs/CMakeLists.txt b/components/dfs/filesystems/uffs/src/uffs/CMakeLists.txt deleted file mode 100644 index 24b726b8cb..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/CMakeLists.txt +++ /dev/null @@ -1,59 +0,0 @@ -SET (libuffs_SRCS - uffs_badblock.c - uffs_blockinfo.c - uffs_buf.c - uffs_debug.c - uffs_device.c - uffs_ecc.c - uffs_fd.c - uffs_fs.c - uffs_init.c - uffs_mem.c - uffs_pool.c - uffs_public.c - uffs_tree.c - uffs_utils.c - uffs_mtb.c - uffs_find.c - uffs_flash.c - uffs_version.c - uffs_crc.c - ) - -SET (HDR ${uffs_SOURCE_DIR}/src/inc/uffs) - -SET (libuffs_HEADS - ${HDR}/uffs.h - ${HDR}/uffs_badblock.h - ${HDR}/uffs_blockinfo.h - ${HDR}/uffs_buf.h - ${HDR}/uffs_core.h - ${HDR}/uffs_device.h - ${HDR}/uffs_ecc.h - ${HDR}/uffs_fd.h - ${HDR}/uffs_fs.h - ${HDR}/uffs_mem.h - ${HDR}/uffs_os.h - ${HDR}/uffs_pool.h - ${HDR}/uffs_public.h - ${HDR}/uffs_tree.h - ${HDR}/uffs_types.h - ${HDR}/uffs_utils.h - ${HDR}/uffs_mtb.h - ${HDR}/uffs_find.h - ${HDR}/uffs_flash.h - ${HDR}/uffs_version.h - ${HDR}/uffs_crc.h - ) - -IF (UNIX) -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/posix) -ENDIF() - -IF (WIN32) -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/win32) -ENDIF() - -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc) - -ADD_LIBRARY( uffs STATIC ${libuffs_SRCS} ${libuffs_HEADS} ) diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_badblock.c b/components/dfs/filesystems/uffs/src/uffs/uffs_badblock.c deleted file mode 100644 index 6145b9e547..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_badblock.c +++ /dev/null @@ -1,249 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_badblock.c - * \brief bad block checking and recovering - * \author Ricky Zheng, created in 13th Jun, 2005 - */ -#include "uffs_config.h" -#include "uffs/uffs_fs.h" -#include "uffs/uffs_ecc.h" -#include "uffs/uffs_badblock.h" -#include <string.h> - -#define PFX "bbl : " - -void uffs_BadBlockInit(uffs_Device *dev) -{ - dev->bad.block = UFFS_INVALID_BLOCK; -} - - -/** - * \brief process bad block: erase bad block, mark it as 'bad' - * and put the node to bad block list. - * \param[in] dev uffs device - * \param[in] node bad block tree node - * (before the block turn 'bad', it must belong to something ...) - */ -void uffs_BadBlockProcess(uffs_Device *dev, TreeNode *node) -{ - if (HAVE_BADBLOCK(dev)) { - // mark the bad block - uffs_FlashMarkBadBlock(dev, dev->bad.block); - - // and put it into bad block list - if (node != NULL) - uffs_TreeInsertToBadBlockList(dev, node); - - //clear bad block mark. - dev->bad.block = UFFS_INVALID_BLOCK; - - } -} - -/** - * \brief process bad block and put the node in 'suspend' list. - * \param[in] dev uffs device - * \param[in] node bad block tree node - */ -void uffs_BadBlockProcessSuspend(uffs_Device *dev, TreeNode *node) -{ - if (HAVE_BADBLOCK(dev)) { - // mark the bad block - uffs_FlashMarkBadBlock(dev, dev->bad.block); - - // and put it into bad block list - if (node != NULL) - uffs_TreeSuspendAdd(dev, node); - - //clear bad block mark. - dev->bad.block = UFFS_INVALID_BLOCK; - } -} - -/** - * \brief recover bad block - * \param[in] dev uffs device - */ -void uffs_BadBlockRecover(uffs_Device *dev) -{ - TreeNode *good, *bad; - uffs_Buf *buf; - u16 i; - u16 page; - uffs_BlockInfo *bc = NULL; - uffs_Tags *tag; - uffs_Tags newTag; - UBOOL succRecov; - UBOOL goodBlockIsDirty = U_FALSE; - int ret; - int region; - u8 type; - - if (dev->bad.block == UFFS_INVALID_BLOCK) - return; - - // pick up an erased good block - good = uffs_TreeGetErasedNode(dev); - if (good == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "no free block to replace bad block!"); - return; - } - - //recover block - bc = uffs_BlockInfoGet(dev, dev->bad.block); - - if (bc == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't get bad block info"); - return; - } - - succRecov = U_TRUE; - for (i = 0; i < dev->attr->pages_per_block; i++) { - page = uffs_FindPageInBlockWithPageId(dev, bc, i); - if (page == UFFS_INVALID_PAGE) { - break; //end of last valid page, normal break - } - page = uffs_FindBestPageInBlock(dev, bc, page); - if (page == UFFS_INVALID_PAGE) { - // got an invalid page ? it's bad block anyway ... - uffs_Perror(UFFS_MSG_SERIOUS, "bad block recover (block %d) not finished", bc->block); - break; - } - tag = GET_TAG(bc, page); - buf = uffs_BufClone(dev, NULL); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "Can't clone a new buf!"); - succRecov = U_FALSE; - break; - } - //NOTE: since this is a bad block, we can't guarantee the data is ECC ok, - // so just load data even ECC is not OK. - ret = uffs_LoadPhyDataToBufEccUnCare(dev, buf, bc->block, page); - if (ret == U_FAIL) { - uffs_Perror(UFFS_MSG_SERIOUS, "I/O error ?"); - uffs_BufFreeClone(dev, buf); - succRecov = U_FALSE; - break; - } - buf->data_len = TAG_DATA_LEN(tag); - if (buf->data_len > dev->com.pg_data_size) { - uffs_Perror(UFFS_MSG_NOISY, "data length over flow!!!"); - buf->data_len = dev->com.pg_data_size; - } - - buf->parent = TAG_PARENT(tag); - buf->serial = TAG_SERIAL(tag); - buf->type = TAG_TYPE(tag); - buf->page_id = TAG_PAGE_ID(tag); - - // new tag copied from old tag, and increase time-stamp. - newTag = *tag; - TAG_BLOCK_TS(&newTag) = uffs_GetNextBlockTimeStamp(TAG_BLOCK_TS(tag)); - - ret = uffs_FlashWritePageCombine(dev, good->u.list.block, i, buf, &newTag); - - goodBlockIsDirty = U_TRUE; - uffs_BufFreeClone(dev, buf); - - if (ret == UFFS_FLASH_IO_ERR) { - uffs_Perror(UFFS_MSG_NORMAL, "I/O error ?"); - succRecov = U_FALSE; - break; - } - } - - - if (succRecov == U_TRUE) { - // successful recover bad block, so need to mark bad block, - // and replace with good one - - region = SEARCH_REGION_DIR|SEARCH_REGION_FILE|SEARCH_REGION_DATA; - bad = uffs_TreeFindNodeByBlock(dev, dev->bad.block, ®ion); - if (bad != NULL) { - switch (region) { - case SEARCH_REGION_DIR: - bad->u.dir.block = good->u.list.block; - type = UFFS_TYPE_DIR; - break; - case SEARCH_REGION_FILE: - bad->u.file.block = good->u.list.block; - type = UFFS_TYPE_FILE; - break; - case SEARCH_REGION_DATA: - bad->u.data.block = good->u.list.block; - type = UFFS_TYPE_DATA; - } - - //from now, the 'bad' is actually good block :))) - uffs_Perror(UFFS_MSG_NOISY, - "new bad block %d found, and replaced by %d, type %d!", - dev->bad.block, good->u.list.block, type); - uffs_BlockInfoExpire(dev, bc, UFFS_ALL_PAGES); - //we reuse the 'good' node as bad block node, and process the bad block. - good->u.list.block = dev->bad.block; - uffs_BadBlockProcess(dev, good); - } - else { - uffs_Perror(UFFS_MSG_SERIOUS, - "can't find the reported bad block(%d) in the tree???", - dev->bad.block); - if (goodBlockIsDirty == U_TRUE) - dev->ops->EraseBlock(dev, good->u.list.block); - uffs_TreeInsertToErasedListTail(dev, good); - } - } - else { - if (goodBlockIsDirty == U_TRUE) - dev->ops->EraseBlock(dev, good->u.list.block); - uffs_TreeInsertToErasedListTail(dev, good); //put back to erased list - } - - uffs_BlockInfoPut(dev, bc); - -} - - -/** put a new block to the bad block waiting list */ -void uffs_BadBlockAdd(uffs_Device *dev, int block) -{ - if (dev->bad.block == block) - return; - - if (dev->bad.block != UFFS_INVALID_BLOCK) - uffs_Perror(UFFS_MSG_SERIOUS, "Can't add more then one bad block !"); - else - dev->bad.block = block; -} - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_blockinfo.c b/components/dfs/filesystems/uffs/src/uffs/uffs_blockinfo.c deleted file mode 100644 index f80bc6113e..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_blockinfo.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_blockinfo.c - * \brief block information cache system manipulations - * \author Ricky Zheng, created 10th May, 2005 - */ - -#include "uffs_config.h" -#include "uffs/uffs_blockinfo.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_os.h" - -#include <string.h> - -#define PFX "bc : " - -#define UFFS_CLONE_BLOCK_INFO_NEXT ((uffs_BlockInfo *)(-2)) - -/** - * \brief before block info cache is enable, - * this function should be called to initialize it - * - * \param[in] dev uffs device - * \param[in] maxCachedBlocks maximum cache buffers to be allocated - * \return result of initialization - * \retval U_SUCC successful - * \retval U_FAIL failed - */ -URET uffs_BlockInfoInitCache(uffs_Device *dev, int maxCachedBlocks) -{ - uffs_BlockInfo * blockInfos = NULL; - uffs_PageSpare * pageSpares = NULL; - void * buf = NULL; - uffs_BlockInfo *work = NULL; - int size, i, j; - - if (dev->bc.head != NULL) { - uffs_Perror(UFFS_MSG_NOISY, - "block info cache has been inited already, " - "now release it first."); - uffs_BlockInfoReleaseCache(dev); - } - - size = ( - sizeof(uffs_BlockInfo) + - sizeof(uffs_PageSpare) * dev->attr->pages_per_block - ) * maxCachedBlocks; - - if (dev->mem.blockinfo_pool_size == 0) { - if (dev->mem.malloc) { - dev->mem.blockinfo_pool_buf = dev->mem.malloc(dev, size); - if (dev->mem.blockinfo_pool_buf) - dev->mem.blockinfo_pool_size = size; - } - } - if (size > dev->mem.blockinfo_pool_size) { - uffs_Perror(UFFS_MSG_DEAD, - "Block cache buffer require %d but only %d available.", - size, dev->mem.blockinfo_pool_size); - return U_FAIL; - } - - uffs_Perror(UFFS_MSG_NOISY, "alloc info cache %d bytes.", size); - - buf = dev->mem.blockinfo_pool_buf; - - memset(buf, 0, size); - - dev->bc.mem_pool = buf; - - size = 0; - blockInfos = (uffs_BlockInfo *)buf; - size += sizeof(uffs_BlockInfo) * maxCachedBlocks; - - pageSpares = (uffs_PageSpare *)((char *)buf + size); - - //initialize block info - work = &(blockInfos[0]); - dev->bc.head = work; - work->ref_count = 0; - work->prev = NULL; - work->next = &(blockInfos[1]); - work->block = UFFS_INVALID_BLOCK; - - for (i = 0; i < maxCachedBlocks - 2; i++) { - work = &(blockInfos[i+1]); - work->prev = &(blockInfos[i]); - work->next = &(blockInfos[i+2]); - work->ref_count = 0; - work->block = UFFS_INVALID_BLOCK; - } - //the last node - work = &(blockInfos[i+1]); - work->prev = &(blockInfos[i]); - work->next = NULL; - work->block = UFFS_INVALID_BLOCK; - work->ref_count = 0; - dev->bc.tail = work; - - //initialize spares - work = dev->bc.head; - for (i = 0; i < maxCachedBlocks; i++) { - work->spares = &(pageSpares[i*dev->attr->pages_per_block]); - for (j = 0; j < dev->attr->pages_per_block; j++) { - work->spares[j].expired = 1; - } - work->expired_count = dev->attr->pages_per_block; - work = work->next; - } - return U_SUCC; -} - -/** - * \brief release all allocated memory of block info cache, - * this function should be called when unmount file system - * \param[in] dev uffs device - */ -URET uffs_BlockInfoReleaseCache(uffs_Device *dev) -{ - uffs_BlockInfo *work; - - if (dev->bc.head) { - for (work = dev->bc.head; work != NULL; work = work->next) { - if (work->ref_count != 0) { - uffs_Perror(UFFS_MSG_SERIOUS, - "There have refed block info cache, release cache fail."); - return U_FAIL; - } - } - if (dev->mem.free) { - dev->mem.free(dev, dev->bc.mem_pool); - dev->mem.blockinfo_pool_size = 0; - } - } - - dev->bc.head = dev->bc.tail = NULL; - dev->bc.mem_pool = NULL; - - return U_SUCC; -} - -static void _BreakBcFromList(uffs_Device *dev, uffs_BlockInfo *bc) -{ - if (bc->prev) - bc->prev->next = bc->next; - - if (bc->next) - bc->next->prev = bc->prev; - - if (dev->bc.head == bc) - dev->bc.head = bc->next; - - if (dev->bc.tail == bc) - dev->bc.tail = bc->prev; -} - -static void _InsertToBcListTail(uffs_Device *dev, uffs_BlockInfo *bc) -{ - bc->next = NULL; - bc->prev = dev->bc.tail; - bc->prev->next = bc; - dev->bc.tail = bc; -} - -static void _MoveBcToTail(uffs_Device *dev, uffs_BlockInfo *bc) -{ - _BreakBcFromList(dev, bc); - _InsertToBcListTail(dev, bc); -} - - -/** - * \brief load page spare data to given block info structure - * with given page number - * \param[in] dev uffs device - * \param[in] work given block info to be filled with - * \param[in] page given page number to be read from, - * if #UFFS_ALL_PAGES is presented, it will read - * all pages, otherwise it will read only one given page. - * \return load result - * \retval U_SUCC successful - * \retval U_FAIL fail to load - * \note work->block must be set before load block info - */ -URET uffs_BlockInfoLoad(uffs_Device *dev, uffs_BlockInfo *work, int page) -{ - int i, ret; - uffs_PageSpare *spare; - - if (page == UFFS_ALL_PAGES) { - for (i = 0; i < dev->attr->pages_per_block; i++) { - spare = &(work->spares[i]); - if (spare->expired == 0) - continue; - - ret = uffs_FlashReadPageTag(dev, work->block, i, - &(spare->tag)); - if (UFFS_FLASH_HAVE_ERR(ret)) { - uffs_Perror(UFFS_MSG_SERIOUS, - "load block %d page %d spare fail.", - work->block, i); - return U_FAIL; - } - spare->expired = 0; - work->expired_count--; - } - } - else { - if (page < 0 || page >= dev->attr->pages_per_block) { - uffs_Perror(UFFS_MSG_SERIOUS, "page out of range !"); - return U_FAIL; - } - spare = &(work->spares[page]); - if (spare->expired != 0) { - ret = uffs_FlashReadPageTag(dev, work->block, page, - &(spare->tag)); - if (UFFS_FLASH_HAVE_ERR(ret)) { - uffs_Perror(UFFS_MSG_SERIOUS, - "load block %d page %d spare fail.", - work->block, page); - return U_FAIL; - } - spare->expired = 0; - work->expired_count--; - } - } - return U_SUCC; -} - - -/** - * \brief find a block cache with given block number - * \param[in] dev uffs device - * \param[in] block block number - * \return found block cache - * \retval NULL cache not found - * \retval non-NULL found cache pointer - */ -uffs_BlockInfo * uffs_BlockInfoFindInCache(uffs_Device *dev, int block) -{ - uffs_BlockInfo *work; - - //search cached block - for (work = dev->bc.head; work != NULL; work = work->next) { - if (work->block == block) { - work->ref_count++; - return work; - } - } - return NULL; -} - - -/** - * \brief Find a cached block in cache pool, - * if the cached block exist then return the pointer, - * if the block does not cached already, find a non-used cache. - * if all of cached are used out, return NULL. - * \param[in] dev uffs device - * \param[in] block block number to be found - * \return found block cache buffer - * \retval NULL caches used out - * \retval non-NULL buffer pointer of given block - */ -uffs_BlockInfo * uffs_BlockInfoGet(uffs_Device *dev, int block) -{ - uffs_BlockInfo *work; - int i; - - //search cached block - if ((work = uffs_BlockInfoFindInCache(dev, block)) != NULL) { - _MoveBcToTail(dev, work); - return work; - } - - //can't find block from cache, need to find a free(unlocked) cache - for (work = dev->bc.head; work != NULL; work = work->next) { - if(work->ref_count == 0) break; - } - if (work == NULL) { - //caches used out ! - uffs_Perror(UFFS_MSG_SERIOUS, "insufficient block info cache"); - return NULL; - } - - work->block = block; - work->expired_count = dev->attr->pages_per_block; - for (i = 0; i < dev->attr->pages_per_block; i++) { - work->spares[i].expired = 1; - - // TODO: init tag - } - - work->ref_count = 1; - - _MoveBcToTail(dev, work); - - return work; -} - -/** - * \brief put block info buffer back to pool, - * should be called with #uffs_BlockInfoGet in pairs. - * \param[in] dev uffs device - * \param[in] p pointer of block info buffer - */ -void uffs_BlockInfoPut(uffs_Device *dev, uffs_BlockInfo *p) -{ - dev = dev; - if (p) - { - if (p->ref_count == 0) { - uffs_Perror(UFFS_MSG_SERIOUS, - "Put an unused block info cache back ?"); - } - else { - p->ref_count--; - } - } -} - - -/** - * \brief make the given pages expired in given block info buffer - * \param[in] dev uffs device - * \param[in] p pointer of block info buffer - * \param[in] page given page number. - * if #UFFS_ALL_PAGES presented, all pages in the block should be made expired. - */ -void uffs_BlockInfoExpire(uffs_Device *dev, uffs_BlockInfo *p, int page) -{ - int i; - uffs_PageSpare *spare; - - if (page == UFFS_ALL_PAGES) { - for (i = 0; i < dev->attr->pages_per_block; i++) { - spare = &(p->spares[i]); - if (spare->expired == 0) { - spare->expired = 1; - p->expired_count++; - } - } - } - else { - if (page >= 0 && page < dev->attr->pages_per_block) { - spare = &(p->spares[page]); - if (spare->expired == 0) { - spare->expired = 1; - p->expired_count++; - } - } - } -} - -/** - * Is all blcok info cache free (not referenced) ? - */ -UBOOL uffs_BlockInfoIsAllFree(uffs_Device *dev) -{ - uffs_BlockInfo *work; - - work = dev->bc.head; - while (work) { - if (work->ref_count != 0) - return U_FALSE; - work = work->next; - } - - return U_TRUE; -} - -void uffs_BlockInfoExpireAll(uffs_Device *dev) -{ - uffs_BlockInfo *bc; - - bc = dev->bc.head; - while (bc) { - uffs_BlockInfoExpire(dev, bc, UFFS_ALL_PAGES); - bc = bc->next; - } - return; -} diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_buf.c b/components/dfs/filesystems/uffs/src/uffs/uffs_buf.c deleted file mode 100644 index fd646aa73e..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_buf.c +++ /dev/null @@ -1,1799 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ -/** - * \file uffs_buf.c - * \brief uffs page buffers manipulations - * \author Ricky Zheng - * \note Created in 11th May, 2005 - */ -#include "uffs_config.h" -#include "uffs/uffs_types.h" -#include "uffs/uffs_buf.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_pool.h" -#include "uffs/uffs_ecc.h" -#include "uffs/uffs_badblock.h" -#include <string.h> - -#define PFX "pbuf: " - - -URET _BufFlush(struct uffs_DeviceSt *dev, UBOOL force_block_recover, int slot); - - -/** - * \brief inspect (print) uffs page buffers. - * \param[in] dev uffs device to be inspected. - */ -void uffs_BufInspect(uffs_Device *dev) -{ - struct uffs_PageBufDescSt *pb = &dev->buf; - uffs_Buf *buf; - - uffs_PerrorRaw(UFFS_MSG_NORMAL, - "------------- page buffer inspect ---------" TENDSTR); - uffs_PerrorRaw(UFFS_MSG_NORMAL, "all buffers: " TENDSTR); - for (buf = pb->head; buf; buf = buf->next) { - if (buf->mark != 0) { - uffs_PerrorRaw(UFFS_MSG_NORMAL, - "\tF:%04x S:%04x P:%02d R:%02d D:%03d M:%c EM:%d" TENDSTR, - buf->parent, buf->serial, - buf->page_id, buf->ref_count, - buf->data_len, buf->mark == UFFS_BUF_VALID ? 'V' : 'D', - buf->ext_mark); - } - } - uffs_PerrorRaw(UFFS_MSG_NORMAL, - "--------------------------------------------" TENDSTR); -} - -/** - * \brief initialize page buffers for device - * in UFFS, each device has one buffer pool - * \param[in] dev uffs device - * \param[in] buf_max maximum buffer number, normally use #MAX_PAGE_BUFFERS - * \param[in] dirty_buf_max maximum dirty buffer allowed, - * if the dirty buffer over this number, - * than need to be flush to flash - */ -URET uffs_BufInit(uffs_Device *dev, int buf_max, int dirty_buf_max) -{ - void *pool; - u8 *data; - uffs_Buf *buf; - int size; - int i, slot; - - if (!dev) - return U_FAIL; - - //init device common parameters, which are needed by page buffers - dev->com.pg_size = dev->attr->page_data_size; // we use the whole page. - dev->com.header_size = sizeof(struct uffs_MiniHeaderSt); // mini header - dev->com.pg_data_size = dev->com.pg_size - dev->com.header_size; - - if (dev->buf.pool != NULL) { - uffs_Perror(UFFS_MSG_NORMAL, - "buf.pool is not NULL, buf already inited ?"); - return U_FAIL; - } - - size = (sizeof(uffs_Buf) + dev->com.pg_size) * buf_max; - if (dev->mem.pagebuf_pool_size == 0) { - if (dev->mem.malloc) { - dev->mem.pagebuf_pool_buf = dev->mem.malloc(dev, size); - if (dev->mem.pagebuf_pool_buf) - dev->mem.pagebuf_pool_size = size; - } - } - if (size > dev->mem.pagebuf_pool_size) { - uffs_Perror(UFFS_MSG_DEAD, - "page buffers require %d but only %d available.", - size, dev->mem.pagebuf_pool_size); - return U_FAIL; - } - pool = dev->mem.pagebuf_pool_buf; - - uffs_Perror(UFFS_MSG_NOISY, "alloc %d bytes.", size); - dev->buf.pool = pool; - - for (i = 0; i < buf_max; i++) { - buf = (uffs_Buf *)((u8 *)pool + (sizeof(uffs_Buf) * i)); - memset(buf, 0, sizeof(uffs_Buf)); - data = (u8 *)pool + (sizeof(uffs_Buf) * buf_max) + (dev->com.pg_size * i); - buf->header = data; - buf->data = data + dev->com.header_size; - buf->mark = UFFS_BUF_EMPTY; - memset(buf->header, 0, dev->com.pg_size); - if (i == 0) { - buf->prev = NULL; - dev->buf.head = buf; - } - else { - buf->prev = (uffs_Buf *)((u8 *)buf - sizeof(uffs_Buf)); - } - - if (i == (buf_max - 1)) { - buf->next = NULL; - dev->buf.tail = buf; - } - else { - buf->next = (uffs_Buf *)((u8 *)buf + sizeof(uffs_Buf)); - } - } - - dev->buf.buf_max = buf_max; - dev->buf.dirty_buf_max = (dirty_buf_max > dev->attr->pages_per_block ? - dev->attr->pages_per_block : dirty_buf_max); - - for (slot = 0; slot < dev->cfg.dirty_groups; slot++) { - dev->buf.dirtyGroup[slot].dirty = NULL; - dev->buf.dirtyGroup[slot].count = 0; - } - return U_SUCC; -} - -/** - * \brief flush all buffers - */ -URET uffs_BufFlushAll(struct uffs_DeviceSt *dev) -{ - int slot; - for (slot = 0; slot < dev->cfg.dirty_groups; slot++) { - if(_BufFlush(dev, FALSE, slot) != U_SUCC) { - uffs_Perror(UFFS_MSG_NORMAL, - "fail to flush buffer(slot %d)", slot); - return U_FAIL; - } - } - return U_SUCC; -} - -/** - * \brief release all page buffer, this function should be called - when unmounting a uffs device - * \param[in] dev uffs device - * \note if there are page buffers in used, it may cause fail to release - */ -URET uffs_BufReleaseAll(uffs_Device *dev) -{ - uffs_Buf *p; - - if (!dev) - return U_FAIL; - - //now release all buffer - p = dev->buf.head; - while (p) { - if (p->ref_count != 0) { - uffs_Perror(UFFS_MSG_NORMAL, PFX - "can't release buffers, parent:%d, serial:%d, \ - page_id:%d still in used.\n", - p->parent, p->serial, p->page_id); - return U_FAIL; - } - p = p->next; - } - - if (uffs_BufFlushAll(dev) != U_SUCC) { - uffs_Perror(UFFS_MSG_NORMAL, - "can't release buf, fail to flush buffer"); - return U_FAIL; - } - - if (dev->mem.free) { - dev->mem.free(dev, dev->buf.pool); - dev->mem.pagebuf_pool_size = 0; - } - - dev->buf.pool = NULL; - dev->buf.head = dev->buf.tail = NULL; - - return U_SUCC; -} - - -static void _BreakFromBufList(uffs_Device *dev, uffs_Buf *buf) -{ - if(buf->next) - buf->next->prev = buf->prev; - - if(buf->prev) - buf->prev->next = buf->next; - - if(dev->buf.head == buf) - dev->buf.head = buf->next; - - if(dev->buf.tail == buf) - dev->buf.tail = buf->prev; - -} - -static void _LinkToBufListHead(uffs_Device *dev, uffs_Buf *buf) -{ - if (buf == dev->buf.head) - return; - - buf->prev = NULL; - buf->next = dev->buf.head; - - if (dev->buf.head) - dev->buf.head->prev = buf; - - if (dev->buf.tail == NULL) - dev->buf.tail = buf; - - dev->buf.head = buf; -} - -static void _LinkToBufListTail(uffs_Device *dev, uffs_Buf *buf) -{ - if (dev->buf.tail == buf) - return; - - buf->prev = dev->buf.tail; - buf->next = NULL; - - if (dev->buf.tail) - dev->buf.tail->next = buf; - - if (dev->buf.head == NULL) - dev->buf.head = buf; - - dev->buf.tail = buf; -} - -//move a node which linked in the list to the head of list -static void _MoveNodeToHead(uffs_Device *dev, uffs_Buf *p) -{ - if (p == dev->buf.head) - return; - - //break from list - _BreakFromBufList(dev, p); - - //link to head - _LinkToBufListHead(dev, p); -} - -// check if the buf is already in dirty list -static UBOOL _IsBufInInDirtyList(uffs_Device *dev, int slot, uffs_Buf *buf) -{ - uffs_Buf *work; - work = dev->buf.dirtyGroup[slot].dirty; - while (work) { - if (work == buf) - return U_TRUE; - work = work->next_dirty; - } - - return U_FALSE; -} - -static void _LinkToDirtyList(uffs_Device *dev, int slot, uffs_Buf *buf) -{ - - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "Try to insert a NULL node into dirty list ?"); - return; - } - - buf->mark = UFFS_BUF_DIRTY; - buf->prev_dirty = NULL; - buf->next_dirty = dev->buf.dirtyGroup[slot].dirty; - - if (dev->buf.dirtyGroup[slot].dirty) - dev->buf.dirtyGroup[slot].dirty->prev_dirty = buf; - - dev->buf.dirtyGroup[slot].dirty = buf; - dev->buf.dirtyGroup[slot].count++; -} - -static int CountFreeBuf(uffs_Device *dev) -{ - int count = 0; - - uffs_Buf *buf = dev->buf.head; - - while (buf) { - - if (buf->ref_count == 0 && - buf->mark != UFFS_BUF_DIRTY) - count++; - - buf = buf->next; - } - - return count; -} - -static uffs_Buf * _FindFreeBufEx(uffs_Device *dev, int clone) -{ - uffs_Buf *buf; - - if (!clone && CountFreeBuf(dev) <= CLONE_BUFFERS_THRESHOLD) - return NULL; - -#if 0 - buf = dev->buf.head; - while (buf) { - - if (buf->ref_count == 0 && - buf->mark != UFFS_BUF_DIRTY) - return buf; - - buf = buf->next; - } -#else - buf = dev->buf.tail; - while (buf) { - - if(buf->ref_count == 0 && - buf->mark != UFFS_BUF_DIRTY) - return buf; - - buf = buf->prev; - } -#endif - - return buf; -} - -static uffs_Buf * _FindFreeBuf(uffs_Device *dev) -{ - return _FindFreeBufEx(dev, 0); -} - - -/** - * load psychical page data into buf and do ecc check - * \param[in] dev uffs device - * \param[in] buf buf to be load in - * \param[in] block psychical block number - * \param[in] page psychical page number - * \return return U_SUCC if no error, - * return U_FAIL if I/O error or ecc check fail - */ -URET uffs_BufLoadPhyData(uffs_Device *dev, uffs_Buf *buf, u32 block, u32 page) -{ - int ret; - - ret = uffs_FlashReadPage(dev, block, page, buf, U_FALSE); - - if (UFFS_FLASH_HAVE_ERR(ret)) { - buf->mark = UFFS_BUF_EMPTY; - return U_FAIL; - } - else { - buf->mark = UFFS_BUF_VALID; - return U_SUCC; - } -} - -/** - * \brief load psychical page data into buf and ignore ECC result - * - * \param[in] dev uffs device - * \param[in] buf buf to be load in - * \param[in] block psychical block number - * \param[in] page psychical page number - * - * \return return U_SUCC if no error, return U_FAIL if I/O error - * \note this function should be only used when doing bad block recover. - */ -URET uffs_LoadPhyDataToBufEccUnCare(uffs_Device *dev, - uffs_Buf *buf, u32 block, u32 page) -{ - int ret; - - ret = uffs_FlashReadPage(dev, block, page, buf, U_TRUE); - - if (ret == UFFS_FLASH_IO_ERR) { - buf->mark = UFFS_BUF_EMPTY; - return U_FAIL; - } - else { - buf->mark = UFFS_BUF_VALID; - return U_SUCC; - } -} - -/** - * find a buffer in the pool - * \param[in] dev uffs device - * \param[in] start buf to search from - * \param[in] parent parent serial num - * \param[in] serial serial num - * \param[in] page_id page_id (if page_id == UFFS_ALL_PAGES then any page would match) - * \return return found buffer, return NULL if buffer not found - */ -uffs_Buf * uffs_BufFindFrom(uffs_Device *dev, uffs_Buf *start, - u16 parent, u16 serial, u16 page_id) -{ - uffs_Buf *p = start; - - while (p) { - if( p->parent == parent && - p->serial == serial && - (page_id == UFFS_ALL_PAGES || p->page_id == page_id) && - p->mark != UFFS_BUF_EMPTY) - { - //they have match one - return p; - } - p = p->next; - } - - return NULL; //buffer not found -} - -/** - * find a buffer in the pool - * \param[in] dev uffs device - * \param[in] parent parent serial num - * \param[in] serial serial num - * \param[in] page_id page_id (if page_id == UFFS_ALL_PAGES then any page would match) - * \return return found buffer, return NULL if buffer not found - */ -uffs_Buf * uffs_BufFind(uffs_Device *dev, - u16 parent, u16 serial, u16 page_id) -{ - uffs_Buf *p = dev->buf.head; - - return uffs_BufFindFrom(dev, p, parent, serial, page_id); -} - - -static uffs_Buf * _FindBufInDirtyList(uffs_Buf *dirty, u16 page_id) -{ - while(dirty) { - if (dirty->page_id == page_id) - return dirty; - dirty = dirty->next_dirty; - } - return NULL; -} - -static URET _BreakFromDirty(uffs_Device *dev, uffs_Buf *dirtyBuf) -{ - int slot = -1; - - if (dirtyBuf->mark != UFFS_BUF_DIRTY) { - uffs_Perror(UFFS_MSG_NORMAL, - "try to break a non-dirty buf from dirty list ?"); - return U_FAIL; - } - - slot = uffs_BufFindGroupSlot(dev, dirtyBuf->parent, dirtyBuf->serial); - if (slot < 0) { - uffs_Perror(UFFS_MSG_NORMAL, "no dirty list exit ?"); - return U_FAIL; - } - - // break from the link - if (dirtyBuf->next_dirty) { - dirtyBuf->next_dirty->prev_dirty = dirtyBuf->prev_dirty; - } - - if (dirtyBuf->prev_dirty) { - dirtyBuf->prev_dirty->next_dirty = dirtyBuf->next_dirty; - } - - // check if it's the link head ... - if (dev->buf.dirtyGroup[slot].dirty == dirtyBuf) { - dev->buf.dirtyGroup[slot].dirty = dirtyBuf->next_dirty; - } - - dirtyBuf->next_dirty = dirtyBuf->prev_dirty = NULL; // clear dirty link - - dev->buf.dirtyGroup[slot].count--; - - return U_SUCC; -} - -static u16 _GetDirOrFileNameSum(uffs_Device *dev, uffs_Buf *buf) -{ - u16 data_sum = 0; //default: 0 - uffs_FileInfo *fi; - - dev = dev; - //FIXME: We use the same schema for both dir and file. - if (buf->type == UFFS_TYPE_FILE || buf->type == UFFS_TYPE_DIR) { - if (buf->page_id == 0) { - fi = (uffs_FileInfo *)(buf->data); - data_sum = uffs_MakeSum16(fi->name, fi->name_len); - } - } - - return data_sum; -} - - -static URET _CheckDirtyList(uffs_Buf *dirty) -{ - u16 parent; - u16 serial; - - if (dirty == NULL) { - return U_SUCC; - } - - parent = dirty->parent; - serial = dirty->serial; - dirty = dirty->next_dirty; - - while (dirty) { - if (parent != dirty->parent || - serial != dirty->serial) { - uffs_Perror(UFFS_MSG_SERIOUS, - "parent or serial in dirty pages buffer are not the same ?"); - return U_FAIL; - } - if (dirty->mark != UFFS_BUF_DIRTY) { - uffs_Perror(UFFS_MSG_SERIOUS, - "non-dirty page buffer in dirty buffer list ?"); - return U_FAIL; - } - dirty = dirty->next_dirty; - } - return U_SUCC; -} - -/** find a page in dirty list, which has minimum page_id */ -uffs_Buf * _FindMinimunPageIdFromDirtyList(uffs_Buf *dirtyList) -{ - uffs_Buf * work = dirtyList; - uffs_Buf * buf = dirtyList; - - if (buf) { - work = work->next_dirty; - while (work) { - if (work->page_id < buf->page_id) - buf = work; - work = work->next_dirty; - } - - uffs_Assert(buf->mark == UFFS_BUF_DIRTY, - "buf (serial = %d, parent = %d, page_id = %d, type = %d) in dirty list but mark is 0x%x ?", - buf->serial, buf->parent, buf->page_id, buf->type, buf->mark); - } - - return buf; -} - - -/** - * \brief flush buffer with block recover - * - * Scenario: - * 1. get a free (erased) block --> newNode <br> - * 2. copy from old block ---> oldNode, or copy from dirty list, <br> - * sorted by page_id, to new block. Skips the invalid pages when copy pages.<br> - * 3. erased old block. set new info to oldNode, set newNode->block = old block,<br> - * and put newNode to erased list.<br> - * \note IT'S IMPORTANT TO KEEP OLD NODE IN THE LIST, - * so you don't need to update the obj->node :-) - */ -static URET uffs_BufFlush_Exist_With_BlockCover( - uffs_Device *dev, - int slot, //!< dirty group slot - TreeNode *node, //!< old data node on tree - uffs_BlockInfo *bc //!< old data block info - ) -{ - u16 i; - u8 type, timeStamp; - u16 page, parent, serial; - uffs_Buf *buf; - TreeNode *newNode; - uffs_BlockInfo *newBc; - uffs_Tags *tag, *oldTag; - int x; - u16 newBlock; - UBOOL succRecover; //U_TRUE: recover successful, erase old block, - //U_FALSE: fail to recover, erase new block - UBOOL flash_op_err; - u16 data_sum = 0xFFFF; - - UBOOL useCloneBuf; - - type = dev->buf.dirtyGroup[slot].dirty->type; - parent = dev->buf.dirtyGroup[slot].dirty->parent; - serial = dev->buf.dirtyGroup[slot].dirty->serial; - -retry: - uffs_BlockInfoLoad(dev, bc, UFFS_ALL_PAGES); - - flash_op_err = UFFS_FLASH_NO_ERR; - succRecover = U_FALSE; - - newNode = uffs_TreeGetErasedNode(dev); - if (newNode == NULL) { - uffs_Perror(UFFS_MSG_NOISY, "no enough erased block!"); - goto ext; - } - newBlock = newNode->u.list.block; - newBc = uffs_BlockInfoGet(dev, newBlock); - if (newBc == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "get block info fail!"); - uffs_InsertToErasedListHead(dev, newNode); //put node back to erased list - //because it doesn't use, so put to head - goto ext; - } - - //uffs_Perror(UFFS_MSG_NOISY, "flush buffer with block cover to %d", newBlock); - -#if 0 - // this assert seems not necessary ... - if (!uffs_Assert(newBc->expired_count == dev->attr->pages_per_block, - "We have block cache for erased block ? expired_count = %d, block = %d\n", - newBc->expired_count, newBc->block)) { - uffs_BlockInfoExpire(dev, newBc, UFFS_ALL_PAGES); - } -#endif - - uffs_BlockInfoLoad(dev, newBc, UFFS_ALL_PAGES); - timeStamp = uffs_GetNextBlockTimeStamp(uffs_GetBlockTimeStamp(dev, bc)); - -// uffs_Perror(UFFS_MSG_NOISY, "Flush buffers with Block Recover, from %d to %d", -// bc->block, newBc->block); - - for (i = 0; i < dev->attr->pages_per_block; i++) { - tag = GET_TAG(newBc, i); - TAG_DIRTY_BIT(tag) = TAG_DIRTY; - TAG_VALID_BIT(tag) = TAG_VALID; - TAG_BLOCK_TS(tag) = timeStamp; - TAG_PARENT(tag) = parent; - TAG_SERIAL(tag) = serial; - TAG_TYPE(tag) = type; - TAG_PAGE_ID(tag) = (u8)(i & 0xFF); // now, page_id = page. - // FIX ME!! if more than 256 pages in a block - - SEAL_TAG(tag); - - buf = _FindBufInDirtyList(dev->buf.dirtyGroup[slot].dirty, i); - if (buf != NULL) { - if (i == 0) - data_sum = _GetDirOrFileNameSum(dev, buf); - - TAG_DATA_LEN(tag) = buf->data_len; - - if (buf->data_len == 0 || (buf->ext_mark & UFFS_BUF_EXT_MARK_TRUNC_TAIL)) { // this only happen when truncating a file - - // when truncating a file, the last dirty buf will be - // set as UFFS_BUF_EXT_MARK_TAIL. so that we don't do page recovery - // for the rest pages in the block. (file is ended at this page) - - if (!uffs_Assert((buf->ext_mark & UFFS_BUF_EXT_MARK_TRUNC_TAIL) != 0, - "buf->data == 0 but not the last page of truncating ? block = %d, page_id = %d", - bc->block, i)) { - - // We can't do more about it for now ... - } - - if (buf->data_len > 0) { - flash_op_err = uffs_FlashWritePageCombine(dev, newBlock, i, buf, tag); - } - else { - // data_len == 0, no I/O needed. - flash_op_err = UFFS_FLASH_NO_ERR; - } - succRecover = U_TRUE; - break; - } - else - flash_op_err = uffs_FlashWritePageCombine(dev, newBlock, i, buf, tag); - - if (flash_op_err != UFFS_FLASH_NO_ERR) { - if (flash_op_err == UFFS_FLASH_BAD_BLK) { - uffs_Perror(UFFS_MSG_NORMAL, - "new bad block %d discovered.", newBlock); - break; - } - else if (flash_op_err == UFFS_FLASH_IO_ERR) { - uffs_Perror(UFFS_MSG_NORMAL, - "writing to block %d page %d, I/O error ?", - (int)newBlock, (int)i); - break; - } - else { - uffs_Perror(UFFS_MSG_SERIOUS, "Unhandled flash op result: %d", flash_op_err); - break; - } - } - } - else { - page = uffs_FindPageInBlockWithPageId(dev, bc, i); - if (page == UFFS_INVALID_PAGE) { - succRecover = U_TRUE; - break; //end of last page, normal break - } - page = uffs_FindBestPageInBlock(dev, bc, page); - - if (!uffs_Assert(page != UFFS_INVALID_PAGE, "got an invalid page ?\n")) - break; - - oldTag = GET_TAG(bc, page); - - // First, try to find existing cached buffer. - // Note: do not call uffs_BufGetEx() as it may trigger buf flush and result in infinite loop - buf = uffs_BufGet(dev, parent, serial, i); - - if (buf == NULL) { // no cached page buffer, use clone buffer. - useCloneBuf = U_TRUE; - buf = uffs_BufClone(dev, NULL); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "Can't clone a new buf!"); - break; - } - x = uffs_BufLoadPhyData(dev, buf, bc->block, page); - if (x == U_FAIL) { - if (HAVE_BADBLOCK(dev) && dev->bad.block == bc->block) { - // the old block is a bad block, we'll process it later. - uffs_Perror(UFFS_MSG_SERIOUS, - "the old block %d is a bad block, \ - but ignore it for now.", - bc->block); - } - else { - uffs_Perror(UFFS_MSG_SERIOUS, "I/O error ?"); - uffs_BufFreeClone(dev, buf); - flash_op_err = UFFS_FLASH_IO_ERR; - break; - } - } - - buf->type = type; - buf->parent = parent; - buf->serial = serial; - buf->page_id = TAG_PAGE_ID(oldTag); - buf->data_len = TAG_DATA_LEN(oldTag); - - } - else { - useCloneBuf = U_FALSE; - - uffs_Assert(buf->page_id == TAG_PAGE_ID(oldTag), "buf->page_id = %d, tag page id: %d", buf->page_id, TAG_PAGE_ID(oldTag)); - uffs_Assert(buf->data_len == TAG_DATA_LEN(oldTag), "buf->data_len = %d, tag data len: %d", buf->data_len, TAG_DATA_LEN(oldTag)); - } - - if (buf->data_len > dev->com.pg_data_size) { - uffs_Perror(UFFS_MSG_NOISY, "data length over flow, truncated !"); - buf->data_len = dev->com.pg_data_size; - } - - if (!uffs_Assert(buf->data_len != 0, "data_len == 0 ? block %d, page %d, serial %d, parent %d", - bc->block, page, buf->serial, buf->parent)) { - // this could be some error on flash ? we can't do more about it for now ... - } - - TAG_DATA_LEN(tag) = buf->data_len; - - if (i == 0) - data_sum = _GetDirOrFileNameSum(dev, buf); - - flash_op_err = uffs_FlashWritePageCombine(dev, newBlock, i, buf, tag); - - if (buf) { - if (useCloneBuf) - uffs_BufFreeClone(dev, buf); - else - uffs_BufPut(dev, buf); - } - - if (flash_op_err == UFFS_FLASH_BAD_BLK) { - uffs_Perror(UFFS_MSG_NORMAL, - "new bad block %d discovered.", newBlock); - break; - } - else if (flash_op_err == UFFS_FLASH_IO_ERR) { - uffs_Perror(UFFS_MSG_NORMAL, "I/O error ?", newBlock); - break; - } - } - } //end of for - - if (i == dev->attr->pages_per_block) - succRecover = U_TRUE; - else { - // expire last page info cache in case the 'tag' is not written. - uffs_BlockInfoExpire(dev, newBc, i); - } - - if (flash_op_err == UFFS_FLASH_BAD_BLK) { - uffs_BlockInfoExpire(dev, newBc, UFFS_ALL_PAGES); - uffs_BlockInfoPut(dev, newBc); - if (newNode->u.list.block == dev->bad.block) { - // the recovered block is a BAD block (buy me a lotto, please :-), we need to - // deal with it immediately (mark it as 'bad' and put into bad block list). - uffs_BadBlockProcess(dev, newNode); - } - - uffs_Perror(UFFS_MSG_NORMAL, "Retry block cover ..."); - - goto retry; // retry on a new erased block ... - } - - if (succRecover == U_TRUE) { - // now it's time to clean the dirty buffers - for (i = 0; i < dev->attr->pages_per_block; i++) { - buf = _FindBufInDirtyList(dev->buf.dirtyGroup[slot].dirty, i); - if (buf) { - if (_BreakFromDirty(dev, buf) == U_SUCC) { - buf->mark = UFFS_BUF_VALID; - buf->ext_mark &= ~UFFS_BUF_EXT_MARK_TRUNC_TAIL; - _MoveNodeToHead(dev, buf); - } - } - } - - // swap the old block node and new block node. - // it's important that we 'swap' the block and keep the node unchanged - // so that allowing someone hold the node pointer unawared. - switch (type) { - case UFFS_TYPE_DIR: - node->u.dir.parent = parent; - node->u.dir.serial = serial; - node->u.dir.block = newBlock; - node->u.dir.checksum = data_sum; - break; - case UFFS_TYPE_FILE: - node->u.file.parent = parent; - node->u.file.serial = serial; - node->u.file.block = newBlock; - node->u.file.checksum = data_sum; - break; - case UFFS_TYPE_DATA: - node->u.data.parent = parent; - node->u.data.serial = serial; - node->u.data.block = newBlock; - break; - default: - uffs_Perror(UFFS_MSG_SERIOUS, "UNKNOW TYPE"); - break; - } - - newNode->u.list.block = bc->block; - - // if the recovered block is a bad block, it's time to process it. - if (HAVE_BADBLOCK(dev) && dev->bad.block == newNode->u.list.block) { - //uffs_Perror(UFFS_MSG_SERIOUS, "Still have bad block ?"); - uffs_BadBlockProcess(dev, newNode); - } - else { - // erase recovered block, put it back to erased block list. - if (uffs_IsThisBlockUsed(dev, bc)) { - uffs_FlashEraseBlock(dev, bc->block); - } - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, newNode); - else - uffs_TreeInsertToErasedListTail(dev, newNode); - } - } - else { - - uffs_BlockInfoExpire(dev, bc, UFFS_ALL_PAGES); // FIXME: this might not be necessary ... - - uffs_FlashEraseBlock(dev, newBlock); - newNode->u.list.block = newBlock; - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, newNode); - else - uffs_TreeInsertToErasedListTail(dev, newNode); - } - - if (dev->buf.dirtyGroup[slot].dirty != NULL || - dev->buf.dirtyGroup[slot].count != 0) { - uffs_Perror(UFFS_MSG_NORMAL, "still have dirty buffer ?"); - } - - uffs_BlockInfoPut(dev, newBc); - -ext: - return (succRecover == U_TRUE ? U_SUCC : U_FAIL); - -} - - - -/** - * \brief flush buffer to a new block which is not registered in tree - * - * Scenario: - * 1. get a new block - * 2. write pages in dirty list to new block, sorted by page_id - * 3. insert new block to tree - */ -static URET _BufFlush_NewBlock(uffs_Device *dev, int slot) -{ - u8 type; - TreeNode *node; - uffs_BlockInfo *bc; - URET ret; - - ret = U_FAIL; - - node = uffs_TreeGetErasedNode(dev); - if (node == NULL) { - uffs_Perror(UFFS_MSG_NOISY, "no erased block!"); - goto ext; - } - bc = uffs_BlockInfoGet(dev, node->u.list.block); - if (bc == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "get block info fail!"); - uffs_InsertToErasedListHead(dev, node); //put node back to erased list - goto ext; - } - - type = dev->buf.dirtyGroup[slot].dirty->type; - - ret = uffs_BufFlush_Exist_With_BlockCover(dev, slot, node, bc); - - if (ret == U_SUCC) - uffs_InsertNodeToTree(dev, type, node); - else { - uffs_FlashEraseBlock(dev, bc->block); - uffs_TreeInsertToErasedListTail(dev, node); - } - - uffs_BlockInfoPut(dev, bc); -ext: - return ret; -} - - -/** - * \brief flush buffer to a block with enough free pages - * - * pages in dirty list must be sorted by page_id to write to flash - */ -static -URET - uffs_BufFlush_Exist_With_Enough_FreePage( - uffs_Device *dev, - int slot, //!< dirty group slot - TreeNode *node, //!< tree node - uffs_BlockInfo *bc //!< block info (Source, also destination) - ) -{ - u16 page; - uffs_Buf *buf; - uffs_Tags *tag; - URET ret = U_FAIL; - int x; - -// uffs_Perror(UFFS_MSG_NOISY, -// "Flush buffers with Enough Free Page to block %d", -// bc->block); - - for (page = 1; // page 0 won't be a free page, so we start from 1. - page < dev->attr->pages_per_block && - dev->buf.dirtyGroup[slot].count > 0; //still has dirty pages? - page++) { - - // locate to the free page (make sure the page is a erased page, so an unclean page won't sneak in) - for (; page < dev->attr->pages_per_block; page++) { - if (uffs_IsPageErased(dev, bc, page)) - break; - } - - if (!uffs_Assert(page < dev->attr->pages_per_block, "no free page? buf flush not finished.")) - break; - - buf = _FindMinimunPageIdFromDirtyList(dev->buf.dirtyGroup[slot].dirty); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "count > 0, but no dirty pages in list ?"); - goto ext; - } - - //write the dirty page (id: buf->page_id) to page (free page) - tag = GET_TAG(bc, page); - TAG_DIRTY_BIT(tag) = TAG_DIRTY; - TAG_VALID_BIT(tag) = TAG_VALID; - TAG_BLOCK_TS(tag) = uffs_GetBlockTimeStamp(dev, bc); - TAG_DATA_LEN(tag) = buf->data_len; - TAG_TYPE(tag) = buf->type; - TAG_PARENT(tag) = buf->parent; - TAG_SERIAL(tag) = buf->serial; - TAG_PAGE_ID(tag) = (u8)(buf->page_id); - - SEAL_TAG(tag); - - x = uffs_FlashWritePageCombine(dev, bc->block, page, buf, tag); - if (x == UFFS_FLASH_IO_ERR) { - uffs_Perror(UFFS_MSG_NORMAL, "I/O error <1>?"); - goto ext; - } - else if (x == UFFS_FLASH_BAD_BLK) { - uffs_Perror(UFFS_MSG_NORMAL, "Bad blcok found, start block cover ..."); - ret = uffs_BufFlush_Exist_With_BlockCover(dev, slot, node, bc); - goto ext; - } - else { - if(_BreakFromDirty(dev, buf) == U_SUCC) { - buf->mark = UFFS_BUF_VALID; - _MoveNodeToHead(dev, buf); - } - } - } //end of for - - if (dev->buf.dirtyGroup[slot].dirty != NULL || - dev->buf.dirtyGroup[slot].count != 0) { - uffs_Perror(UFFS_MSG_NORMAL, "still has dirty buffer ?"); - } - else { - ret = U_SUCC; - } - -ext: - return ret; -} - - -URET _BufFlush(struct uffs_DeviceSt *dev, - UBOOL force_block_recover, int slot) -{ - uffs_Buf *dirty; - TreeNode *node; - uffs_BlockInfo *bc; - u16 n; - URET ret; - u8 type; - u16 parent; - u16 serial; - int block; - - if (dev->buf.dirtyGroup[slot].count == 0) { - return U_SUCC; - } - - dirty = dev->buf.dirtyGroup[slot].dirty; - - if (_CheckDirtyList(dirty) == U_FAIL) - return U_FAIL; - - type = dirty->type; - parent = dirty->parent; - serial = dirty->serial; - - switch (type) { - case UFFS_TYPE_DIR: - node = uffs_TreeFindDirNode(dev, serial); - break; - case UFFS_TYPE_FILE: - node = uffs_TreeFindFileNode(dev, serial); - break; - case UFFS_TYPE_DATA: - node = uffs_TreeFindDataNode(dev, parent, serial); - break; - default: - uffs_Perror(UFFS_MSG_SERIOUS, "unknown type"); - return U_FAIL; - } - - if (node == NULL) { - //not found in the tree, need to generate a new block - ret = _BufFlush_NewBlock(dev, slot); - } - else { - switch (type) { - case UFFS_TYPE_DIR: - block = node->u.dir.block; - break; - case UFFS_TYPE_FILE: - block = node->u.file.block; - break; - case UFFS_TYPE_DATA: - block = node->u.data.block; - break; - default: - uffs_Perror(UFFS_MSG_SERIOUS, "unknown type."); - return U_FAIL; - } - bc = uffs_BlockInfoGet(dev, block); - if(bc == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "get block info fail."); - return U_FAIL; - } - - ret = uffs_BlockInfoLoad(dev, bc, UFFS_ALL_PAGES); - if (ret == U_SUCC) { - - n = uffs_GetFreePagesCount(dev, bc); - - if (n >= dev->buf.dirtyGroup[slot].count && !force_block_recover) { - //The free pages are enough for the dirty pages - ret = uffs_BufFlush_Exist_With_Enough_FreePage(dev, slot, node, bc); - } - else { - ret = uffs_BufFlush_Exist_With_BlockCover(dev, slot, node, bc); - } - } - uffs_BlockInfoPut(dev, bc); - } - - return ret; -} - -static int _FindMostDirtyGroup(struct uffs_DeviceSt *dev) -{ - int i, slot = -1; - int max_count = 0; - - for (i = 0; i < dev->cfg.dirty_groups; i++) { - if (dev->buf.dirtyGroup[i].dirty && - dev->buf.dirtyGroup[i].lock == 0) { - if (dev->buf.dirtyGroup[i].count > max_count) { - max_count = dev->buf.dirtyGroup[i].count; - slot = i; - } - } - } - - return slot; -} - -/** lock dirty group */ -URET uffs_BufLockGroup(struct uffs_DeviceSt *dev, int slot) -{ - URET ret = U_FAIL; - if (slot >= 0 && slot < dev->cfg.dirty_groups) { - dev->buf.dirtyGroup[slot].lock++; - ret = U_SUCC; - } - return ret; -} - -/** unlock dirty group */ -URET uffs_BufUnLockGroup(struct uffs_DeviceSt *dev, int slot) -{ - URET ret = U_FAIL; - - if (slot >= 0 && slot < dev->cfg.dirty_groups) { - if (dev->buf.dirtyGroup[slot].lock > 0) - dev->buf.dirtyGroup[slot].lock--; - else { - uffs_Perror(UFFS_MSG_SERIOUS, "Try to unlock an unlocked group ?"); - } - ret = U_SUCC; - } - return ret; -} - - -/** - * flush buffers to flash. - * this will flush all dirty groups. - * \param[in] dev uffs device - */ -URET uffs_BufFlush(struct uffs_DeviceSt *dev) -{ - int slot; - - slot = uffs_BufFindFreeGroupSlot(dev); - if (slot >= 0) - return U_SUCC; // do nothing if there is free slot - else - return uffs_BufFlushMostDirtyGroup(dev); -} - -/** - * flush most dirty group - * \param[in] dev uffs device - */ -URET uffs_BufFlushMostDirtyGroup(struct uffs_DeviceSt *dev) -{ - int slot; - - slot = _FindMostDirtyGroup(dev); - if (slot >= 0) { - return _BufFlush(dev, U_FALSE, slot); - } - return U_SUCC; -} - -/** - * flush buffers to flash - * this will pick up a most dirty group, - * and flush it if there is no free dirty group slot. - * - * \param[in] dev uffs device - * \param[in] force_block_recover #U_TRUE: force a block recover - * even there are enough free pages - */ -URET uffs_BufFlushEx(struct uffs_DeviceSt *dev, UBOOL force_block_recover) -{ - int slot; - - slot = uffs_BufFindFreeGroupSlot(dev); - if (slot >= 0) { - return U_SUCC; //there is free slot, do nothing. - } - else { - slot = _FindMostDirtyGroup(dev); - return _BufFlush(dev, force_block_recover, slot); - } -} - -/** - * flush buffer group with given parent/serial num. - * - * \param[in] dev uffs device - * \param[in] parent parent num of the group - * \param[in] serial serial num of the group - */ -URET uffs_BufFlushGroup(struct uffs_DeviceSt *dev, u16 parent, u16 serial) -{ - int slot; - - slot = uffs_BufFindGroupSlot(dev, parent, serial); - if (slot >= 0) { - return _BufFlush(dev, U_FALSE, slot); - } - - return U_SUCC; -} - -/** - * flush buffer group with given parent/serial num - * and force_block_recover indicator. - * - * \param[in] dev uffs device - * \param[in] parent parent num of the group - * \param[in] serial serial num of group - * \param[in] force_block_recover indicator - */ -URET uffs_BufFlushGroupEx(struct uffs_DeviceSt *dev, - u16 parent, u16 serial, UBOOL force_block_recover) -{ - int slot; - - slot = uffs_BufFindGroupSlot(dev, parent, serial); - if (slot >= 0) { - return _BufFlush(dev, force_block_recover, slot); - } - - return U_SUCC; -} - - -/** - * flush buffer group/groups which match given parent num. - * - * \param[in] dev uffs device - * \param[in] parent parent num of the group - * \param[in] serial serial num of group - * \param[in] force_block_recover indicator - */ -URET uffs_BufFlushGroupMatchParent(struct uffs_DeviceSt *dev, u16 parent) -{ - int slot; - uffs_Buf *buf; - URET ret = U_SUCC; - - for (slot = 0; slot < dev->cfg.dirty_groups && ret == U_SUCC; slot++) { - if (dev->buf.dirtyGroup[slot].dirty) { - buf = dev->buf.dirtyGroup[slot].dirty; - if (buf->parent == parent) { - ret = _BufFlush(dev, U_FALSE, slot); - } - } - } - - return ret; -} - -/** - * find a free dirty group slot - * - * \param[in] dev uffs device - * \return slot index (0 to MAX_DIRTY_BUF_GROUPS - 1) if found one, - * otherwise return -1. - */ -int uffs_BufFindFreeGroupSlot(struct uffs_DeviceSt *dev) -{ - int i, slot = -1; - - for (i = 0; i < dev->cfg.dirty_groups; i++) { - if (dev->buf.dirtyGroup[i].dirty == NULL) { - slot = i; - break; - } - } - return slot; -} - -/** - * find a dirty group slot with given parent/serial num. - * - * \param[in] dev uffs device - * \param[in] parent parent num of the group - * \param[in] serial serial num of group - * \return slot index (0 to MAX_DIRTY_BUF_GROUPS - 1) if found one, - * otherwise return -1. - */ -int uffs_BufFindGroupSlot(struct uffs_DeviceSt *dev, u16 parent, u16 serial) -{ - uffs_Buf *buf; - int i, slot = -1; - - for (i = 0; i < dev->cfg.dirty_groups; i++) { - if (dev->buf.dirtyGroup[i].dirty) { - buf = dev->buf.dirtyGroup[i].dirty; - if (buf->parent == parent && buf->serial == serial) { - slot = i; - break; - } - } - } - return slot; -} - -/** - * \brief get a page buffer - * \param[in] dev uffs device - * \param[in] parent parent serial num - * \param[in] serial serial num - * \param[in] page_id page_id - * \return return the buffer found in buffer list, if not found, return NULL. - */ -uffs_Buf * uffs_BufGet(struct uffs_DeviceSt *dev, - u16 parent, u16 serial, u16 page_id) -{ - uffs_Buf *p; - - //first, check whether the buffer exist in buf list ? - p = uffs_BufFind(dev, parent, serial, page_id); - - if (p) { - p->ref_count++; - _MoveNodeToHead(dev, p); - } - - return p; -} - -/** - * New generate a buffer - */ -uffs_Buf *uffs_BufNew(struct uffs_DeviceSt *dev, - u8 type, u16 parent, u16 serial, u16 page_id) -{ - uffs_Buf *buf; - - buf = uffs_BufGet(dev, parent, serial, page_id); - if (buf) { - if (buf->ref_count > 1) { - uffs_Perror(UFFS_MSG_SERIOUS, "When create new buf, \ - an exist buffer has ref count %d, possibly bug!", - buf->ref_count); - } - else { - buf->data_len = 0; - } - _MoveNodeToHead(dev, buf); - return buf; - } - - buf = _FindFreeBuf(dev); - if (buf == NULL) { - uffs_BufFlushMostDirtyGroup(dev); - buf = _FindFreeBuf(dev); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "no free page buf!"); - return NULL; - } - } - - buf->mark = UFFS_BUF_EMPTY; - buf->type = type; - buf->parent = parent; - buf->serial = serial; - buf->page_id = page_id; - buf->data_len = 0; - buf->ref_count++; - memset(buf->data, 0xff, dev->com.pg_data_size); - - _MoveNodeToHead(dev, buf); - - return buf; -} - - - -/** - * get a page buffer - * \param[in] dev uffs device - * \param[in] type dir, file or data ? - * \param[in] node node on the tree - * \param[in] page_id page_id - * \param[in] oflag the open flag of current file/dir object - * \return return the buffer if found in buffer list, if not found in - * buffer list, it will get a free buffer, and load data from flash. - * return NULL if not free buffer. - */ -uffs_Buf *uffs_BufGetEx(struct uffs_DeviceSt *dev, - u8 type, TreeNode *node, u16 page_id, int oflag) -{ - uffs_Buf *buf; - u16 parent, serial, block, page; - uffs_BlockInfo *bc; - - switch (type) { - case UFFS_TYPE_DIR: - parent = node->u.dir.parent; - serial = node->u.dir.serial; - block = node->u.dir.block; - break; - case UFFS_TYPE_FILE: - parent = node->u.file.parent; - serial = node->u.file.serial; - block = node->u.file.block; - break; - case UFFS_TYPE_DATA: - parent = node->u.data.parent; - serial = node->u.data.serial; - block = node->u.data.block; - break; - default: - uffs_Perror(UFFS_MSG_SERIOUS, "unknown type"); - return NULL; - } - - buf = uffs_BufFind(dev, parent, serial, page_id); - if (buf) { - buf->ref_count++; - return buf; - } - - buf = _FindFreeBuf(dev); - if (buf == NULL) { - uffs_BufFlushMostDirtyGroup(dev); - buf = _FindFreeBuf(dev); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "no free page buf!"); - return NULL; - } - - /* Note: if uffs_BufFlushMostDirtyGroup() flush the same block as we'll write to, - * the block will be changed to a new one! (and the content of 'node' is changed). - * So here we need to update block number from the new 'node'. - */ - switch (type) { - case UFFS_TYPE_DIR: - block = node->u.dir.block; - break; - case UFFS_TYPE_FILE: - block = node->u.file.block; - break; - case UFFS_TYPE_DATA: - block = node->u.data.block; - break; - default: - uffs_Perror(UFFS_MSG_SERIOUS, "unknown type"); - return NULL; - } - } - - bc = uffs_BlockInfoGet(dev, block); - if (bc == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "Can't get block info!"); - return NULL; - } - - page = uffs_FindPageInBlockWithPageId(dev, bc, page_id); - if (page == UFFS_INVALID_PAGE) { - uffs_BlockInfoPut(dev, bc); - uffs_Perror(UFFS_MSG_SERIOUS, "can't find right page ? block %d page_id %d", bc->block, page_id); - return NULL; - } - page = uffs_FindBestPageInBlock(dev, bc, page); - if (!uffs_Assert(page != UFFS_INVALID_PAGE, "got an invalid page?\n")) - return NULL; - - uffs_BlockInfoPut(dev, bc); - - buf->mark = UFFS_BUF_EMPTY; - buf->type = type; - buf->parent = parent; - buf->serial = serial; - buf->page_id = page_id; - - if (UFFS_FLASH_HAVE_ERR(uffs_FlashReadPage(dev, block, page, buf, oflag & UO_NOECC ? U_TRUE : U_FALSE))) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't load page from flash !"); - return NULL; - } - - buf->data_len = TAG_DATA_LEN(GET_TAG(bc, page)); - buf->mark = UFFS_BUF_VALID; - buf->ref_count++; - - _MoveNodeToHead(dev, buf); - - return buf; - -} - -/** - * \brief Put back a page buffer, make reference count decrease by one - * \param[in] dev uffs device - * \param[in] buf buffer to be put back - */ -URET uffs_BufPut(uffs_Device *dev, uffs_Buf *buf) -{ - URET ret = U_FAIL; - - dev = dev; - if (buf == NULL) { - uffs_Perror(UFFS_MSG_NORMAL, "Can't put an NULL buffer!"); - } - else if (buf->ref_count == 0) { - uffs_Perror(UFFS_MSG_NORMAL, "Putting an unused page buffer ? "); - } - else if (buf->ref_count == CLONE_BUF_MARK) { - uffs_Perror(UFFS_MSG_NORMAL, "Putting an cloned page buffer ? "); - ret = uffs_BufFreeClone(dev, buf); - } - else { - buf->ref_count--; - ret = U_SUCC; - } - - return ret; -} - - -/** - * \brief clone from an exist buffer. - allocate memory for new buffer, and copy data from original buffer if - original buffer is not NULL. - * \param[in] dev uffs device - * \param[in] buf page buffer to be clone from. - * if NULL presented here, data copy will not be processed - * \return return the cloned page buffer, all data copied from source - * \note the cloned buffer is not linked in page buffer list in uffs device, - * so you should use #uffs_BufFreeClone instead of #uffs_BufPut - * when you put back or release buffer - */ -uffs_Buf * uffs_BufClone(uffs_Device *dev, uffs_Buf *buf) -{ - uffs_Buf *p; - - p = _FindFreeBufEx(dev, 1); - if (p == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "no enough free pages for clone! " \ - "Please increase Clone Buffer Count threshold."); - } - else { - _BreakFromBufList(dev, p); - - if (buf) { - p->parent = buf->parent; - p->type = buf->type; - p->serial = buf->serial; - p->page_id = buf->page_id; - - p->data_len = buf->data_len; - //athough the valid data length is .data_len, - //but we still need copy the whole buffer, include header - memcpy(p->header, buf->header, dev->com.pg_size); - } - p->next = p->prev = NULL; // the cloned one is not linked to device buffer - p->next_dirty = p->prev_dirty = NULL; - p->ref_count = CLONE_BUF_MARK; // CLONE_BUF_MARK indicates that - // this is an cloned buffer - } - - return p; -} - -/** - * \brief release cloned buffer - * \param[in] dev uffs device - * \param[in] buf cloned buffer - */ -URET uffs_BufFreeClone(uffs_Device *dev, uffs_Buf *buf) -{ - dev = dev; //make compiler happy - if (!buf) - return U_FAIL; - - if (buf->ref_count != CLONE_BUF_MARK) { - /* a cloned buffer must have a ref_count of CLONE_BUF_MARK */ - uffs_Perror(UFFS_MSG_SERIOUS, - "Try to release a non-cloned page buffer ?"); - return U_FAIL; - } - - buf->ref_count = 0; - buf->mark = UFFS_BUF_EMPTY; - _LinkToBufListTail(dev, buf); - - return U_SUCC; -} - - - -UBOOL uffs_BufIsAllFree(struct uffs_DeviceSt *dev) -{ - uffs_Buf *buf = dev->buf.head; - - while (buf) { - if(buf->ref_count != 0) return U_FALSE; - buf = buf->next; - } - - return U_TRUE; -} - -UBOOL uffs_BufIsAllEmpty(struct uffs_DeviceSt *dev) -{ - uffs_Buf *buf = dev->buf.head; - - while (buf) { - if(buf->mark != UFFS_BUF_EMPTY) return U_FALSE; - buf = buf->next; - } - - return U_TRUE; -} - - -URET uffs_BufSetAllEmpty(struct uffs_DeviceSt *dev) -{ - uffs_Buf *buf = dev->buf.head; - - while (buf) { - buf->mark = UFFS_BUF_EMPTY; - buf = buf->next; - } - return U_SUCC; -} - - -void uffs_BufIncRef(uffs_Buf *buf) -{ - buf->ref_count++; -} - -void uffs_BufDecRef(uffs_Buf *buf) -{ - if (buf->ref_count > 0) - buf->ref_count--; -} - -/** mark buffer as #UFFS_BUF_EMPTY if ref_count == 0, - and discard all data it holds */ -void uffs_BufMarkEmpty(uffs_Device *dev, uffs_Buf *buf) -{ - if (buf->mark != UFFS_BUF_EMPTY) { - if (buf->ref_count == 0) { - if (buf->mark == UFFS_BUF_DIRTY) - _BreakFromDirty(dev, buf); - buf->mark = UFFS_BUF_EMPTY; - } - } -} - -#if 0 -static UBOOL _IsBufInDirtyList(struct uffs_DeviceSt *dev, uffs_Buf *buf) -{ - uffs_Buf *p = dev->buf.dirtyGroup[slot].dirty; - - while (p) { - if(p == buf) return U_TRUE; - p = p->next_dirty; - } - - return U_FALSE; -} -#endif - -URET uffs_BufWrite(struct uffs_DeviceSt *dev, - uffs_Buf *buf, void *data, u32 ofs, u32 len) -{ - int slot; - - if(ofs + len > dev->com.pg_data_size) { - uffs_Perror(UFFS_MSG_SERIOUS, - "data length out of range! %d+%d", ofs, len); - return U_FAIL; - } - - slot = uffs_BufFindGroupSlot(dev, buf->parent, buf->serial); - - if (slot < 0) { - // need to take a free slot - slot = uffs_BufFindFreeGroupSlot(dev); - if (slot < 0) { - // no free slot ? flush buffer - if (uffs_BufFlushMostDirtyGroup(dev) != U_SUCC) - return U_FAIL; - - slot = uffs_BufFindFreeGroupSlot(dev); - if (slot < 0) { - // still no free slot ?? - uffs_Perror(UFFS_MSG_SERIOUS, "no free slot ?"); - return U_FAIL; - } - } - } - - if (data) - memcpy(buf->data + ofs, data, len); - else - memset(buf->data + ofs, 0, len); // if data == NULL, then fill all '\0'. - - if (ofs + len > buf->data_len) - buf->data_len = ofs + len; - - if (_IsBufInInDirtyList(dev, slot, buf) == U_FALSE) { - _LinkToDirtyList(dev, slot, buf); - } - - if (dev->buf.dirtyGroup[slot].count >= dev->buf.dirty_buf_max) { - if (uffs_BufFlushGroup(dev, buf->parent, buf->serial) != U_SUCC) { - return U_FAIL; - } - } - - return U_SUCC; -} - -URET uffs_BufRead(struct uffs_DeviceSt *dev, - uffs_Buf *buf, void *data, u32 ofs, u32 len) -{ - u32 readSize; - u32 pg_data_size = dev->com.pg_data_size; - - readSize = (ofs >= pg_data_size ? - 0 : (ofs + len >= pg_data_size ? pg_data_size - ofs : len) - ); - - if (readSize > 0) - memcpy(data, buf->data + ofs, readSize); - - return U_SUCC; -} - - - - - - - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_crc.c b/components/dfs/filesystems/uffs/src/uffs/uffs_crc.c deleted file mode 100644 index 0ef95bf7f1..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_crc.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ -/** - * \file uffs_crc.c - * \brief simple CRC functions - * \author Ricky Zheng - * \note Created in 23 Nov, 2011 - */ - -#include "uffs/uffs_crc.h" - -/* CRC16 Table */ -static const u16 CRC16_TBL[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -#define CRC16(v, x) v = ((v) >> 8) ^ CRC16_TBL[((v) ^ (x)) & 0x00ff] - -u16 uffs_crc16update(const void *data, int length, u16 crc) -{ - int i; - const u8 *p = (const u8 *)data; - for (i = 0; i < length; i++, p++) { - CRC16(crc, *p); - } - - return crc; -} - -u16 uffs_crc16sum(const void *data, int length) -{ - return uffs_crc16update(data, length, 0xFFFF); -} diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_debug.c b/components/dfs/filesystems/uffs/src/uffs/uffs_debug.c deleted file mode 100644 index 5f6c1558e4..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_debug.c +++ /dev/null @@ -1,188 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_debug.c - * \brief output debug messages - * \author Ricky Zheng, created 10th May, 2005 - */ -#include "uffs_config.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" - -#if !defined(RT_THREAD) -#include <stdio.h> -#include <stdarg.h> -#include <string.h> - -#define MAX_DEBUG_MSG_LINE_LENGTH 128 - -static struct uffs_DebugMsgOutputSt * m_ops = NULL; -static int m_msg_level = UFFS_MSG_NORMAL; - -static void uffs_vprintf(const char *fmt, va_list args) -{ - char line_buf[MAX_DEBUG_MSG_LINE_LENGTH]; - - if (m_ops && m_ops->output) { -#ifdef _COMPILER_CLIB_DO_NOT_HAVE_VSNPRINTF_ - vsprintf(line_buf, fmt, args); -#else - vsnprintf(line_buf, MAX_DEBUG_MSG_LINE_LENGTH, fmt, args); -#endif - m_ops->output(line_buf); - } -} - -/** - * \brief Initialize debug message output functions - */ -URET uffs_InitDebugMessageOutput(struct uffs_DebugMsgOutputSt *ops, int msg_level) -{ - m_ops = ops; - - if (m_ops == NULL || m_ops->output == NULL) { - m_ops = NULL; - return U_FAIL; - } - else if (m_ops->vprintf == NULL) - m_ops->vprintf = uffs_vprintf; - - m_msg_level = msg_level; - - return U_SUCC; -} - -void uffs_DebugSetMessageLevel(int msg_level) -{ - m_msg_level = msg_level; -} -#endif - -#ifdef CONFIG_ENABLE_UFFS_DEBUG_MSG - -/** - * \brief The main debug message output function - */ -#if !defined(RT_THREAD) -void uffs_DebugMessage(int level, const char *prefix, - const char *suffix, const char *errFmt, ...) -{ - va_list arg; - - if (m_ops && level >= m_msg_level) { - if (prefix) - m_ops->output(prefix); - - va_start(arg, errFmt); - m_ops->vprintf(errFmt, arg); - va_end(arg); - - if (suffix) - m_ops->output(suffix); - } -} - -/** - * \brief Called when an assert occurred. - * This method is called when an assert occurred and should stop the - * application from running, as this there is a severe error condition. - * \param[in] file Source filename - * \param[in] line Source line of code - * \param[in] msg Assert message - */ -void uffs_AssertCall(const char *file, int line, const char *msg, ...) -{ - va_list args; - char buf[32]; - - if (m_ops && m_msg_level < UFFS_MSG_NOMSG) { - m_ops->output("ASSERT "); - m_ops->output(file); - sprintf(buf, ":%d - :", line); - m_ops->output(buf); - va_start(args, msg); - m_ops->vprintf(msg, args); - va_end(args); - m_ops->output(TENDSTR); - } -} -#endif - -#ifdef _COMPILER_DO_NOT_SUPPORT_MACRO_VALIST_REPLACE_ -void uffs_Perror(int level, const char *fmt, ...) -{ - va_list args; - if (m_ops && level >= m_msg_level) { - va_start(args, fmt); - m_ops->vprintf(fmt, args); - va_end(args); - m_ops->output(TENDSTR); - } -} - -void uffs_PerrorRaw(int level, const char *fmt, ...) -{ - va_list args; - if (m_ops && level >= m_msg_level) { - va_start(args, fmt); - m_ops->vprintf(fmt, args); - va_end(args); - } -} - -UBOOL uffs_Assert(UBOOL expr, const char *fmt, ...) -{ - va_list args; - if (m_ops && !expr && m_msg_level < UFFS_MSG_NOMSG) { - m_ops->output("ASSERT FAILED: "); - va_start(args, fmt); - m_ops->vprintf(fmt, args); - va_end(args); - m_ops->output(TENDSTR); - } - return expr ? U_TRUE : U_FALSE; -} -#endif - -#else - -void uffs_DebugMessage(int level, const char *prefix, const char *suffix, const char *errFmt, ...) {}; -void uffs_AssertCall(const char *file, int line, const char *msg, ...) {}; - -#ifdef _COMPILER_DO_NOT_SUPPORT_MACRO_VALIST_REPLACE_ -void uffs_Perror(int level, const char *fmt, ...) {} -void uffs_PerrorRaw(int level, const char *fmt, ...) {} -UBOOL uffs_Assert(UBOOL expr, const char *fmt, ...) { return expr ? U_TRUE : U_FALSE; } -#endif - -#endif diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_device.c b/components/dfs/filesystems/uffs/src/uffs/uffs_device.c deleted file mode 100644 index 7b6a14de81..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_device.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_device.c - * \brief uffs device operation - * \author Ricky Zheng, created 10th May, 2005 - */ -#include "uffs_config.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_mtb.h" -#include <string.h> - -#define PFX "dev : " - - -#ifdef CONFIG_USE_PER_DEVICE_LOCK -void uffs_DeviceInitLock(uffs_Device *dev) -{ - uffs_SemCreate(&dev->lock.sem); - dev->lock.task_id = UFFS_TASK_ID_NOT_EXIST; - dev->lock.counter = 0; -} - -void uffs_DeviceReleaseLock(uffs_Device *dev) -{ - uffs_SemDelete(&dev->lock.sem); -} - -void uffs_DeviceLock(uffs_Device *dev) -{ - uffs_SemWait(dev->lock.sem); - - if (dev->lock.counter != 0) { - uffs_Perror(UFFS_MSG_NORMAL, - "Lock device, counter %d NOT zero?!", dev->lock.counter); - } - - dev->lock.counter++; -} - -void uffs_DeviceUnLock(uffs_Device *dev) -{ - dev->lock.counter--; - - if (dev->lock.counter != 0) { - uffs_Perror(UFFS_MSG_NORMAL, - "Unlock device, counter %d NOT zero?!", dev->lock.counter); - } - - uffs_SemSignal(dev->lock.sem); -} - -#else - -/* dummy stubs */ -void uffs_DeviceInitLock(uffs_Device *dev) {} -void uffs_DeviceReleaseLock(uffs_Device *dev) {} -void uffs_DeviceLock(uffs_Device *dev) {} -void uffs_DeviceUnLock(uffs_Device *dev) {} - -#endif diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_ecc.c b/components/dfs/filesystems/uffs/src/uffs/uffs_ecc.c deleted file mode 100644 index 3d10c2d3f0..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_ecc.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_ecc.c - * \brief ecc maker and correct - * \author Ricky Zheng, created in 12th Jun, 2005 - */ -#include "uffs_config.h" -#include "uffs/uffs_fs.h" -#include <string.h> - -#define PFX "ecc : " - -static const u8 bits_tbl[256] = { - 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, - 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8, -}; - -static const u8 line_parity_tbl[16] = { - 0x00, 0x02, 0x08, 0x0a, 0x20, 0x22, 0x28, 0x2a, - 0x80, 0x82, 0x88, 0x8a, 0xa0, 0xa2, 0xa8, 0xaa -}; - -static const u8 line_parity_prime_tbl[16] = { - 0x00, 0x01, 0x04, 0x05, 0x10, 0x11, 0x14, 0x15, - 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55 -}; - -static const u8 column_parity_tbl[256] = { - 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, - 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, - 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, - 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, - 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, - 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, - 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, - 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, - 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, - 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, - 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, - 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, - 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, - 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, - 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, - 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, - 0xa9, 0xfc, 0xf0, 0xa5, 0xcc, 0x99, 0x95, 0xc0, - 0xc0, 0x95, 0x99, 0xcc, 0xa5, 0xf0, 0xfc, 0xa9, - 0x3c, 0x69, 0x65, 0x30, 0x59, 0x0c, 0x00, 0x55, - 0x55, 0x00, 0x0c, 0x59, 0x30, 0x65, 0x69, 0x3c, - 0x30, 0x65, 0x69, 0x3c, 0x55, 0x00, 0x0c, 0x59, - 0x59, 0x0c, 0x00, 0x55, 0x3c, 0x69, 0x65, 0x30, - 0xa5, 0xf0, 0xfc, 0xa9, 0xc0, 0x95, 0x99, 0xcc, - 0xcc, 0x99, 0x95, 0xc0, 0xa9, 0xfc, 0xf0, 0xa5, - 0x0c, 0x59, 0x55, 0x00, 0x69, 0x3c, 0x30, 0x65, - 0x65, 0x30, 0x3c, 0x69, 0x00, 0x55, 0x59, 0x0c, - 0x99, 0xcc, 0xc0, 0x95, 0xfc, 0xa9, 0xa5, 0xf0, - 0xf0, 0xa5, 0xa9, 0xfc, 0x95, 0xc0, 0xcc, 0x99, - 0x95, 0xc0, 0xcc, 0x99, 0xf0, 0xa5, 0xa9, 0xfc, - 0xfc, 0xa9, 0xa5, 0xf0, 0x99, 0xcc, 0xc0, 0x95, - 0x00, 0x55, 0x59, 0x0c, 0x65, 0x30, 0x3c, 0x69, - 0x69, 0x3c, 0x30, 0x65, 0x0c, 0x59, 0x55, 0x00, -}; - -/** - * calculate 3 bytes ECC for 256 bytes data. - * - * \param[in] data input data - * \param[out] ecc output ecc - * \param[in] length of data in bytes - */ -static void uffs_EccMakeChunk256(const void *data, void *ecc, u16 len) -{ - u8 *pecc = (u8 *)ecc; - const u8 *p = (const u8 *)data; - u8 b, col_parity = 0, line_parity = 0, line_parity_prime = 0; - u16 i; - - for (i = 0; i < len; i++) { - b = column_parity_tbl[*p++]; - col_parity ^= b; - if (b & 0x01) { // odd number of bits in the byte - line_parity ^= i; - line_parity_prime ^= ~i; - } - } - - // ECC layout: - // Byte[0] P64 | P64' | P32 | P32' | P16 | P16' | P8 | P8' - // Byte[1] P1024 | P1024' | P512 | P512' | P256 | P256' | P128 | P128' - // Byte[2] P4 | P4' | P2 | P2' | P1 | P1' | 1 | 1 - pecc[0] = ~(line_parity_tbl[line_parity & 0xf] | - line_parity_prime_tbl[line_parity_prime & 0xf]); - pecc[1] = ~(line_parity_tbl[line_parity >> 4] | - line_parity_prime_tbl[line_parity_prime >> 4]); - pecc[2] = (~col_parity) | 0x03; - -} - - -/** - * calculate ECC. (3 bytes ECC per 256 data) - * - * \param[in] data input data - * \param[in] data_len length of data in byte - * \param[out] ecc output ecc - * - * \return length of ECC in byte. (3 bytes ECC per 256 data) - */ -int uffs_EccMake(const void *data, int data_len, void *ecc) -{ - const u8 *p_data = (const u8 *)data; - u8 *p_ecc = (u8 *)ecc; - int len; - - if (data == NULL || ecc == NULL) - return 0; - - while (data_len > 0) { - len = data_len > 256 ? 256 : data_len; - uffs_EccMakeChunk256(p_data, p_ecc, len); - data_len -= len; - p_data += len; - p_ecc += 3; - } - - return p_ecc - (u8 *)ecc; -} - -/** - * perform ECC error correct for 256 bytes data chunk. - * - * \param[in|out] data input data to be corrected - * \param[in] read_ecc 3 bytes ECC read from storage - * \param[in] test_ecc 3 bytes ECC calculated from data - * \param[in] errtop top position of error - * - * \return: 0 -- no error - * -1 -- can not be corrected - * >0 -- how many bits corrected - */ -static int uffs_EccCorrectChunk256(void *data, void *read_ecc, - const void *test_ecc, int errtop) -{ - u8 d0, d1, d2; /* deltas */ - u8 *p = (u8 *)data; - u8 *pread_ecc = (u8 *)read_ecc, *ptest_ecc = (u8 *)test_ecc; - - d0 = pread_ecc[0] ^ ptest_ecc[0]; - d1 = pread_ecc[1] ^ ptest_ecc[1]; - d2 = pread_ecc[2] ^ ptest_ecc[2]; - - if ((d0 | d1 | d2) == 0) - return 0; - - if( ((d0 ^ (d0 >> 1)) & 0x55) == 0x55 && - ((d1 ^ (d1 >> 1)) & 0x55) == 0x55 && - ((d2 ^ (d2 >> 1)) & 0x54) == 0x54) - { - // Single bit (recoverable) error in data - - u8 b; - u8 bit; - - bit = b = 0; - - if(d1 & 0x80) b |= 0x80; - if(d1 & 0x20) b |= 0x40; - if(d1 & 0x08) b |= 0x20; - if(d1 & 0x02) b |= 0x10; - if(d0 & 0x80) b |= 0x08; - if(d0 & 0x20) b |= 0x04; - if(d0 & 0x08) b |= 0x02; - if(d0 & 0x02) b |= 0x01; - - if(d2 & 0x80) bit |= 0x04; - if(d2 & 0x20) bit |= 0x02; - if(d2 & 0x08) bit |= 0x01; - - if (b >= errtop) return -1; - - p[b] ^= (1 << bit); - - return 1; - } - - if ((bits_tbl[d0] + bits_tbl[d1] + bits_tbl[d2]) == 1) { - // error in ecc, no action need - return 1; - } - - // Unrecoverable error - return -1; -} - -/** - * perform ECC error correct - * - * \param[in|out] data input data to be corrected - * \param[in] data_len length of data in byte - * \param[in] read_ecc ECC read from storage - * \param[in] test_ecc ECC calculated from data - * - * \return: 0 -- no error - * -1 -- can not be corrected - * >0 -- how many bits corrected - */ - -int uffs_EccCorrect(void *data, int data_len, - void *read_ecc, const void *test_ecc) -{ - u8 *p_data = (u8 *)data; - u8 *p_read_ecc = (u8 *)read_ecc; - u8 *p_test_ecc = (u8 *)test_ecc; - int total = 0, ret, len; - - if (data == NULL || read_ecc == NULL || test_ecc == NULL) - return -1; - - while (data_len > 0) { - len = (data_len > 256 ? 256 : data_len); - ret = uffs_EccCorrectChunk256(p_data, p_read_ecc, p_test_ecc, len); - if (ret < 0) { - total = ret; - break; - } - else - total += ret; - - p_data += len; - p_read_ecc += 3; - p_test_ecc += 3; - data_len -= len; - } - - return total; - -} - -/** - * generate 12 bit ecc for 8 bytes data. - * (use 0xFF padding if the data length is less then 8 bytes) - * - * \param[in] data input data - * \param[in] data_len length of data in byte - * - * \return 12 bits ECC data (lower 12 bits). - */ -u16 uffs_EccMake8(void *data, int data_len) -{ - u8 *p = (u8 *)data; - u8 b, col_parity = 0, line_parity = 0, line_parity_prime = 0; - u8 i; - u16 ecc = 0; - - - data_len = (data_len > 8 ? 8 : data_len); - - for (i = 0; i < data_len; i++) { - b = column_parity_tbl[*p++]; - col_parity ^= b; - if (b & 0x01) { // odd number of bits in the byte - line_parity ^= i; - line_parity_prime ^= ~i; - } - } - - // ECC layout: - // row: (1) | (1) | P32 | P32' | P16 | P16' | P8 | P8' - // column: P4 | P4' | P2 | P2' | P1 | P1' | (1) | (1) - // 12-bit ecc: P32 | P32' | P16 | P16' | P8 | P8' | P4 | P4' | P2 | P2' | P1 | P1' | - ecc = (~( - line_parity_tbl[line_parity & 0xf] | - line_parity_prime_tbl[line_parity_prime & 0xf] - )) << 6; - ecc |= (((~col_parity) >> 2) & 0x3f); - - return ecc & 0xfff; -} - -/** - * correct 8 bytes data from 12 bits ECC - * - * \param[in|out] data input data - * \param[in] read_ecc ecc read from storage - * \param[in] test_ecc ecc calculated from data - * \param[in] errtop top position of error. - * - * \return: 0 -- no error - * -1 -- can not be corrected - * >0 -- how many bits corrected - */ -int uffs_EccCorrect8(void *data, u16 read_ecc, u16 test_ecc, int errtop) -{ - u8 d0, d1; /* deltas */ - u8 *p = (u8 *)data; - - read_ecc &= 0xfff; - test_ecc &= 0xfff; - - d0 = (read_ecc >> 6) ^ (test_ecc >> 6); - d1 = (read_ecc & 0x3f) ^ (test_ecc & 0x3f); - - if ((d0 | d1) == 0) - return 0; - - if( ((d0 ^ (d0 >> 1)) & 0x15) == 0x15 && - ((d1 ^ (d1 >> 1)) & 0x15) == 0x15) - { - // Single bit (recoverable) error in data - - u8 b; - u8 bit; - - bit = b = 0; - - if(d0 & 0x20) b |= 0x04; - if(d0 & 0x08) b |= 0x02; - if(d0 & 0x02) b |= 0x01; - - if(d1 & 0x20) bit |= 0x04; - if(d1 & 0x08) bit |= 0x02; - if(d1 & 0x02) bit |= 0x01; - - if (b >= (u8)errtop) return -1; - if (bit >= 8) return -1; - - p[b] ^= (1 << bit); - - return 1; - } - - if ((bits_tbl[d0] + bits_tbl[d1]) == 1) { - // error in ecc, no action need - return 1; - } - - // Unrecoverable error - return -1; -} - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_fd.c b/components/dfs/filesystems/uffs/src/uffs/uffs_fd.c deleted file mode 100644 index bbc1bb880d..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_fd.c +++ /dev/null @@ -1,746 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fd.c - * \brief POSIX like, hight level file operations - * \author Ricky Zheng, created 8th Jun, 2005 - */ - -#include <string.h> -#include "uffs_config.h" -#include "uffs/uffs_fs.h" -#include "uffs/uffs_fd.h" -#include "uffs/uffs_utils.h" -#include "uffs/uffs_version.h" -#include "uffs/uffs_mtb.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_find.h" - -#define PFX "fd : " - -/** - * \brief POSIX DIR - */ -struct uffs_dirSt { - struct uffs_ObjectSt *obj; /* dir object */ - struct uffs_FindInfoSt f; /* find info */ - struct uffs_ObjectInfoSt info; /* object info */ - struct uffs_dirent dirent; /* dir entry */ -}; - - -#define FD_OFFSET 3 //!< just make file handler more like POSIX (0, 1, 2 for stdin/stdout/stderr) - -#define OBJ2FD(obj) \ - ( \ - ( \ - uffs_PoolGetIndex(uffs_GetObjectPool(), obj) | \ - (_fd_signature << FD_SIGNATURE_SHIFT) \ - ) \ - + FD_OFFSET \ - ) - -/** - * check #fd signature, convert #fd to #obj - * if success, hold global file system lock, otherwise return with #ret - */ -#define CHK_OBJ_LOCK(fd, obj, ret) \ - do { \ - uffs_GlobalFsLockLock(); \ - fd -= FD_OFFSET; \ - if ( (fd >> FD_SIGNATURE_SHIFT) != _fd_signature ) { \ - uffs_set_error(-UEBADF); \ - uffs_Perror(UFFS_MSG_NOISY, "invalid fd: %d (sig: %d, expect: %d)", \ - fd + FD_OFFSET, fd >> FD_SIGNATURE_SHIFT, _fd_signature); \ - uffs_GlobalFsLockUnlock(); \ - return (ret); \ - } \ - fd = fd & ((1 << FD_SIGNATURE_SHIFT) - 1); \ - obj = (uffs_Object *)uffs_PoolGetBufByIndex(uffs_GetObjectPool(), fd); \ - if ((obj) == NULL || \ - uffs_PoolVerify(uffs_GetObjectPool(), (obj)) == U_FALSE || \ - uffs_PoolCheckFreeList(uffs_GetObjectPool(), (obj)) == U_TRUE) { \ - uffs_set_error(-UEBADF); \ - uffs_Perror(UFFS_MSG_NOISY, "invalid obj"); \ - uffs_GlobalFsLockUnlock(); \ - return (ret); \ - } \ - } while(0) - -/** - * check #dirp signature, - * if success, hold global file system lock, - * otherwise return with #ret - */ -#define CHK_DIR_LOCK(dirp, ret) \ - do { \ - uffs_GlobalFsLockLock(); \ - if ((dirp) == NULL || \ - uffs_PoolVerify(&_dir_pool, (dirp)) == U_FALSE || \ - uffs_PoolCheckFreeList(&_dir_pool, (dirp)) == U_TRUE) { \ - uffs_set_error(-UEBADF); \ - uffs_Perror(UFFS_MSG_NOISY, "invalid dirp"); \ - uffs_GlobalFsLockUnlock(); \ - return (ret); \ - } \ - } while(0) - -/** - * check #dirp signature, - * if success, hold global file system lock, - * otherwise return void - */ -#define CHK_DIR_VOID_LOCK(dirp) \ - do { \ - uffs_GlobalFsLockLock(); \ - if ((dirp) == NULL || \ - uffs_PoolVerify(&_dir_pool, (dirp)) == U_FALSE || \ - uffs_PoolCheckFreeList(&_dir_pool, (dirp)) == U_TRUE) { \ - uffs_set_error(-UEBADF); \ - uffs_Perror(UFFS_MSG_NOISY, "invalid dirp"); \ - uffs_GlobalFsLockUnlock(); \ - return; \ - } \ - } while(0) - - -static int _dir_pool_data[sizeof(uffs_DIR) * MAX_DIR_HANDLE / sizeof(int)]; -static uffs_Pool _dir_pool; -static int _uffs_errno = 0; - - -// -// What is fd signature ? fd signature is for detecting file system get formated by other party. -// A thread open a file, read()...sleep()...write()...sleep()... -// B thread format UFFS partition, increase fd signature. -// A thread ...sleep()...read() --> Opps, fd signature changed ! read() return error(expected). -// -#define MAX_FD_SIGNATURE_ROUND (100) -static int _fd_signature = 0; - -// -// only get called when formating UFFS partition -// -void uffs_FdSignatureIncrease(void) -{ - if (_fd_signature++ > MAX_FD_SIGNATURE_ROUND) - _fd_signature = 0; -} - -/** - * initialise uffs_DIR buffers, called by UFFS internal - */ -URET uffs_DirEntryBufInit(void) -{ - return uffs_PoolInit(&_dir_pool, _dir_pool_data, - sizeof(_dir_pool_data), - sizeof(uffs_DIR), MAX_DIR_HANDLE); -} - -/** - * Release uffs_DIR buffers, called by UFFS internal - */ -URET uffs_DirEntryBufRelease(void) -{ - return uffs_PoolRelease(&_dir_pool); -} - -/** - * Put all dir entry buf match dev - */ -int uffs_DirEntryBufPutAll(uffs_Device *dev) -{ - int count = 0; - uffs_DIR *dirp = NULL; - - do { - dirp = (uffs_DIR *) uffs_PoolFindNextAllocated(&_dir_pool, dirp); - if (dirp && dirp->obj && dirp->obj->dev && - dirp->obj->dev->dev_num == dev->dev_num) { - uffs_PoolPut(&_dir_pool, dirp); - count++; - } - } while (dirp); - - return count; -} - - -uffs_Pool * uffs_DirEntryBufGetPool(void) -{ - return &_dir_pool; -} - -static uffs_DIR * GetDirEntry(void) -{ - uffs_DIR *dirp = (uffs_DIR *) uffs_PoolGet(&_dir_pool); - - if (dirp) - memset(dirp, 0, sizeof(uffs_DIR)); - - return dirp; -} - -static void PutDirEntry(uffs_DIR *p) -{ - uffs_PoolPut(&_dir_pool, p); -} - - -/** get global errno - */ -int uffs_get_error(void) -{ - return _uffs_errno; -} - -/** set global errno - */ -int uffs_set_error(int err) -{ - return (_uffs_errno = err); -} - -/* POSIX compliant file system APIs */ - -int uffs_open(const char *name, int oflag, ...) -{ - uffs_Object *obj; - int ret = 0; - - uffs_GlobalFsLockLock(); - - obj = uffs_GetObject(); - if (obj == NULL) { - uffs_set_error(-UEMFILE); - ret = -1; - } - else { - if (uffs_OpenObject(obj, name, oflag) == U_FAIL) { - uffs_set_error(-uffs_GetObjectErr(obj)); - uffs_PutObject(obj); - ret = -1; - } - else { - ret = OBJ2FD(obj); - } - } - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_close(int fd) -{ - int ret = 0; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - - uffs_ClearObjectErr(obj); - if (uffs_CloseObject(obj) == U_FAIL) { - uffs_set_error(-uffs_GetObjectErr(obj)); - ret = -1; - } - else { - uffs_PutObject(obj); - ret = 0; - } - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_read(int fd, void *data, int len) -{ - int ret; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - uffs_ClearObjectErr(obj); - ret = uffs_ReadObject(obj, data, len); - uffs_set_error(-uffs_GetObjectErr(obj)); - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_write(int fd, const void *data, int len) -{ - int ret; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - uffs_ClearObjectErr(obj); - ret = uffs_WriteObject(obj, data, len); - uffs_set_error(-uffs_GetObjectErr(obj)); - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -long uffs_seek(int fd, long offset, int origin) -{ - int ret; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - uffs_ClearObjectErr(obj); - ret = uffs_SeekObject(obj, offset, origin); - uffs_set_error(-uffs_GetObjectErr(obj)); - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -long uffs_tell(int fd) -{ - long ret; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - uffs_ClearObjectErr(obj); - ret = (long) uffs_GetCurOffset(obj); - uffs_set_error(-uffs_GetObjectErr(obj)); - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_eof(int fd) -{ - int ret; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - uffs_ClearObjectErr(obj); - ret = uffs_EndOfFile(obj); - uffs_set_error(-uffs_GetObjectErr(obj)); - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_flush(int fd) -{ - int ret; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - uffs_ClearObjectErr(obj); - ret = (uffs_FlushObject(obj) == U_SUCC) ? 0 : -1; - uffs_set_error(-uffs_GetObjectErr(obj)); - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_rename(const char *old_name, const char *new_name) -{ - int err = 0; - int ret = 0; - - uffs_GlobalFsLockLock(); - ret = (uffs_RenameObject(old_name, new_name, &err) == U_SUCC) ? 0 : -1; - uffs_set_error(-err); - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_remove(const char *name) -{ - int err = 0; - int ret = 0; - struct uffs_stat st; - - if (uffs_stat(name, &st) < 0) { - err = UENOENT; - ret = -1; - } - else if (st.st_mode & US_IFDIR) { - err = UEISDIR; - ret = -1; - } - else { - uffs_GlobalFsLockLock(); - if (uffs_DeleteObject(name, &err) == U_SUCC) { - ret = 0; - } - else { - ret = -1; - } - uffs_GlobalFsLockUnlock(); - } - - uffs_set_error(-err); - return ret; -} - -int uffs_ftruncate(int fd, long remain) -{ - int ret; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - uffs_ClearObjectErr(obj); - ret = (uffs_TruncateObject(obj, remain) == U_SUCC) ? 0 : -1; - uffs_set_error(-uffs_GetObjectErr(obj)); - uffs_GlobalFsLockUnlock(); - - return ret; -} - -static int do_stat(uffs_Object *obj, struct uffs_stat *buf) -{ - uffs_ObjectInfo info; - int ret = 0; - int err = 0; - - if (uffs_GetObjectInfo(obj, &info, &err) == U_FAIL) { - ret = -1; - } - else { - buf->st_dev = obj->dev->dev_num; - buf->st_ino = info.serial; - buf->st_nlink = 0; - buf->st_uid = 0; - buf->st_gid = 0; - buf->st_rdev = 0; - buf->st_size = info.len; - buf->st_blksize = obj->dev->com.pg_data_size; - buf->st_blocks = 0; - buf->st_atime = info.info.last_modify; - buf->st_mtime = info.info.last_modify; - buf->st_ctime = info.info.create_time; - buf->st_mode = (info.info.attr & FILE_ATTR_DIR ? US_IFDIR : US_IFREG); - if (info.info.attr & FILE_ATTR_WRITE) - buf->st_mode |= US_IRWXU; - } - - uffs_set_error(-err); - return ret; -} - -int uffs_stat(const char *name, struct uffs_stat *buf) -{ - uffs_Object *obj; - int ret = 0; - int err = 0; - URET result; - - uffs_GlobalFsLockLock(); - - obj = uffs_GetObject(); - if (obj) { - if (*name && name[strlen(name) - 1] == '/') { - result = uffs_OpenObject(obj, name, UO_RDONLY | UO_DIR); - } - else { - if ((result = uffs_OpenObject(obj, name, UO_RDONLY)) != U_SUCC) // try file - result = uffs_OpenObject(obj, name, UO_RDONLY | UO_DIR); // then try dir - } - if (result == U_SUCC) { - ret = do_stat(obj, buf); - uffs_CloseObject(obj); - } - else { - err = uffs_GetObjectErr(obj); - ret = -1; - } - uffs_PutObject(obj); - } - else { - err = UENOMEM; - ret = -1; - } - - uffs_set_error(-err); - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_lstat(const char *name, struct uffs_stat *buf) -{ - return uffs_stat(name, buf); -} - -int uffs_fstat(int fd, struct uffs_stat *buf) -{ - int ret; - uffs_Object *obj; - - CHK_OBJ_LOCK(fd, obj, -1); - - ret = do_stat(obj, buf); - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_closedir(uffs_DIR *dirp) -{ - CHK_DIR_LOCK(dirp, -1); - - uffs_FindObjectClose(&dirp->f); - if (dirp->obj) { - uffs_CloseObject(dirp->obj); - uffs_PutObject(dirp->obj); - } - PutDirEntry(dirp); - uffs_GlobalFsLockUnlock(); - - return 0; -} - -uffs_DIR * uffs_opendir(const char *path) -{ - int err = 0; - uffs_DIR *ret = NULL; - uffs_DIR *dirp; - - uffs_GlobalFsLockLock(); - - dirp = GetDirEntry(); - - if (dirp) { - dirp->obj = uffs_GetObject(); - if (dirp->obj) { - if (uffs_OpenObject(dirp->obj, path, UO_RDONLY | UO_DIR) == U_SUCC) { - if (uffs_FindObjectOpen(&dirp->f, dirp->obj) == U_SUCC) { - ret = dirp; - goto ext; - } - else { - uffs_CloseObject(dirp->obj); - } - } - else { - err = uffs_GetObjectErr(dirp->obj); - } - uffs_PutObject(dirp->obj); - dirp->obj = NULL; - } - else { - err = UEMFILE; - } - PutDirEntry(dirp); - } - else { - err = UEMFILE; - } -ext: - uffs_set_error(-err); - uffs_GlobalFsLockUnlock(); - - return ret; -} - -struct uffs_dirent * uffs_readdir(uffs_DIR *dirp) -{ - struct uffs_dirent *ent = NULL; - - CHK_DIR_LOCK(dirp, NULL); - - if (uffs_FindObjectNext(&dirp->info, &dirp->f) == U_SUCC) { - ent = &dirp->dirent; - ent->d_ino = dirp->info.serial; - ent->d_namelen = dirp->info.info.name_len < (sizeof(ent->d_name) - 1) ? dirp->info.info.name_len : (sizeof(ent->d_name) - 1); - memcpy(ent->d_name, dirp->info.info.name, ent->d_namelen); - ent->d_name[ent->d_namelen] = '\0'; - ent->d_off = dirp->f.pos; - ent->d_reclen = sizeof(struct uffs_dirent); - ent->d_type = dirp->info.info.attr; - } - uffs_GlobalFsLockUnlock(); - - return ent; -} - -void uffs_rewinddir(uffs_DIR *dirp) -{ - CHK_DIR_VOID_LOCK(dirp); - - uffs_FindObjectRewind(&dirp->f); - - uffs_GlobalFsLockUnlock(); -} - - -int uffs_mkdir(const char *name, ...) -{ - uffs_Object *obj; - int ret = 0; - int err = 0; - - uffs_GlobalFsLockLock(); - - obj = uffs_GetObject(); - if (obj) { - if (uffs_CreateObject(obj, name, UO_CREATE|UO_DIR) != U_SUCC) { - err = obj->err; - ret = -1; - } - else { - uffs_CloseObject(obj); - ret = 0; - } - uffs_PutObject(obj); - } - else { - err = UEMFILE; - ret = -1; - } - - uffs_set_error(-err); - uffs_GlobalFsLockUnlock(); - - return ret; -} - -int uffs_rmdir(const char *name) -{ - int err = 0; - int ret = 0; - struct uffs_stat st; - - if (uffs_stat(name, &st) < 0) { - err = UENOENT; - ret = -1; - } - else if ((st.st_mode & US_IFDIR) == 0) { - err = UENOTDIR; - ret = -1; - } - else { - uffs_GlobalFsLockLock(); - if (uffs_DeleteObject(name, &err) == U_SUCC) { - ret = 0; - } - else { - ret = -1; - } - uffs_GlobalFsLockUnlock(); - } - uffs_set_error(-err); - return ret; -} - -int uffs_version(void) -{ - return uffs_GetVersion(); -} - -int uffs_format(const char *mount_point) -{ - uffs_Device *dev = NULL; - URET ret = U_FAIL; - - dev = uffs_GetDeviceFromMountPoint(mount_point); - if (dev) { - uffs_GlobalFsLockLock(); - ret = uffs_FormatDevice(dev, U_TRUE); - uffs_GlobalFsLockUnlock(); - } - - return ret == U_SUCC ? 0 : -1; -} - -long uffs_space_total(const char *mount_point) -{ - uffs_Device *dev = NULL; - long ret = -1L; - - dev = uffs_GetDeviceFromMountPoint(mount_point); - if (dev) { - uffs_GlobalFsLockLock(); - ret = (long) uffs_GetDeviceTotal(dev); - uffs_GlobalFsLockUnlock(); - } - - return ret; -} - -long uffs_space_used(const char *mount_point) -{ - uffs_Device *dev = NULL; - long ret = -1L; - - dev = uffs_GetDeviceFromMountPoint(mount_point); - if (dev) { - uffs_GlobalFsLockLock(); - ret = (long) uffs_GetDeviceUsed(dev); - uffs_GlobalFsLockUnlock(); - } - - return ret; -} - -long uffs_space_free(const char *mount_point) -{ - uffs_Device *dev = NULL; - long ret = -1L; - - dev = uffs_GetDeviceFromMountPoint(mount_point); - if (dev) { - uffs_GlobalFsLockLock(); - ret = (long) uffs_GetDeviceFree(dev); - uffs_GlobalFsLockUnlock(); - } - - return ret; -} - - -void uffs_flush_all(const char *mount_point) -{ - uffs_Device *dev = NULL; - - dev = uffs_GetDeviceFromMountPoint(mount_point); - if (dev) { - uffs_GlobalFsLockLock(); - uffs_BufFlushAll(dev); - uffs_PutDevice(dev); - uffs_GlobalFsLockUnlock(); - } -} - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_find.c b/components/dfs/filesystems/uffs/src/uffs/uffs_find.c deleted file mode 100644 index e79da042f7..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_find.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_find.c - * \brief find objects under dir - * \author Ricky Zheng, created 13th July, 2009 - */ - -#include <string.h> -#include <stdio.h> -#include "uffs_config.h" -#include "uffs/uffs_find.h" - -#define TPOOL(dev) &((dev)->mem.tree_pool) - -static void ResetFindInfo(uffs_FindInfo *f) -{ - f->hash = 0; - f->work = NULL; - f->step = 0; - f->pos = 0; -} - -static URET _LoadObjectInfo(uffs_Device *dev, - TreeNode *node, - uffs_ObjectInfo *info, - int type, - int *err) -{ - uffs_Buf *buf; - - buf = uffs_BufGetEx(dev, (u8)type, node, 0, 0); - - if (buf == NULL) { - if (err) - *err = UENOMEM; - return U_FAIL; - } - - memcpy(&(info->info), buf->data, sizeof(uffs_FileInfo)); - - if (type == UFFS_TYPE_DIR) { - info->len = 0; - info->serial = node->u.dir.serial; - } - else { - info->len = node->u.file.len; - info->serial = node->u.file.serial; - } - - uffs_BufPut(dev, buf); - - return U_SUCC; -} - -/** - * get object information - * - * \param[in] obj the object to be revealed - * \param[out] info object information will be loaded to info - * \param[out] err return error code if failed - * - * \return U_SUCC or U_FAIL - * - * \node the obj should be openned before call this function. - */ -URET uffs_GetObjectInfo(uffs_Object *obj, uffs_ObjectInfo *info, int *err) -{ - uffs_Device *dev = obj->dev; - URET ret = U_FAIL; - - uffs_DeviceLock(dev); - - if (obj && dev && info) { - if (obj->parent == PARENT_OF_ROOT) { - // this is ROOT. UFFS does not physically has root, just fake it ... - memset(info, 0, sizeof(uffs_ObjectInfo)); - info->serial = obj->serial; - info->info.attr |= (FILE_ATTR_DIR | FILE_ATTR_WRITE); - if (err) - *err = UENOERR; - ret = U_SUCC; - } - else - ret = _LoadObjectInfo(dev, obj->node, info, obj->type, err); - } - else { - if (err) - *err = UEINVAL; - } - - uffs_DeviceUnLock(dev); - - return ret; -} - - -/** - * Open a FindInfo for finding objects under dir - * - * \param[out] f uffs_FindInfo structure - * \param[in] dir an openned dir object (openned by uffs_OpenObject() ). - * - * \return U_SUCC if success, U_FAIL if invalid param or the dir - * is not been openned. - */ -URET uffs_FindObjectOpen(uffs_FindInfo *f, uffs_Object *dir) -{ - if (f == NULL || dir == NULL || - dir->dev == NULL || dir->open_succ != U_TRUE) - return U_FAIL; - - f->dev = dir->dev; - f->serial = dir->serial; - ResetFindInfo(f); - - return U_SUCC; -} - -/** - * Open a FindInfo for finding objects under dir - * - * \param[out] f uffs_FindInfo structure - * \param[in] dev uffs device - * \param[in] dir serial number of the dir to be searched - * - * \return U_SUCC if success, U_FAIL if invalid param or the dir - * serial number is not valid. - */ -URET uffs_FindObjectOpenEx(uffs_FindInfo *f, uffs_Device *dev, int dir) -{ - TreeNode *node; - - if (f == NULL || dev == NULL) - return U_FAIL; - - node = uffs_TreeFindDirNode(dev, dir); - - if (node == NULL) - return U_FAIL; - - f->serial = dir; - f->dev = dev; - ResetFindInfo(f); - - return U_SUCC; -} - - -static URET do_FindObject(uffs_FindInfo *f, uffs_ObjectInfo *info, u16 x) -{ - URET ret = U_SUCC; - TreeNode *node; - uffs_Device *dev = f->dev; - - if (f->step == 0) { //!< working on dirs - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.dir.parent == f->serial) { - f->work = node; - f->pos++; - if (info) - ret = _LoadObjectInfo(dev, node, info, UFFS_TYPE_DIR, NULL); - goto ext; - } - x = node->hash_next; - } - - f->hash++; //come to next hash entry - - for (; f->hash < DIR_NODE_ENTRY_LEN; f->hash++) { - x = dev->tree.dir_entry[f->hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.dir.parent == f->serial) { - f->work = node; - f->pos++; - if (info) - ret = _LoadObjectInfo(dev, node, info, UFFS_TYPE_DIR, NULL); - goto ext; - } - x = node->hash_next; - } - } - - //no subdirs, then lookup files .. - f->step++; - f->hash = 0; - x = dev->tree.file_entry[f->hash]; - } - - if (f->step == 1) { - - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.file.parent == f->serial) { - f->work = node; - f->pos++; - if (info) - ret = _LoadObjectInfo(dev, node, info, UFFS_TYPE_FILE, NULL); - goto ext; - } - x = node->hash_next; - } - - f->hash++; //come to next hash entry - - for (; f->hash < FILE_NODE_ENTRY_LEN; f->hash++) { - x = dev->tree.file_entry[f->hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.file.parent == f->serial) { - f->work = node; - f->pos++; - if (info) - ret = _LoadObjectInfo(dev, node, info, UFFS_TYPE_FILE, NULL); - goto ext; - } - x = node->hash_next; - } - } - - //no any files, stopped. - f->step++; - } - - ret = U_FAIL; -ext: - - return ret; - -} - - -/** - * Find the first object - * - * \param[out] info the object information will be filled to info. - * if info is NULL, then skip this object. - * \param[in] f uffs_FindInfo structure, openned by uffs_FindObjectOpen(). - * - * \return U_SUCC if an object is found, U_FAIL if no object is found. - */ -URET uffs_FindObjectFirst(uffs_ObjectInfo * info, uffs_FindInfo * f) -{ - uffs_Device *dev = f->dev; - URET ret = U_SUCC; - - uffs_DeviceLock(dev); - ResetFindInfo(f); - ret = do_FindObject(f, info, dev->tree.dir_entry[0]); - uffs_DeviceUnLock(dev); - - return ret; -} - -/** - * Find the next object. - * - * \param[out] info the object information will be filled to info. - * if info is NULL, then skip this object. - * \param[in] f uffs_FindInfo structure, openned by uffs_FindObjectOpen(). - * - * \return U_SUCC if an object is found, U_FAIL if no object is found. - * - * \note uffs_FindObjectFirst() should be called before uffs_FindObjectNext(). - */ -URET uffs_FindObjectNext(uffs_ObjectInfo *info, uffs_FindInfo * f) -{ - uffs_Device *dev = f->dev; - URET ret = U_SUCC; - - if (dev == NULL || f->step > 1) - return U_FAIL; - - if (f->work == NULL) - return uffs_FindObjectFirst(info, f); - - uffs_DeviceLock(dev); - ret = do_FindObject(f, info, f->work->hash_next); - uffs_DeviceUnLock(dev); - - return ret; -} - -/** - * Rewind a find object process. - * - * \note After rewind, you can call uffs_FindObjectFirst() to - * start find object process. - */ -URET uffs_FindObjectRewind(uffs_FindInfo *f) -{ - if (f == NULL) - return U_FAIL; - - ResetFindInfo(f); - - return U_SUCC; -} - -/** - * Close Find Object. - * - * \param[in] f uffs_FindInfo structure, openned by uffs_FindObjectOpen(). - * - * \return U_SUCC if success, U_FAIL if invalid param. - */ -URET uffs_FindObjectClose(uffs_FindInfo * f) -{ - if (f == NULL) - return U_FAIL; - - f->dev = NULL; - ResetFindInfo(f); - - return U_SUCC; -} - -/** - * Count objects - * - * \param[in] f uffs_FindInfo structure, openned by uffs_FindObjectOpen(). - * - * \return object counts - * \note after call this function, you need to call - * uffs_FindObjectRewind() to start finding process. - */ -int uffs_FindObjectCount(uffs_FindInfo *f) -{ - if (uffs_FindObjectFirst(NULL, f) == U_SUCC) { - while (uffs_FindObjectNext(NULL, f) == U_SUCC) { }; - } - return f->pos; -} - -/** - * Return current finding position - * - * \param[in] f uffs_FindInfo structure, openned by uffs_FindObjectOpen(). - * - * \return current finding position - */ -int uffs_FindObjectTell(uffs_FindInfo *f) -{ - return f->pos; -} - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_flash.c b/components/dfs/filesystems/uffs/src/uffs/uffs_flash.c deleted file mode 100644 index be4f4246dc..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_flash.c +++ /dev/null @@ -1,1034 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_flash.c - * \brief UFFS flash interface - * \author Ricky Zheng, created 17th July, 2009 - */ -#include "uffs_config.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_ecc.h" -#include "uffs/uffs_flash.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_badblock.h" -#include "uffs/uffs_crc.h" -#include <string.h> - -#define PFX "flsh: " - -#define SPOOL(dev) &((dev)->mem.spare_pool) -#define HEADER(buf) ((struct uffs_MiniHeaderSt *)(buf)->header) - -#define ECC_SIZE(dev) ((dev)->attr->ecc_size) -#define NOMINAL_ECC_SIZE(dev) (3 * ((((dev)->attr->page_data_size - 1) / 256) + 1)) - -#define TAG_STORE_SIZE (sizeof(struct uffs_TagStoreSt)) - -#define SEAL_BYTE(dev, spare) spare[(dev)->mem.spare_data_size - 1] // seal byte is the last byte of spare data - -#if defined(CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME) -/** Linux MTD spare layout for 512 and 2K page size */ -static const u8 MTD512_LAYOUT_ECC[] = {0, 4, 6, 2, 0xFF, 0}; -static const u8 MTD512_LAYOUT_DATA[] = {8, 8, 0xFF, 0}; -static const u8 MTD2K_LAYOUT_ECC[] = {40, 24, 0xFF, 0}; -static const u8 MTD2K_LAYOUT_DATA[] = {2, 38, 0xFF, 0}; -#endif - -static void TagMakeEcc(struct uffs_TagStoreSt *ts) -{ - ts->tag_ecc = 0xFFF; - ts->tag_ecc = uffs_EccMake8(ts, sizeof(struct uffs_TagStoreSt)); -} - -static int TagEccCorrect(struct uffs_TagStoreSt *ts) -{ - u16 ecc_store, ecc_read; - int ret; - - ecc_store = ts->tag_ecc; - ts->tag_ecc = 0xFFF; - ecc_read = uffs_EccMake8(ts, sizeof(struct uffs_TagStoreSt)); - ret = uffs_EccCorrect8(ts, ecc_read, ecc_store, sizeof(struct uffs_TagStoreSt)); - ts->tag_ecc = ecc_store; // restore tag ecc - - return ret; - -} - -/** setup UFFS spare data & ecc layout */ -static void InitSpareLayout(uffs_Device *dev) -{ - u8 s; // status byte offset - u8 *p; - - s = dev->attr->block_status_offs; - - if (s < TAG_STORE_SIZE) { /* status byte is within 0 ~ TAG_STORE_SIZE-1 */ - - /* spare data layout */ - p = dev->attr->_uffs_data_layout; - if (s > 0) { - *p++ = 0; - *p++ = s; - } - *p++ = s + 1; - *p++ = TAG_STORE_SIZE - s; - *p++ = 0xFF; - *p++ = 0; - - /* spare ecc layout */ - p = dev->attr->_uffs_ecc_layout; - if (dev->attr->ecc_opt != UFFS_ECC_NONE) { - *p++ = TAG_STORE_SIZE + 1; - *p++ = ECC_SIZE(dev); - } - *p++ = 0xFF; - *p++ = 0; - } - else { /* status byte > TAG_STORE_SIZE-1 */ - - /* spare data layout */ - p = dev->attr->_uffs_data_layout; - *p++ = 0; - *p++ = TAG_STORE_SIZE; - *p++ = 0xFF; - *p++ = 0; - - /* spare ecc layout */ - p = dev->attr->_uffs_ecc_layout; - if (dev->attr->ecc_opt != UFFS_ECC_NONE) { - if (s < TAG_STORE_SIZE + ECC_SIZE(dev)) { - if (s > TAG_STORE_SIZE) { - *p++ = TAG_STORE_SIZE; - *p++ = s - TAG_STORE_SIZE; - } - *p++ = s + 1; - *p++ = TAG_STORE_SIZE + ECC_SIZE(dev) - s; - } - else { - *p++ = TAG_STORE_SIZE; - *p++ = ECC_SIZE(dev); - } - } - *p++ = 0xFF; - *p++ = 0; - } - - dev->attr->data_layout = dev->attr->_uffs_data_layout; - dev->attr->ecc_layout = dev->attr->_uffs_ecc_layout; -} - -static int CalculateSpareDataSize(uffs_Device *dev) -{ - const u8 *p; - int ecc_last = 0, tag_last = 0; - int ecc_size, tag_size; - int n; - - ecc_size = (dev->attr->ecc_opt == UFFS_ECC_NONE ? 0 : ECC_SIZE(dev)); - - p = dev->attr->ecc_layout; - if (p) { - while (*p != 0xFF && ecc_size > 0) { - n = (p[1] > ecc_size ? ecc_size : p[1]); - ecc_last = p[0] + n; - ecc_size -= n; - p += 2; - } - } - - tag_size = TAG_STORE_SIZE; - p = dev->attr->data_layout; - if (p) { - while (*p != 0xFF && tag_size > 0) { - n = (p[1] > tag_size ? tag_size : p[1]); - tag_last = p[0] + n; - tag_size -= n; - p += 2; - } - } - - n = (ecc_last > tag_last ? ecc_last : tag_last); - n = (n > dev->attr->block_status_offs + 1 ? - n : dev->attr->block_status_offs + 1); - - return n + 1; // plus one seal byte. -} - - -/** - * Initialize UFFS flash interface - */ -URET uffs_FlashInterfaceInit(uffs_Device *dev) -{ - URET ret = U_FAIL; - struct uffs_StorageAttrSt *attr = dev->attr; - uffs_Pool *pool = SPOOL(dev); - - if (dev->mem.spare_pool_size == 0) { - if (dev->mem.malloc) { - dev->mem.spare_pool_buf = dev->mem.malloc(dev, UFFS_SPARE_BUFFER_SIZE); - if (dev->mem.spare_pool_buf) - dev->mem.spare_pool_size = UFFS_SPARE_BUFFER_SIZE; - } - } - - if (UFFS_SPARE_BUFFER_SIZE > dev->mem.spare_pool_size) { - uffs_Perror(UFFS_MSG_DEAD, - "Spare buffer require %d but only %d available.", - UFFS_SPARE_BUFFER_SIZE, dev->mem.spare_pool_size); - memset(pool, 0, sizeof(uffs_Pool)); - goto ext; - } - - uffs_Perror(UFFS_MSG_NOISY, - "alloc spare buffers %d bytes.", - UFFS_SPARE_BUFFER_SIZE); - uffs_PoolInit(pool, dev->mem.spare_pool_buf, - dev->mem.spare_pool_size, - UFFS_MAX_SPARE_SIZE, MAX_SPARE_BUFFERS); - - // init flash driver - if (dev->ops->InitFlash) { - if (dev->ops->InitFlash(dev) < 0) - goto ext; - } - - if (dev->ops->WritePage == NULL && dev->ops->WritePageWithLayout == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "Flash driver must provide 'WritePage' or 'WritePageWithLayout' function!"); - goto ext; - } - - if (dev->ops->ReadPage == NULL && dev->ops->ReadPageWithLayout == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "Flash driver must provide 'ReadPage' or 'ReadPageWithLayout' function!"); - goto ext; - } - - if (dev->attr->layout_opt == UFFS_LAYOUT_UFFS) { - /* sanity check */ - - if (dev->attr->ecc_size == 0 && dev->attr->ecc_opt != UFFS_ECC_NONE) { - dev->attr->ecc_size = NOMINAL_ECC_SIZE(dev); - } - - uffs_Perror(UFFS_MSG_NORMAL, "ECC size %d", dev->attr->ecc_size); - - if ((dev->attr->data_layout && !dev->attr->ecc_layout) || - (!dev->attr->data_layout && dev->attr->ecc_layout)) { - uffs_Perror(UFFS_MSG_SERIOUS, - "Please setup data_layout and ecc_layout, " - "or leave them all NULL !"); - goto ext; - } - - if (!attr->data_layout && !attr->ecc_layout) { -#if defined(CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME) - switch(attr->page_data_size) { - case 512: - attr->ecc_layout = MTD512_LAYOUT_ECC; - attr->data_layout = MTD512_LAYOUT_DATA; - break; - case 2048: - attr->ecc_layout = MTD2K_LAYOUT_ECC; - attr->data_layout = MTD2K_LAYOUT_DATA; - break; - default: - InitSpareLayout(dev); - break; - } -#else - InitSpareLayout(dev); -#endif - } - } - else if (dev->attr->layout_opt == UFFS_LAYOUT_FLASH) { - if (dev->ops->WritePageWithLayout == NULL || dev->ops->ReadPageWithLayout == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "When using UFFS_LAYOUT_FLASH option, " - "flash driver must provide 'WritePageWithLayout' and 'ReadPageWithLayout' function!"); - goto ext; - } - } - else { - uffs_Perror(UFFS_MSG_SERIOUS, "Invalid layout_opt: %d", dev->attr->layout_opt); - goto ext; - } - - if (dev->ops->EraseBlock == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "Flash driver MUST implement 'EraseBlock()' function !"); - goto ext; - } - - dev->mem.spare_data_size = CalculateSpareDataSize(dev); - uffs_Perror(UFFS_MSG_NORMAL, "UFFS consume spare data size %d", dev->mem.spare_data_size); - - if (dev->mem.spare_data_size > dev->attr->spare_size) { - uffs_Perror(UFFS_MSG_SERIOUS, "NAND spare(%dB) can't hold UFFS spare data(%dB) !", - dev->attr->spare_size, dev->mem.spare_data_size); - goto ext; - } - - ret = U_SUCC; -ext: - return ret; -} - -/** - * Release UFFS flash interface - */ -URET uffs_FlashInterfaceRelease(uffs_Device *dev) -{ - uffs_Pool *pool; - - pool = SPOOL(dev); - if (pool->mem && dev->mem.free) { - dev->mem.free(dev, pool->mem); - pool->mem = NULL; - dev->mem.spare_pool_size = 0; - } - uffs_PoolRelease(pool); - memset(pool, 0, sizeof(uffs_Pool)); - - // release flash driver - if (dev->ops->ReleaseFlash) { - if (dev->ops->ReleaseFlash(dev) < 0) - return U_FAIL; - } - - return U_SUCC; -} - -/** - * unload spare to tag and ecc. - */ -void uffs_FlashUnloadSpare(uffs_Device *dev, - const u8 *spare, struct uffs_TagStoreSt *ts, u8 *ecc) -{ - u8 *p_tag = (u8 *)ts; - int tag_size = TAG_STORE_SIZE; - int ecc_size = dev->attr->ecc_size; - int n; - const u8 *p; - - // unload ecc - p = dev->attr->ecc_layout; - if (p && ecc) { - while (*p != 0xFF && ecc_size > 0) { - n = (p[1] > ecc_size ? ecc_size : p[1]); - memcpy(ecc, spare + p[0], n); - ecc_size -= n; - ecc += n; - p += 2; - } - } - - // unload tag - if (ts) { - p = dev->attr->data_layout; - while (*p != 0xFF && tag_size > 0) { - n = (p[1] > tag_size ? tag_size : p[1]); - memcpy(p_tag, spare + p[0], n); - tag_size -= n; - p_tag += n; - p += 2; - } - } -} - -/** - * Read tag from page spare - * - * \param[in] dev uffs device - * \param[in] block flash block num - * \param[in] page flash page num - * \param[out] tag tag to be filled - * - * \return #UFFS_FLASH_NO_ERR: success and/or has no flip bits. - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_ECC_FAIL: spare data has flip bits and ecc correct failed. - * #UFFS_FLASH_ECC_OK: spare data has flip bits and corrected by ecc. -*/ -int uffs_FlashReadPageTag(uffs_Device *dev, - int block, int page, uffs_Tags *tag) -{ - uffs_FlashOps *ops = dev->ops; - u8 * spare_buf; - int ret = UFFS_FLASH_UNKNOWN_ERR; - int tmp_ret; - UBOOL is_bad = U_FALSE; - - spare_buf = (u8 *) uffs_PoolGet(SPOOL(dev)); - if (spare_buf == NULL) - goto ext; - - if (ops->ReadPageWithLayout) { - ret = ops->ReadPageWithLayout(dev, block, page, NULL, 0, NULL, tag ? &tag->s : NULL, NULL); - if (tag) - tag->seal_byte = (ret == UFFS_FLASH_NOT_SEALED ? 0xFF : 0); - } - else { - ret = ops->ReadPage(dev, block, page, NULL, 0, NULL, - spare_buf, dev->mem.spare_data_size); - - if (tag) { - tag->seal_byte = SEAL_BYTE(dev, spare_buf); - - if (!UFFS_FLASH_HAVE_ERR(ret)) - uffs_FlashUnloadSpare(dev, spare_buf, &tag->s, NULL); - } - } - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - is_bad = U_TRUE; - - if (UFFS_FLASH_HAVE_ERR(ret)) - goto ext; - - if (tag) { - if (!TAG_IS_SEALED(tag)) // not sealed ? don't try tag ECC correction - goto ext; - - if (!TAG_IS_VALID(tag)) { - if (dev->attr->ecc_opt != UFFS_ECC_NONE) { - /* - * There could be a special case if: - * a) tag is sealed (so we are here), and - * b) s.valid == 1 and this bit is a 'bad' bit, and - * c) after tag ECC (corrected by tag ECC) s.valid == 0. - * - * So we need to try tag ECC (don't treat it as bad block if ECC failed) - */ - - struct uffs_TagStoreSt s; - - memcpy(&s, &tag->s, sizeof(s)); - tmp_ret = TagEccCorrect(&s); - - if (tmp_ret <= 0 || !TAG_IS_VALID(tag)) // can not corrected by ECC. - goto ext; - } - else { - goto ext; - } - } - - // do tag ecc correction - if (dev->attr->ecc_opt != UFFS_ECC_NONE) { - ret = TagEccCorrect(&tag->s); - ret = (ret < 0 ? UFFS_FLASH_ECC_FAIL : - (ret > 0 ? UFFS_FLASH_ECC_OK : UFFS_FLASH_NO_ERR)); - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - is_bad = U_TRUE; - - if (UFFS_FLASH_HAVE_ERR(ret)) - goto ext; - } - } - -ext: - if (is_bad) { - uffs_BadBlockAdd(dev, block); - uffs_Perror(UFFS_MSG_NORMAL, - "A new bad block (%d) is detected.", block); - } - - if (spare_buf) - uffs_PoolPut(SPOOL(dev), spare_buf); - - return ret; -} - -/** - * Read page data to buf (do ECC error correction if needed) - * \param[in] dev uffs device - * \param[in] block flash block num - * \param[in] page flash page num of the block - * \param[out] buf holding the read out data - * \param[in] skip_ecc skip ecc when reading data from flash - * - * \return #UFFS_FLASH_NO_ERR: success and/or has no flip bits. - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_ECC_FAIL: spare data has flip bits and ecc correct failed. - * #UFFS_FLASH_ECC_OK: spare data has flip bits and corrected by ecc. - * #UFFS_FLASH_CRC_ERR: CRC verification failed. - * #UFFS_FLASH_UNKNOWN_ERR: - * - * \note if skip_ecc is U_TRUE, skip CRC as well. - */ -int uffs_FlashReadPage(uffs_Device *dev, int block, int page, uffs_Buf *buf, UBOOL skip_ecc) -{ - uffs_FlashOps *ops = dev->ops; - struct uffs_StorageAttrSt *attr = dev->attr; - int size = dev->com.pg_size; - u8 ecc_buf[UFFS_MAX_ECC_SIZE]; - u8 ecc_store[UFFS_MAX_ECC_SIZE]; - UBOOL is_bad = U_FALSE; -#ifdef CONFIG_ENABLE_PAGE_DATA_CRC - UBOOL crc_ok = U_TRUE; -#endif - u8 * spare; - - int ret = UFFS_FLASH_UNKNOWN_ERR; - - spare = (u8 *) uffs_PoolGet(SPOOL(dev)); - if (spare == NULL) - goto ext; - - if (ops->ReadPageWithLayout) { - if (skip_ecc) - ret = ops->ReadPageWithLayout(dev, block, page, buf->header, size, NULL, NULL, NULL); - else - ret = ops->ReadPageWithLayout(dev, block, page, buf->header, size, ecc_buf, NULL, ecc_store); - } - else { - if (skip_ecc) - ret = ops->ReadPage(dev, block, page, buf->header, size, NULL, NULL, 0); - else - ret = ops->ReadPage(dev, block, page, buf->header, size, ecc_buf, spare, dev->mem.spare_data_size); - } - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - is_bad = U_TRUE; - - if (UFFS_FLASH_HAVE_ERR(ret)) - goto ext; - -#ifdef CONFIG_ENABLE_PAGE_DATA_CRC - if (!skip_ecc) { - crc_ok = (HEADER(buf)->crc == uffs_crc16sum(buf->data, size - sizeof(struct uffs_MiniHeaderSt)) ? U_TRUE : U_FALSE); - - if (crc_ok) - goto ext; // CRC is matched, no need to do ECC correction. - else { - if (dev->attr->ecc_opt == UFFS_ECC_NONE || dev->attr->ecc_opt == UFFS_ECC_HW_AUTO) { - // ECC is not enabled or ecc correction already done, error return immediately, - // otherwise, we try CRC check again after ecc correction. - ret = UFFS_FLASH_CRC_ERR; - goto ext; - } - } - } -#endif - - // make ECC for UFFS_ECC_SOFT - if (attr->ecc_opt == UFFS_ECC_SOFT && !skip_ecc) - uffs_EccMake(buf->header, size, ecc_buf); - - // unload ecc_store if driver doesn't do the layout - if (ops->ReadPageWithLayout == NULL) { - if (!skip_ecc && (attr->ecc_opt == UFFS_ECC_SOFT || attr->ecc_opt == UFFS_ECC_HW)) - uffs_FlashUnloadSpare(dev, spare, NULL, ecc_store); - } - - // check page data ecc - if (!skip_ecc && (dev->attr->ecc_opt == UFFS_ECC_SOFT || dev->attr->ecc_opt == UFFS_ECC_HW)) { - - ret = uffs_EccCorrect(buf->header, size, ecc_store, ecc_buf); - ret = (ret < 0 ? UFFS_FLASH_ECC_FAIL : - (ret > 0 ? UFFS_FLASH_ECC_OK : UFFS_FLASH_NO_ERR)); - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - is_bad = U_TRUE; - - if (UFFS_FLASH_HAVE_ERR(ret)) - goto ext; - } - -#ifdef CONFIG_ENABLE_PAGE_DATA_CRC - if (!skip_ecc && !UFFS_FLASH_HAVE_ERR(ret)) { - // Everything seems ok, do CRC check again. - if (HEADER(buf)->crc == uffs_crc16sum(buf->data, size - sizeof(struct uffs_MiniHeaderSt))) { - ret = UFFS_FLASH_CRC_ERR; - goto ext; - } - } -#endif - -ext: - switch(ret) { - case UFFS_FLASH_IO_ERR: - uffs_Perror(UFFS_MSG_NORMAL, "Read block %d page %d I/O error", block, page); - break; - case UFFS_FLASH_ECC_FAIL: - uffs_Perror(UFFS_MSG_NORMAL, "Read block %d page %d ECC failed", block, page); - ret = UFFS_FLASH_BAD_BLK; // treat ECC FAIL as BAD BLOCK - is_bad = U_TRUE; - break; - case UFFS_FLASH_ECC_OK: - uffs_Perror(UFFS_MSG_NORMAL, "Read block %d page %d bit flip corrected by ECC", block, page); - break; - case UFFS_FLASH_BAD_BLK: - uffs_Perror(UFFS_MSG_NORMAL, "Read block %d page %d BAD BLOCK found", block, page); - break; - case UFFS_FLASH_UNKNOWN_ERR: - uffs_Perror(UFFS_MSG_NORMAL, "Read block %d page %d UNKNOWN error!", block, page); - break; - case UFFS_FLASH_CRC_ERR: - uffs_Perror(UFFS_MSG_NORMAL, "Read block %d page %d CRC failed", block, page); - break; - default: - break; - } - - if (is_bad) - uffs_BadBlockAdd(dev, block); - - if (spare) - uffs_PoolPut(SPOOL(dev), spare); - - - return ret; -} - -/** - * make spare from tag and ecc - * - * \param[in] dev uffs dev - * \param[in] ts uffs tag store, NULL if don't pack tag store - * \param[in] ecc ecc of data, NULL if don't pack ecc - * \param[out] spare output buffer - * \note spare buffer size: dev->mem.spare_data_size, - * all unpacked bytes will be inited 0xFF - */ -void uffs_FlashMakeSpare(uffs_Device *dev, - const uffs_TagStore *ts, const u8 *ecc, u8* spare) -{ - u8 *p_ts = (u8 *)ts; - int ts_size = TAG_STORE_SIZE; - int ecc_size = ECC_SIZE(dev); - int n; - const u8 *p; - - if (!uffs_Assert(spare != NULL, "invalid param")) - return; - - memset(spare, 0xFF, dev->mem.spare_data_size); // initialize as 0xFF. - SEAL_BYTE(dev, spare) = 0; // set seal byte = 0. - - // load ecc - p = dev->attr->ecc_layout; - if (p && ecc) { - while (*p != 0xFF && ecc_size > 0) { - n = (p[1] > ecc_size ? ecc_size : p[1]); - memcpy(spare + p[0], ecc, n); - ecc_size -= n; - ecc += n; - p += 2; - } - } - - p = dev->attr->data_layout; - while (*p != 0xFF && ts_size > 0) { - n = (p[1] > ts_size ? ts_size : p[1]); - memcpy(spare + p[0], p_ts, n); - ts_size -= n; - p_ts += n; - p += 2; - } - - uffs_Assert(SEAL_BYTE(dev, spare) == 0, "Make spare fail!"); -} - -/** - * write the whole page, include data and tag - * - * \param[in] dev uffs device - * \param[in] block - * \param[in] page - * \param[in] buf contains data to be wrote - * \param[in] tag tag to be wrote - * - * \return #UFFS_FLASH_NO_ERR: success. - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_BAD_BLK: a new bad block detected. - */ -int uffs_FlashWritePageCombine(uffs_Device *dev, - int block, int page, - uffs_Buf *buf, uffs_Tags *tag) -{ - uffs_FlashOps *ops = dev->ops; - int size = dev->com.pg_size; - u8 ecc_buf[UFFS_MAX_ECC_SIZE]; - u8 *ecc = NULL; - u8 *spare; - struct uffs_MiniHeaderSt *header; - int ret = UFFS_FLASH_UNKNOWN_ERR; - UBOOL is_bad = U_FALSE; - uffs_Buf *verify_buf; -#ifdef CONFIG_PAGE_WRITE_VERIFY - uffs_Tags chk_tag; -#endif - - spare = (u8 *) uffs_PoolGet(SPOOL(dev)); - if (spare == NULL) - goto ext; - - // setup header - header = HEADER(buf); - memset(header, 0xFF, sizeof(struct uffs_MiniHeaderSt)); - header->status = 0; -#ifdef CONFIG_ENABLE_PAGE_DATA_CRC - header->crc = uffs_crc16sum(buf->data, size - sizeof(struct uffs_MiniHeaderSt)); -#endif - - // setup tag - TAG_DIRTY_BIT(tag) = TAG_DIRTY; //!< set dirty bit - TAG_VALID_BIT(tag) = TAG_VALID; //!< set valid bit - SEAL_TAG(tag); //!< seal tag (the real seal byte will be set in uffs_FlashMakeSpare()) - - if (dev->attr->ecc_opt != UFFS_ECC_NONE) - TagMakeEcc(&tag->s); - else - tag->s.tag_ecc = TAG_ECC_DEFAULT; - - if (dev->attr->ecc_opt == UFFS_ECC_SOFT) { - uffs_EccMake(buf->header, size, ecc_buf); - ecc = ecc_buf; - } - else if (dev->attr->ecc_opt == UFFS_ECC_HW) { - ecc = ecc_buf; - } - - if (ops->WritePageWithLayout) { - ret = ops->WritePageWithLayout(dev, block, page, - buf->header, size, ecc, &tag->s); - } - else { - - if (!uffs_Assert(!(dev->attr->layout_opt == UFFS_LAYOUT_FLASH || - dev->attr->ecc_opt == UFFS_ECC_HW || - dev->attr->ecc_opt == UFFS_ECC_HW_AUTO), "WritePageWithLayout() not implemented ?")) { - ret = UFFS_FLASH_IO_ERR; - goto ext; - } - - uffs_FlashMakeSpare(dev, &tag->s, ecc, spare); - - ret = ops->WritePage(dev, block, page, buf->header, size, spare, dev->mem.spare_data_size); - - } - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - is_bad = U_TRUE; - - if (UFFS_FLASH_HAVE_ERR(ret)) - goto ext; - -#ifdef CONFIG_PAGE_WRITE_VERIFY - verify_buf = uffs_BufClone(dev, NULL); - if (verify_buf) { - ret = uffs_FlashReadPage(dev, block, page, verify_buf, U_FALSE); - if (!UFFS_FLASH_HAVE_ERR(ret)) { - if (memcmp(buf->header, verify_buf->header, size) != 0) { - uffs_Perror(UFFS_MSG_NORMAL, - "Page write verify failed (block %d page %d)", - block, page); - ret = UFFS_FLASH_BAD_BLK; - } - } - - uffs_BufFreeClone(dev, verify_buf); - } - else { - uffs_Perror(UFFS_MSG_SERIOUS, "Insufficient buf, clone buf failed."); - } - - ret = uffs_FlashReadPageTag(dev, block, page, &chk_tag); - if (UFFS_FLASH_HAVE_ERR(ret)) - goto ext; - - if (memcmp(&tag->s, &chk_tag.s, sizeof(uffs_TagStore)) != 0) { - uffs_Perror(UFFS_MSG_NORMAL, "Page tag write verify failed (block %d page %d)", - block, page); - ret = UFFS_FLASH_BAD_BLK; - } - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - is_bad = U_TRUE; - -#endif -ext: - if (is_bad) - uffs_BadBlockAdd(dev, block); - - if (spare) - uffs_PoolPut(SPOOL(dev), spare); - - return ret; -} - -/** - * mark a clean page tag as 'dirty' and 'invalid'. - * - * \param[in] dev uffs device - * \param[in] bc block info - * \param[in] page - * - * \return #UFFS_FLASH_NO_ERR: success. - * #UFFS_FLASH_IO_ERR: I/O error, expect retry ? - * #UFFS_FLASH_BAD_BLK: a new bad block detected. - */ -int uffs_FlashMarkDirtyPage(uffs_Device *dev, uffs_BlockInfo *bc, int page) -{ - u8 *spare; - uffs_FlashOps *ops = dev->ops; - UBOOL is_bad = U_FALSE; - int ret = UFFS_FLASH_UNKNOWN_ERR; - int block = bc->block; - uffs_Tags *tag = GET_TAG(bc, page); - struct uffs_TagStoreSt *ts = &tag->s; - - spare = (u8 *) uffs_PoolGet(SPOOL(dev)); - if (spare == NULL) - goto ext; - - memset(ts, 0xFF, sizeof(struct uffs_TagStoreSt)); - ts->dirty = TAG_DIRTY; // set only 'dirty' bit, leave 'valid' bit to 1 (invalid). - - if (dev->attr->ecc_opt != UFFS_ECC_NONE) - TagMakeEcc(ts); - - if (ops->WritePageWithLayout) { - ret = ops->WritePageWithLayout(dev, block, page, NULL, 0, NULL, ts); - } - else { - uffs_FlashMakeSpare(dev, ts, NULL, spare); - ret = ops->WritePage(dev, block, page, NULL, 0, spare, dev->mem.spare_data_size); - } - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - is_bad = U_TRUE; - -ext: - if (is_bad) - uffs_BadBlockAdd(dev, block); - - if (spare) - uffs_PoolPut(SPOOL(dev), spare); - - return ret; -} - -/** Mark this block as bad block */ -URET uffs_FlashMarkBadBlock(uffs_Device *dev, int block) -{ - int ret; - uffs_BlockInfo *bc; - - uffs_Perror(UFFS_MSG_NORMAL, "Mark bad block: %d", block); - - bc = uffs_BlockInfoGet(dev, block); - if (bc) { - uffs_BlockInfoExpire(dev, bc, UFFS_ALL_PAGES); // expire this block, just in case it's been cached before - uffs_BlockInfoPut(dev, bc); - } - - if (dev->ops->MarkBadBlock) - return dev->ops->MarkBadBlock(dev, block) == 0 ? U_SUCC : U_FAIL; - -#ifdef CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD - ret = dev->ops->EraseBlock(dev, block); - if (ret != UFFS_FLASH_IO_ERR) { - // note: even EraseBlock return UFFS_FLASH_BAD_BLK, - // we still process it ... not recommended for most NAND flash. -#endif - if (dev->ops->WritePageWithLayout) - ret = dev->ops->WritePageWithLayout(dev, block, 0, NULL, 0, NULL, NULL); - else - ret = dev->ops->WritePage(dev, block, 0, NULL, 0, NULL, 0); - -#ifdef CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD - } -#endif - - return ret == UFFS_FLASH_NO_ERR ? U_SUCC : U_FAIL; -} - -/** Is this block a bad block ? */ -UBOOL uffs_FlashIsBadBlock(uffs_Device *dev, int block) -{ - struct uffs_FlashOpsSt *ops = dev->ops; - UBOOL ret = U_FALSE; - - if (ops->IsBadBlock) { - /* if flash driver provide 'IsBadBlock' function, call it */ - ret = (ops->IsBadBlock(dev, block) == 0 ? U_FALSE : U_TRUE); - } - else { - /* otherwise we call ReadPage[WithLayout]() to get bad block status byte */ - /* check the first page */ - if (ops->ReadPageWithLayout) { - ret = (ops->ReadPageWithLayout(dev, block, 0, NULL, 0, NULL, NULL, NULL) - == UFFS_FLASH_BAD_BLK ? U_TRUE : U_FALSE); - } - else { - ret = (ops->ReadPage(dev, block, 0, NULL, 0, NULL, NULL, 0) - == UFFS_FLASH_BAD_BLK ? U_TRUE : U_FALSE); - } - - if (ret == U_FALSE) { - /* check the second page */ - if (ops->ReadPageWithLayout) { - ret = (ops->ReadPageWithLayout(dev, block, 0, NULL, 0, NULL, NULL, NULL) - == UFFS_FLASH_BAD_BLK ? U_TRUE : U_FALSE); - } - else { - ret = (ops->ReadPage(dev, block, 0, NULL, 0, NULL, NULL, 0) - == UFFS_FLASH_BAD_BLK ? U_TRUE : U_FALSE); - } - } - } - - //uffs_Perror(UFFS_MSG_NOISY, "Block %d is %s", block, ret ? "BAD" : "GOOD"); - - return ret; -} - -/** Erase flash block */ -URET uffs_FlashEraseBlock(uffs_Device *dev, int block) -{ - int ret; - uffs_BlockInfo *bc; - - ret = dev->ops->EraseBlock(dev, block); - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - uffs_BadBlockAdd(dev, block); - - bc = uffs_BlockInfoGet(dev, block); - if (bc) { - uffs_BlockInfoExpire(dev, bc, UFFS_ALL_PAGES); - uffs_BlockInfoPut(dev, bc); - } - return UFFS_FLASH_HAVE_ERR(ret) ? U_FAIL : U_SUCC; -} - -/** - * Check the block by reading all pages. - * - * \return U_SUCC - all pages are clean, - * U_FAIL - block is not clean - */ -URET uffs_FlashCheckErasedBlock(uffs_Device *dev, int block) -{ - u8 *spare = NULL; - uffs_FlashOps *ops = dev->ops; - int ret = U_SUCC; - int page; - int flash_ret; - u8 ecc_store[UFFS_MAX_ECC_SIZE]; - uffs_TagStore ts; - uffs_Buf *buf = NULL; - int size = dev->com.pg_size; - int i; - u8 *p; - - spare = (u8 *) uffs_PoolGet(SPOOL(dev)); - - if (spare == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "Can't allocate spare buf."); - goto ext; - } - - buf = uffs_BufClone(dev, NULL); - - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "Can't clone buf."); - goto ext; - } - - for (page = 0; page < dev->attr->pages_per_block; page++) { - if (ops->ReadPageWithLayout) { - - flash_ret = ops->ReadPageWithLayout(dev, block, page, buf->header, size, NULL, &ts, ecc_store); - - if (flash_ret != UFFS_FLASH_IO_ERR) { - // check page tag, should be all 0xFF - for (i = 0, p = (u8 *)(&ts); i < sizeof(ts); i++, p++) { - if (*p != 0xFF) { - ret = U_FAIL; - goto ext; - } - } - - // for hw or soft ecc, check stored ecc, should be all 0xFF - if (dev->attr->ecc_opt == UFFS_ECC_HW || - dev->attr->ecc_opt == UFFS_ECC_SOFT) - { - for (i = 0, p = ecc_store; i < ECC_SIZE(dev); i++, p++) { - if (*p != 0xFF) { - ret = U_FAIL; - goto ext; - } - } - } - } - } - else { - - flash_ret = ops->ReadPage(dev, block, page, buf->header, size, NULL, spare, dev->attr->spare_size); - if (flash_ret != UFFS_FLASH_IO_ERR) { - // check spare data, should be all 0xFF - for (i = 0, p = spare; i < dev->attr->spare_size; i++, p++) { - if (*p != 0xFF) { - ret = U_FAIL; - goto ext; - } - } - } - } - - if (flash_ret != UFFS_FLASH_IO_ERR) { - // check page data, should be all 0xFF - for (i = 0, p = buf->header; i < size; i++, p++) { - if (*p != 0xFF) { - ret = U_FAIL; - goto ext; - } - } - } - - } - - -ext: - if (spare) - uffs_PoolPut(SPOOL(dev), spare); - - if (buf) - uffs_BufFreeClone(dev, buf); - - - return ret; -} - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_fs.c b/components/dfs/filesystems/uffs/src/uffs/uffs_fs.c deleted file mode 100644 index d467c3ec97..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_fs.c +++ /dev/null @@ -1,1944 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_fs.c - * \brief basic file operations - * \author Ricky Zheng, created 12th May, 2005 - */ -#include "uffs_config.h" -#include "uffs/uffs_fs.h" -#include "uffs/uffs_pool.h" -#include "uffs/uffs_ecc.h" -#include "uffs/uffs_badblock.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_mtb.h" -#include "uffs/uffs_utils.h" -#include <string.h> -#include <stdio.h> - -#define PFX "fs : " - -#define GET_OBJ_NODE_SERIAL(obj) \ - ( \ - (obj)->type == UFFS_TYPE_DIR ? \ - (obj)->node->u.dir.serial : (obj)->node->u.file.serial \ - ) - -#define GET_OBJ_NODE_FATHER(obj) \ - ( \ - (obj)->type == UFFS_TYPE_DIR ? \ - (obj)->node->u.dir.parent : (obj)->node->u.file.parent \ - ) - -#define GET_SERIAL_FROM_OBJECT(obj) \ - ((obj)->node ? GET_OBJ_NODE_SERIAL(obj) : obj->serial) - -#define GET_FATHER_FROM_OBJECT(obj) \ - ((obj)->node ? GET_OBJ_NODE_FATHER(obj) : obj->parent) - - -#define GET_BLOCK_FROM_NODE(obj) \ - ( \ - (obj)->type == UFFS_TYPE_DIR ? \ - (obj)->node->u.dir.block : (obj)->node->u.file.block \ - ) - -typedef enum { - eDRY_RUN = 0, - eREAL_RUN, -} RunOptionE; - - -static void do_ReleaseObjectResource(uffs_Object *obj); -static URET do_TruncateObject(uffs_Object *obj, u32 remain, RunOptionE run_opt); - - -static int _object_data[(sizeof(struct uffs_ObjectSt) * MAX_OBJECT_HANDLE) / sizeof(int)]; - -static uffs_Pool _object_pool; - - -uffs_Pool * uffs_GetObjectPool(void) -{ - return &_object_pool; -} - -/** - * initialise object buffers, called by UFFS internal - */ -URET uffs_InitObjectBuf(void) -{ - return uffs_PoolInit(&_object_pool, _object_data, sizeof(_object_data), - sizeof(uffs_Object), MAX_OBJECT_HANDLE); -} - -/** - * Release object buffers, called by UFFS internal - */ -URET uffs_ReleaseObjectBuf(void) -{ - return uffs_PoolRelease(&_object_pool); -} - -/** - * Get free object handlers - */ -int uffs_GetFreeObjectHandlers(void) -{ - int count = 0; - - uffs_GlobalFsLockLock(); - count = uffs_PoolGetFreeCount(&_object_pool); - uffs_GlobalFsLockUnlock(); - - return count; -} - -/** - * Put all object which match dev - */ -int uffs_PutAllObjectBuf(uffs_Device *dev) -{ - int count = 0; - uffs_Object * obj = NULL; - - do { - obj = (uffs_Object *) uffs_PoolFindNextAllocated(&_object_pool, (void *)obj); - if (obj && obj->dev && obj->dev->dev_num == dev->dev_num) { - uffs_PutObject(obj); - count++; - } - } while (obj); - - return count; -} - -/** - * alloc a new object structure - * \return the new object - */ -uffs_Object * uffs_GetObject(void) -{ - uffs_Object * obj; - - obj = (uffs_Object *) uffs_PoolGet(&_object_pool); - if (obj) { - memset(obj, 0, sizeof(uffs_Object)); - obj->attr_loaded = U_FALSE; - obj->open_succ = U_FALSE; - } - - return obj; -} - -/** - * re-initialize an object. - * - * \return U_SUCC or U_FAIL if the object is openned. - */ -URET uffs_ReInitObject(uffs_Object *obj) -{ - if (obj == NULL) - return U_FAIL; - - if (obj->open_succ == U_TRUE) - return U_FAIL; // can't re-init an openned object. - - memset(obj, 0, sizeof(uffs_Object)); - obj->attr_loaded = U_FALSE; - obj->open_succ = U_FALSE; - - return U_SUCC; -} - -/** - * put the object struct back to system - */ -void uffs_PutObject(uffs_Object *obj) -{ - if (obj) - uffs_PoolPut(&_object_pool, obj); -} - -/** - * \return the internal index num of object - */ -int uffs_GetObjectIndex(uffs_Object *obj) -{ - return uffs_PoolGetIndex(&_object_pool, obj); -} - -/** - * \return the object by the internal index - */ -uffs_Object * uffs_GetObjectByIndex(int idx) -{ - return (uffs_Object *) uffs_PoolGetBufByIndex(&_object_pool, idx); -} - -#ifdef CONFIG_PER_DEVICE_LOCK -static void uffs_ObjectDevLock(uffs_Object *obj) -{ - if (obj) { - if (obj->dev) { - uffs_DeviceLock(obj->dev); - obj->dev_lock_count++; - } - } -} - -static void uffs_ObjectDevUnLock(uffs_Object *obj) -{ - if (obj) { - if (obj->dev) { - obj->dev_lock_count--; - uffs_DeviceUnLock(obj->dev); - } - } -} -#else -#define uffs_ObjectDevLock(obj) do { } while (0) -#define uffs_ObjectDevUnLock(obj) do { } while (0) - -#endif - - - -/** - * create a new object and open it if success - */ -URET uffs_CreateObject(uffs_Object *obj, const char *fullname, int oflag) -{ - URET ret = U_FAIL; - - oflag |= UO_CREATE; - - if (uffs_ParseObject(obj, fullname) == U_SUCC) - uffs_CreateObjectEx(obj, obj->dev, obj->parent, - obj->name, obj->name_len, oflag); - - if (obj->err == UENOERR) { - ret = U_SUCC; - } - else { - if (obj->dev) { - uffs_PutDevice(obj->dev); - obj->dev = NULL; - } - ret = U_FAIL; - } - - return ret; -} - - - -/** - * return the dir length from a path. - * for example, path = "abc/def/xyz", return 8 ("abc/def/") - */ -static int GetDirLengthFromPath(const char *path, int path_len) -{ - const char *p = path; - - if (path_len > 0) { - if (path[path_len - 1] == '/') - path_len--; // skip the last '/' - - p = path + path_len - 1; - while (p > path && *p != '/') - p--; - } - - return p - path; -} - -/** - * Create an object under the given dir. - * - * \param[in|out] obj to be created, obj is returned from uffs_GetObject() - * \param[in] dev uffs device - * \param[in] dir object parent dir serial NO. - * \param[in] name point to the object name - * \param[in] name_len object name length - * \param[in] oflag open flag. UO_DIR should be passed for an dir object. - * - * \return U_SUCC or U_FAIL (error code in obj->err). - */ -URET uffs_CreateObjectEx(uffs_Object *obj, uffs_Device *dev, - int dir, const char *name, int name_len, int oflag) -{ - uffs_Buf *buf = NULL; - uffs_FileInfo fi; - TreeNode *node; - - obj->dev = dev; - obj->parent = dir; - obj->type = (oflag & UO_DIR ? UFFS_TYPE_DIR : UFFS_TYPE_FILE); - obj->name = name; - obj->name_len = name_len; - - if (obj->type == UFFS_TYPE_DIR) { - if (name[obj->name_len - 1] == '/') // get rid of ending '/' for dir - obj->name_len--; - } - else { - if (name[obj->name_len - 1] == '/') { // file name can't end with '/' - obj->err = UENOENT; - goto ext; - } - } - - if (obj->name_len == 0) { // empty name ? - obj->err = UENOENT; - goto ext; - } - - obj->sum = uffs_MakeSum16(obj->name, obj->name_len); - - uffs_ObjectDevLock(obj); - - if (obj->type == UFFS_TYPE_DIR) { - //find out whether have file with the same name - node = uffs_TreeFindFileNodeByName(obj->dev, obj->name, - obj->name_len, obj->sum, - obj->parent); - if (node != NULL) { - obj->err = UEEXIST; // we can't create a dir has the - // same name with exist file. - goto ext_1; - } - obj->node = uffs_TreeFindDirNodeByName(obj->dev, obj->name, - obj->name_len, obj->sum, - obj->parent); - if (obj->node != NULL) { - obj->err = UEEXIST; // we can't create a dir already exist. - goto ext_1; - } - } - else { - //find out whether have dir with the same name - node = uffs_TreeFindDirNodeByName(obj->dev, obj->name, - obj->name_len, obj->sum, - obj->parent); - if (node != NULL) { - obj->err = UEEXIST; - goto ext_1; - } - obj->node = uffs_TreeFindFileNodeByName(obj->dev, obj->name, - obj->name_len, obj->sum, - obj->parent); - if (obj->node) { - /* file already exist, truncate it to zero length */ - obj->serial = GET_OBJ_NODE_SERIAL(obj); - obj->open_succ = U_TRUE; // set open_succ to U_TRUE before - // call do_TruncateObject() - if (do_TruncateObject(obj, 0, eDRY_RUN) == U_SUCC) - do_TruncateObject(obj, 0, eREAL_RUN); - goto ext_1; - } - } - - /* dir|file does not exist, create a new one */ - obj->serial = uffs_FindFreeFsnSerial(obj->dev); - if (obj->serial == INVALID_UFFS_SERIAL) { - uffs_Perror(UFFS_MSG_SERIOUS, "No free serial num!"); - obj->err = UENOMEM; - goto ext_1; - } - - if (obj->dev->tree.erased_count < obj->dev->cfg.reserved_free_blocks) { - uffs_Perror(UFFS_MSG_NOISY, - "insufficient block in create obj"); - obj->err = UENOMEM; - goto ext_1; - } - - buf = uffs_BufNew(obj->dev, obj->type, obj->parent, obj->serial, 0); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "Can't create new buffer when create obj!"); - goto ext_1; - } - - memset(&fi, 0, sizeof(uffs_FileInfo)); - fi.name_len = obj->name_len < sizeof(fi.name) ? obj->name_len : sizeof(fi.name) - 1; - memcpy(fi.name, obj->name, fi.name_len); - fi.name[fi.name_len] = '\0'; - - fi.access = 0; - fi.attr |= FILE_ATTR_WRITE; - - if (obj->type == UFFS_TYPE_DIR) - fi.attr |= FILE_ATTR_DIR; - - fi.create_time = fi.last_modify = uffs_GetCurDateTime(); - - uffs_BufWrite(obj->dev, buf, &fi, 0, sizeof(uffs_FileInfo)); - uffs_BufPut(obj->dev, buf); - - // flush buffer immediately, - // so that the new node will be inserted into the tree - uffs_BufFlushGroup(obj->dev, obj->parent, obj->serial); - - // update obj->node: after buf flushed, - // the NEW node can be found in the tree - if (obj->type == UFFS_TYPE_DIR) - obj->node = uffs_TreeFindDirNode(obj->dev, obj->serial); - else - obj->node = uffs_TreeFindFileNode(obj->dev, obj->serial); - - if (obj->node == NULL) { - uffs_Perror(UFFS_MSG_NOISY, "Can't find the node in the tree ?"); - obj->err = UEIOERR; - goto ext_1; - } - - if (obj->type == UFFS_TYPE_FILE) - obj->node->u.file.len = 0; //init the length to 0 - - if (HAVE_BADBLOCK(obj->dev)) - uffs_BadBlockRecover(obj->dev); - - obj->open_succ = U_TRUE; - -ext_1: - uffs_ObjectDevUnLock(obj); -ext: - return (obj->err == UENOERR ? U_SUCC : U_FAIL); -} - -/** - * Open object under the given dir. - * - * \param[in|out] obj to be open, obj is returned from uffs_GetObject() - * \param[in] dev uffs device - * \param[in] dir object parent dir serial NO. - * \param[in] name point to the object name - * \param[in] name_len object name length - * \param[in] oflag open flag. UO_DIR should be passed for an dir object. - * - * \return U_SUCC or U_FAIL (error code in obj->err). - */ -URET uffs_OpenObjectEx(uffs_Object *obj, uffs_Device *dev, - int dir, const char *name, int name_len, int oflag) -{ - - obj->err = UENOERR; - obj->open_succ = U_FALSE; - - if (dev == NULL) { - obj->err = UEINVAL; - goto ext; - } - - if ((oflag & (UO_WRONLY | UO_RDWR)) == (UO_WRONLY | UO_RDWR)) { - /* UO_WRONLY and UO_RDWR can't appear together */ - uffs_Perror(UFFS_MSG_NOISY, - "UO_WRONLY and UO_RDWR can't appear together"); - obj->err = UEINVAL; - goto ext; - } - - obj->oflag = oflag; - obj->parent = dir; - obj->type = (oflag & UO_DIR ? UFFS_TYPE_DIR : UFFS_TYPE_FILE); - obj->pos = 0; - obj->dev = dev; - obj->name = name; - obj->name_len = name_len; - - // adjust the name length - if (obj->type == UFFS_TYPE_DIR) { - if (obj->name_len > 0 && name[obj->name_len - 1] == '/') - obj->name_len--; // truncate the ending '/' for dir - } - - obj->sum = (obj->name_len > 0 ? uffs_MakeSum16(name, obj->name_len) : 0); - obj->head_pages = obj->dev->attr->pages_per_block - 1; - - if (obj->type == UFFS_TYPE_DIR) { - if (obj->name_len == 0) { - if (dir != PARENT_OF_ROOT) { - uffs_Perror(UFFS_MSG_SERIOUS, "Bad parent for root dir!"); - obj->err = UEINVAL; - } - else { - obj->serial = ROOT_DIR_SERIAL; - } - goto ext; - } - } - else { - if (obj->name_len == 0 || name[obj->name_len - 1] == '/') { - uffs_Perror(UFFS_MSG_SERIOUS, "Bad file name."); - obj->err = UEINVAL; - } - } - - - uffs_ObjectDevLock(obj); - - if (obj->type == UFFS_TYPE_DIR) { - obj->node = uffs_TreeFindDirNodeByName(obj->dev, obj->name, - obj->name_len, obj->sum, - obj->parent); - } - else { - obj->node = uffs_TreeFindFileNodeByName(obj->dev, obj->name, - obj->name_len, obj->sum, - obj->parent); - } - - if (obj->node == NULL) { // dir or file not exist - if (obj->oflag & UO_CREATE) { // expect to create a new one - uffs_ObjectDevUnLock(obj); - if (obj->name == NULL || obj->name_len == 0) - obj->err = UEEXIST; - else - uffs_CreateObjectEx(obj, dev, dir, obj->name, obj->name_len, oflag); - goto ext; - } - else { - obj->err = UENOENT; - goto ext_1; - } - } - - if ((obj->oflag & (UO_CREATE | UO_EXCL)) == (UO_CREATE | UO_EXCL)){ - obj->err = UEEXIST; - goto ext_1; - } - - obj->serial = GET_OBJ_NODE_SERIAL(obj); - obj->open_succ = U_TRUE; - - if (obj->oflag & UO_TRUNC) - if (do_TruncateObject(obj, 0, eDRY_RUN) == U_SUCC) { - //NOTE: obj->err will be set in do_TruncateObject() if failed. - do_TruncateObject(obj, 0, eREAL_RUN); - } - -ext_1: - uffs_ObjectDevUnLock(obj); -ext: - obj->open_succ = (obj->err == UENOERR ? U_TRUE : U_FALSE); - - return (obj->err == UENOERR ? U_SUCC : U_FAIL); -} - - -/** - * Parse the full path name, initialize obj. - * - * \param[out] obj object to be initialize. - * \param[in] name full path name. - * - * \return U_SUCC if the name is parsed correctly, - * U_FAIL if failed, and obj->err is set. - * - * \note the following fields in obj will be initialized: - * obj->dev - * obj->parent - * obj->name - * obj->name_len - */ -URET uffs_ParseObject(uffs_Object *obj, const char *name) -{ - int len, m_len, d_len; - uffs_Device *dev; - const char *start, *p, *dname; - u16 dir; - TreeNode *node; - u16 sum; - - if (uffs_ReInitObject(obj) == U_FAIL) - return U_FAIL; - - len = strlen(name); - m_len = uffs_GetMatchedMountPointSize(name); - dev = uffs_GetDeviceFromMountPointEx(name, m_len); - - if (dev) { - start = name + m_len; - d_len = GetDirLengthFromPath(start, len - m_len); - p = start; - obj->dev = dev; - if (m_len == len) { - obj->parent = PARENT_OF_ROOT; - obj->name = NULL; - obj->name_len = 0; - } - else { - dir = ROOT_DIR_SERIAL; - dname = start; - while (p - start < d_len) { - while (*p != '/') p++; - sum = uffs_MakeSum16(dname, p - dname); - node = uffs_TreeFindDirNodeByName(dev, dname, p - dname, sum, dir); - if (node == NULL) { - obj->err = UENOENT; - break; - } - else { - dir = node->u.dir.serial; - p++; // skip the '/' - dname = p; - } - } - obj->parent = dir; - obj->name = start + (d_len > 0 ? d_len + 1 : 0); - obj->name_len = len - (d_len > 0 ? d_len + 1 : 0) - m_len; - } - - if (obj->err != UENOERR) { - uffs_PutDevice(obj->dev); - obj->dev = NULL; - } - } - else { - obj->err = UENOENT; - } - - return (obj->err == UENOERR ? U_SUCC : U_FAIL); -} - - -static void do_ReleaseObjectResource(uffs_Object *obj) -{ - if (obj) { - if (obj->dev) { - if (HAVE_BADBLOCK(obj->dev)) - uffs_BadBlockRecover(obj->dev); - if (obj->dev_lock_count > 0) { - uffs_ObjectDevUnLock(obj); - } - uffs_PutDevice(obj->dev); - obj->dev = NULL; - obj->open_succ = U_FALSE; - } - } -} - -/** - * Open a UFFS object - * - * \param[in|out] obj the object to be open - * \param[in] name the full name of the object - * \param[in] oflag open flag - * - * \return U_SUCC if object is opened successfully, - * U_FAIL if failed, error code will be set to obj->err. - */ -URET uffs_OpenObject(uffs_Object *obj, const char *name, int oflag) -{ - URET ret; - - if (obj == NULL) - return U_FAIL; - - if ((ret = uffs_ParseObject(obj, name)) == U_SUCC) { - ret = uffs_OpenObjectEx(obj, obj->dev, obj->parent, - obj->name, obj->name_len, oflag); - } - if (ret != U_SUCC) - do_ReleaseObjectResource(obj); - - return ret; -} - -static URET do_FlushObject(uffs_Object *obj) -{ - uffs_Device *dev; - URET ret = U_SUCC; - TreeNode *node = NULL; - - dev = obj->dev; - if (obj->node) { - node = obj->node; - if (obj->type == UFFS_TYPE_DIR) - ret = uffs_BufFlushGroup(dev, obj->node->u.dir.parent, - obj->node->u.dir.serial); - else { - ret = ( - uffs_BufFlushGroupMatchParent(dev, obj->node->u.file.serial) == U_SUCC && - uffs_BufFlushGroup(dev, obj->node->u.file.parent, obj->node->u.file.serial) == U_SUCC - ) ? U_SUCC : U_FAIL; - } - uffs_Assert(node == obj->node, "obj->node change!\n"); - } - - return ret; -} - -/** - * Flush object data. - * - * \param[in] obj object to be flushed - * \return U_SUCC or U_FAIL (error code in obj->err). - */ -URET uffs_FlushObject(uffs_Object *obj) -{ - if(obj->dev == NULL || obj->open_succ != U_TRUE) { - obj->err = UEBADF; - goto ext; - } - - uffs_ObjectDevLock(obj); - - if (do_FlushObject(obj) != U_SUCC) - obj->err = UEIOERR; - - uffs_ObjectDevUnLock(obj); - -ext: - return (obj->err == UENOERR ? U_SUCC : U_FAIL); -} - -/** - * Close an openned object. - * - * \param[in] obj object to be closed - * \return U_SUCC or U_FAIL (error code in obj->err). - */ -URET uffs_CloseObject(uffs_Object *obj) -{ -#ifdef CONFIG_CHANGE_MODIFY_TIME - uffs_Device *dev; - uffs_Buf *buf; - uffs_FileInfo fi; -#endif - - if(obj->dev == NULL || obj->open_succ != U_TRUE) { - obj->err = UEBADF; - goto ext; - } - - - uffs_ObjectDevLock(obj); - - if (obj->oflag & (UO_WRONLY|UO_RDWR|UO_APPEND|UO_CREATE|UO_TRUNC)) { - -#ifdef CONFIG_CHANGE_MODIFY_TIME - dev = obj->dev; - if (obj->node) { - //need to change the last modify time stamp - if (obj->type == UFFS_TYPE_DIR) - buf = uffs_BufGetEx(dev, UFFS_TYPE_DIR, obj->node, 0, obj->oflag); - else - buf = uffs_BufGetEx(dev, UFFS_TYPE_FILE, obj->node, 0, obj->oflag); - - if(buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't get file header"); - do_FlushObject(obj); - uffs_ObjectDevUnLock(obj); - goto ext; - } - uffs_BufRead(dev, buf, &fi, 0, sizeof(uffs_FileInfo)); - fi.last_modify = uffs_GetCurDateTime(); - uffs_BufWrite(dev, buf, &fi, 0, sizeof(uffs_FileInfo)); - uffs_BufPut(dev, buf); - } -#endif - do_FlushObject(obj); - } - - uffs_ObjectDevUnLock(obj); - -ext: - do_ReleaseObjectResource(obj); - - return (obj->err == UENOERR ? U_SUCC : U_FAIL); -} - -static u16 GetFdnByOfs(uffs_Object *obj, u32 ofs) -{ - uffs_Device *dev = obj->dev; - - if (ofs < (u32)(obj->head_pages * dev->com.pg_data_size)) { - return 0; - } - else { - ofs -= obj->head_pages * dev->com.pg_data_size; - return (ofs / (dev->com.pg_data_size * dev->attr->pages_per_block)) + 1; - } -} - - -static u32 GetStartOfDataBlock(uffs_Object *obj, u16 fdn) -{ - if (fdn == 0) { - return 0; - } - else { - return (obj->head_pages * obj->dev->com.pg_data_size) + - (fdn - 1) * (obj->dev->com.pg_data_size * - obj->dev->attr->pages_per_block); - } -} - - -static int do_WriteNewBlock(uffs_Object *obj, - const void *data, u32 len, - u16 parent, - u16 serial) -{ - uffs_Device *dev = obj->dev; - u16 page_id; - int wroteSize = 0; - int size; - uffs_Buf *buf; - URET ret; - - for (page_id = 0; page_id < dev->attr->pages_per_block; page_id++) { - size = (len - wroteSize) > dev->com.pg_data_size ? - dev->com.pg_data_size : len - wroteSize; - if (size <= 0) - break; - - buf = uffs_BufNew(dev, UFFS_TYPE_DATA, parent, serial, page_id); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't create a new page ?"); - break; - } - // Note: if data == NULL, we will fill '\0' - ret = uffs_BufWrite(dev, buf, data == NULL ? NULL : (u8 *)data + wroteSize, 0, size); - uffs_BufPut(dev, buf); - - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "write data fail!"); - break; - } - wroteSize += size; - obj->node->u.file.len += size; - } - - return wroteSize; -} - -static int do_WriteInternalBlock(uffs_Object *obj, - TreeNode *node, - u16 fdn, - const void *data, - u32 len, - u32 blockOfs) -{ - uffs_Device *dev = obj->dev; - u16 maxPageID; - u16 page_id; - u32 size; - u32 pageOfs; - u32 wroteSize = 0; - URET ret; - uffs_Buf *buf; - u32 block_start; - u8 type; - u16 parent, serial; - - block_start = GetStartOfDataBlock(obj, fdn); - - if (fdn == 0) { - type = UFFS_TYPE_FILE; - parent = node->u.file.parent; - serial = node->u.file.serial; - } - else { - type = UFFS_TYPE_DATA; - parent = node->u.data.parent; - serial = fdn; - } - - if (fdn == 0) - maxPageID = obj->head_pages; - else - maxPageID = dev->attr->pages_per_block - 1; - - - while (wroteSize < len) { - page_id = blockOfs / dev->com.pg_data_size; - if (fdn == 0) - page_id++; //in file header, page_id start from 1, not 0. - if (page_id > maxPageID) - break; - - pageOfs = blockOfs % dev->com.pg_data_size; - size = (len - wroteSize + pageOfs) > dev->com.pg_data_size ? - (dev->com.pg_data_size - pageOfs) : (len - wroteSize); - - if ((obj->node->u.file.len % dev->com.pg_data_size) == 0 && - (blockOfs + block_start) == obj->node->u.file.len) { - - buf = uffs_BufNew(dev, type, parent, serial, page_id); - - if(buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can create a new buf!"); - break; - } - } - else { - buf = uffs_BufGetEx(dev, type, node, page_id, obj->oflag); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't get buffer ?"); - break; - } - } - - // Note: if data == NULL, then we will fill '\0' - ret = uffs_BufWrite(dev, buf, data == NULL ? NULL : (u8 *)data + wroteSize, pageOfs, size); - - uffs_BufPut(dev, buf); - - if (ret == U_FAIL) { - uffs_Perror(UFFS_MSG_SERIOUS, "write inter data fail!"); - break; - } - - wroteSize += size; - blockOfs += size; - - if (block_start + blockOfs > obj->node->u.file.len) - obj->node->u.file.len = block_start + blockOfs; - - } - - return wroteSize; -} - - -/** - * write data to obj, return remain data (0 if all data been written). - */ -static int do_WriteObject(uffs_Object *obj, const void *data, int len) -{ - uffs_Device *dev = obj->dev; - TreeNode *fnode = obj->node; - int remain = len; - u16 fdn; - u32 write_start; - TreeNode *dnode; - u32 size; - - while (remain > 0) { - write_start = obj->pos + len - remain; - if (write_start > fnode->u.file.len) { - uffs_Perror(UFFS_MSG_SERIOUS, "write point out of file ?"); - break; - } - - fdn = GetFdnByOfs(obj, write_start); - - if (write_start == fnode->u.file.len && fdn > 0 && - write_start == GetStartOfDataBlock(obj, fdn)) { - if (dev->tree.erased_count < dev->cfg.reserved_free_blocks) { - uffs_Perror(UFFS_MSG_NOISY, "insufficient block in write obj, new block"); - break; - } - size = do_WriteNewBlock(obj, data ? (u8 *)data + len - remain : NULL, - remain, fnode->u.file.serial, fdn); - - // - // Flush the new block buffers immediately, so that the new data node will be - // created and put in the tree. - // - // But before do that, we need to make sure the previous - // data block (if exist) been flushed first. - // - if (fdn > 1) { - uffs_BufFlushGroup(dev, fnode->u.file.serial, fdn - 1); - } - else { - uffs_BufFlushGroup(dev, fnode->u.file.parent, fnode->u.file.serial); - } - // Now flush the new block. - uffs_BufFlushGroup(dev, fnode->u.file.serial, fdn); - - if (size == 0) - break; - - remain -= size; - } - else { - - if(fdn == 0) - dnode = obj->node; - else - dnode = uffs_TreeFindDataNode(dev, fnode->u.file.serial, fdn); - - if(dnode == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't find data node in tree ?"); - obj->err = UEUNKNOWN_ERR; - break; - } - size = do_WriteInternalBlock(obj, dnode, fdn, - data ? (u8 *)data + len - remain : NULL, remain, - write_start - GetStartOfDataBlock(obj, fdn)); -#ifdef CONFIG_FLUSH_BUF_AFTER_WRITE - if (fdn == 0) - uffs_BufFlushGroup(dev, fnode->u.file.parent, fnode->u.file.serial); - else - uffs_BufFlushGroup(dev, fnode->u.file.serial, fdn); -#endif - if (size == 0) - break; - - remain -= size; - } - } - - uffs_Assert(fnode == obj->node, "obj->node change!\n"); - - return remain; -} - - -/** - * write data to obj, from obj->pos - * - * \param[in] obj file obj - * \param[in] data data pointer - * \param[in] len length of data to be write - * - * \return bytes wrote to obj - */ -int uffs_WriteObject(uffs_Object *obj, const void *data, int len) -{ - uffs_Device *dev = obj->dev; - TreeNode *fnode = NULL; - int remain; - u32 pos; - int wrote = 0; - - if (obj == NULL) - return 0; - - if (obj->dev == NULL || obj->open_succ != U_TRUE) { - obj->err = UEBADF; - return 0; - } - - if (obj->type == UFFS_TYPE_DIR) { - uffs_Perror(UFFS_MSG_NOISY, "Can't write to an dir object!"); - obj->err = UEACCES; - return 0; - } - - if (obj->oflag == UO_RDONLY) { - obj->err = UEACCES; // can't write to 'read only' mode opened file - return 0; - } - - fnode = obj->node; - - uffs_ObjectDevLock(obj); - - if (obj->oflag & UO_APPEND) - obj->pos = fnode->u.file.len; - else { - if (obj->pos > fnode->u.file.len) { - // current pos pass over the end of file, need to fill the gap with '\0' - pos = obj->pos; // save desired pos - obj->pos = fnode->u.file.len; // filling gap from the end of the file. - remain = do_WriteObject(obj, NULL, pos - fnode->u.file.len); // Write filling bytes. Note: the filling data does not count as 'wrote' in this write operation. - obj->pos = pos - remain; - if (remain > 0) // fail to fill the gap ? stop. - goto ext; - } - } - - remain = do_WriteObject(obj, data, len); - wrote = len - remain; - obj->pos += wrote; - -ext: - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockRecover(dev); - - uffs_ObjectDevUnLock(obj); - - uffs_Assert(fnode == obj->node, "obj->node change!\n"); - - return wrote; -} - -/** - * read data from obj - * - * \param[in] obj uffs object - * \param[out] data output data buffer - * \param[in] len required length of data to be read from object->pos - * - * \return return bytes of data have been read - */ -int uffs_ReadObject(uffs_Object *obj, void *data, int len) -{ - uffs_Device *dev = obj->dev; - TreeNode *fnode = NULL; - u32 remain = len; - u16 fdn; - u32 read_start; - TreeNode *dnode; - u32 size; - uffs_Buf *buf; - u32 blockOfs; - u16 page_id; - u8 type; - u32 pageOfs; - - if (obj == NULL) - return 0; - - fnode = obj->node; - - if (obj->dev == NULL || obj->open_succ == U_FALSE) { - obj->err = UEBADF; - return 0; - } - - if (obj->type == UFFS_TYPE_DIR) { - uffs_Perror(UFFS_MSG_NOISY, "Can't read data from a dir object!"); - obj->err = UEBADF; - return 0; - } - - if (obj->pos > fnode->u.file.len) { - return 0; //can't read file out of range - } - - if (obj->oflag & UO_WRONLY) { - obj->err = UEACCES; - return 0; - } - - uffs_ObjectDevLock(obj); - - while (remain > 0) { - read_start = obj->pos + len - remain; - if (read_start >= fnode->u.file.len) { - //uffs_Perror(UFFS_MSG_NOISY, "read point out of file ?"); - break; - } - - fdn = GetFdnByOfs(obj, read_start); - if (fdn == 0) { - dnode = obj->node; - type = UFFS_TYPE_FILE; - } - else { - type = UFFS_TYPE_DATA; - dnode = uffs_TreeFindDataNode(dev, fnode->u.file.serial, fdn); - if (dnode == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't get data node in entry!"); - obj->err = UEUNKNOWN_ERR; - break; - } - } - - blockOfs = GetStartOfDataBlock(obj, fdn); - page_id = (read_start - blockOfs) / dev->com.pg_data_size; - - if (fdn == 0) { - /** - * fdn == 0: this means that the reading is start from the first block, - * since the page 0 is for file attr, so we move to the next page ID. - */ - page_id++; - } - - buf = uffs_BufGetEx(dev, type, dnode, (u16)page_id, obj->oflag); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't get buffer when read obj."); - obj->err = UEIOERR; - break; - } - - pageOfs = read_start % dev->com.pg_data_size; - if (pageOfs >= buf->data_len) { - //uffs_Perror(UFFS_MSG_NOISY, "read data out of page range ?"); - uffs_BufPut(dev, buf); - break; - } - size = (remain + pageOfs > buf->data_len ? buf->data_len - pageOfs : remain); - - uffs_BufRead(dev, buf, (u8 *)data + len - remain, pageOfs, size); - uffs_BufPut(dev, buf); - - remain -= size; - } - - obj->pos += (len - remain); - - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockRecover(dev); - - uffs_ObjectDevUnLock(obj); - - uffs_Assert(fnode == obj->node, "obj->node change!\n"); - - return len - remain; -} - -/** - * move the file pointer - * - * \param[in] obj uffs object - * \param[in] offset offset from origin - * \param[in] origin the origin position, one of: - * #USEEK_CUR, #USEEK_SET or #USEEK_END - * - * \return the new file pointer position if success, - * or -1 if the new position would be negative. - */ -long uffs_SeekObject(uffs_Object *obj, long offset, int origin) -{ - if (obj->type == UFFS_TYPE_DIR) { - uffs_Perror(UFFS_MSG_NOISY, "Can't seek a dir object!"); - obj->err = UEACCES; - } - else { - uffs_ObjectDevLock(obj); - switch (origin) { - case USEEK_CUR: - if ((long)obj->pos + offset < 0) { - obj->err = UEINVAL; - } - else { - obj->pos += offset; - } - break; - case USEEK_SET: - if (offset < 0) { - obj->err = UEINVAL; - } - else { - obj->pos = offset; - } - break; - case USEEK_END: - if ((long)obj->node->u.file.len + offset < 0) { - obj->err = UEINVAL; - } - else { - obj->pos = obj->node->u.file.len + offset; - } - break; - } - uffs_ObjectDevUnLock(obj); - } - - return (obj->err == UENOERR ? (long)obj->pos : -1); -} - -/** - * get current file pointer - * - * \param[in] obj uffs object - * - * \return return the file pointer position if the obj is valid, - * return -1 if obj is invalid. - */ -int uffs_GetCurOffset(uffs_Object *obj) -{ - if (obj) { - if (obj->dev && obj->open_succ == U_TRUE) - return obj->pos; - } - return -1; -} - -/** - * check whether the file pointer is at the end of file - * - * \param[in] obj uffs object - * - * \return return 1 if file pointer is at the end of file, - * return -1 if error occur, else return 0. - */ -int uffs_EndOfFile(uffs_Object *obj) -{ - if (obj) { - if (obj->dev && obj->type == UFFS_TYPE_FILE && obj->open_succ == U_TRUE) { - if (obj->pos >= obj->node->u.file.len) { - return 1; - } - else { - return 0; - } - } - } - - return -1; -} - -// -// To trancate the file, this is the last block to be trancated. -// We need to discard one or more pages within this block, hence requires 'block recover'. -// -static URET do_TruncateInternalWithBlockRecover(uffs_Object *obj, - u16 fdn, u32 remain, RunOptionE run_opt) -{ - uffs_Device *dev = obj->dev; - TreeNode *fnode = obj->node; - u16 page_id, max_page_id; - TreeNode *node; - uffs_Buf *buf = NULL; - u8 type; - u32 block_start; - u16 parent, serial; - int slot; - uffs_BlockInfo *bc = NULL; - int block = -1; - - if (fdn == 0) { - node = fnode; - type = UFFS_TYPE_FILE; - max_page_id = obj->head_pages; - block_start = 0; - parent = node->u.file.parent; - serial = node->u.file.serial; - block = node->u.file.block; - } - else { - node = uffs_TreeFindDataNode(dev, fnode->u.file.serial, fdn); - if (node == NULL) { - obj->err = UEIOERR; - uffs_Perror(UFFS_MSG_SERIOUS, - "can't find data node when truncate obj"); - goto ext; - } - block = node->u.data.block; - type = UFFS_TYPE_DATA; - max_page_id = dev->attr->pages_per_block - 1; - block_start = obj->head_pages * dev->com.pg_data_size + - (fdn - 1) * dev->com.pg_data_size * - dev->attr->pages_per_block; - parent = node->u.data.parent; - serial = node->u.data.serial; - } - - if (run_opt == eDRY_RUN) { - // checking the buffer. this is the main reason why we need the 'dry run' mode. - for (page_id = 0; page_id <= max_page_id; page_id++) { - buf = uffs_BufFind(dev, parent, serial, page_id); - if (buf) { - //!< ok, the buffer was loaded before ... - if (uffs_BufIsFree(buf) == U_FALSE) { - obj->err = UEEXIST; - break; //!< and someone is still holding the buffer, - // can't truncate it !!! - } - } - } - buf = NULL; - goto ext; - } - - // find the last page *after* truncate - for (page_id = (fdn == 0 ? 1 : 0); page_id <= max_page_id; page_id++) { - if (block_start + (page_id + 1) * dev->com.pg_data_size >= remain) - break; - } - - if (!uffs_Assert(page_id <= max_page_id, "fdn = %d, block_start = %d, remain = %d\n", fdn, block_start, remain)) { - obj->err = UEUNKNOWN_ERR; - goto ext; - } - - // flush buffer before performing block recovery - uffs_BufFlushGroup(dev, parent, serial); - - // load the last page - buf = uffs_BufGetEx(dev, type, node, page_id, obj->oflag); - if (buf == NULL) { - obj->err = UENOMEM; - uffs_Perror(UFFS_MSG_SERIOUS, "Can't get buf"); - goto ext; - } - - uffs_BufWrite(dev, buf, NULL, 0, 0); // just make this buf dirty - - // lock the group - slot = uffs_BufFindGroupSlot(dev, parent, serial); - uffs_BufLockGroup(dev, slot); - - if (remain == 0) // remain == 0: means discard all data in this block. - buf->data_len = 0; - else { - remain = (remain % dev->com.pg_data_size); - // remain == 0: means that we need to keep all data in this page. - buf->data_len = (remain == 0 ? dev->com.pg_data_size : remain); - } - - /* mark this buf as UFFS_BUF_EXT_MARK_TRUNC_TAIL, when flushing - dirty buffers, UFFS will not do page recover for pages after - this buf page id (because this file is ended at this page) */ - buf->ext_mark |= UFFS_BUF_EXT_MARK_TRUNC_TAIL; - - uffs_BufPut(dev, buf); - - // invalidate the rest page buf - page_id++; - for (; page_id <= max_page_id; page_id++) { - buf = uffs_BufFind(dev, parent, serial, page_id); - if (buf) - uffs_BufMarkEmpty(dev, buf); - } - - // flush dirty buffer immediately, forcing block recovery. - uffs_BufFlushGroupEx(dev, parent, serial, U_TRUE); - - // unlock the group - uffs_BufUnLockGroup(dev, slot); - - // Invalidate block info cache for the 'old' block - bc = uffs_BlockInfoGet(dev, block); - if (bc) { - uffs_BlockInfoExpire(dev, bc, UFFS_ALL_PAGES); - uffs_BlockInfoPut(dev, bc); - } - -ext: - return (obj->err == UENOERR ? U_SUCC : U_FAIL); -} - -/** - * truncate an object - * - * \param[in] obj object to be truncated - * \param[in] remain data bytes to be remained in this object - * - * \return U_SUCC or U_FAIL (error code in obj->err) - */ -URET uffs_TruncateObject(uffs_Object *obj, u32 remain) -{ - uffs_ObjectDevLock(obj); - if (do_TruncateObject(obj, remain, eDRY_RUN) == U_SUCC) - do_TruncateObject(obj, remain, eREAL_RUN); - uffs_ObjectDevUnLock(obj); - - uffs_FlushObject(obj); - - return (obj->err == UENOERR ? U_SUCC : U_FAIL); -} - -/** truncate obj without lock device */ -static URET do_TruncateObject(uffs_Object *obj, u32 remain, RunOptionE run_opt) -{ - uffs_Device *dev = obj->dev; - TreeNode *fnode = obj->node; - u16 fdn; - u32 flen; - u32 block_start; - TreeNode *node; - uffs_BlockInfo *bc; - uffs_Buf *buf; - u16 page; - int pos; - - pos = obj->pos; // save current file position - - if (obj->dev == NULL || obj->open_succ == U_FALSE || fnode == NULL) { - obj->err = UEBADF; - goto ext; - } - - /* can't truncate a dir */ - /* TODO: delete files under dir ? */ - if (obj->type == UFFS_TYPE_DIR) { - obj->err = UEEXIST; - goto ext; - } - - if (remain >= fnode->u.file.len) { - goto ext; //!< nothing to do ... - } - - flen = fnode->u.file.len; - - if (flen < remain) { - // file is shorter than 'reamin', fill the gap with '\0' - if (run_opt == eREAL_RUN) { - obj->pos = flen; // move file pointer to the end - if (do_WriteObject(obj, NULL, remain - flen) > 0) { // fill '\0' ... - uffs_Perror(UFFS_MSG_SERIOUS, "Write object not finished. expect %d but only %d wrote.", - remain - flen, fnode->u.file.len - flen); - obj->err = UEIOERR; // likely be an I/O error. - } - flen = obj->node->u.file.len; - } - } - else { - while (flen > remain) { - fdn = GetFdnByOfs(obj, flen - 1); - - //uffs_BufFlushGroup(dev, obj->serial, fdn); //!< flush the buffer - - block_start = GetStartOfDataBlock(obj, fdn); - if (remain <= block_start && fdn > 0) { - node = uffs_TreeFindDataNode(dev, obj->serial, fdn); - if (node == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "can't find data node when trancate obj."); - obj->err = UEIOERR; - goto ext; - } - bc = uffs_BlockInfoGet(dev, node->u.data.block); - if (bc == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "can't get block info when trancate obj."); - obj->err = UEIOERR; - goto ext; - } - - for (page = 0; page < dev->attr->pages_per_block; page++) { - buf = uffs_BufFind(dev, fnode->u.file.serial, fdn, page); - if (buf) { - //!< ok, the buffer was loaded before ... - if (uffs_BufIsFree(buf) == U_FALSE) { - uffs_BlockInfoPut(dev, bc); - goto ext; //!< and someone is still holding the buffer, - // can't truncate it !!! - } - else if (run_opt == eREAL_RUN) - uffs_BufMarkEmpty(dev, buf); //!< discard the buffer - } - } - - if (run_opt == eREAL_RUN) { - uffs_BreakFromEntry(dev, UFFS_TYPE_DATA, node); - uffs_FlashEraseBlock(dev, bc->block); - node->u.list.block = bc->block; - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, node); - else - uffs_TreeInsertToErasedListTail(dev, node); - - fnode->u.file.len = block_start; - } - - flen = block_start; - uffs_BlockInfoPut(dev, bc); - } - else { - if (do_TruncateInternalWithBlockRecover(obj, fdn, - remain, run_opt) == U_SUCC) { - if (run_opt == eREAL_RUN) - fnode->u.file.len = remain; - flen = remain; - } - } - } - } - - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockRecover(dev); -ext: - obj->pos = pos; // keep file pointer offset not changed. - - uffs_Assert(fnode == obj->node, "obj->node change!\n"); - - return (obj->err == UENOERR ? U_SUCC : U_FAIL); - -} - -/** - * \brief check if there are anyone holding buf of this obj. - * If no one holding the buffers, expire the buffer. - * \return - * 0 : no one holding any buf of this obj - * >0 : the ref_count of buf which refer to this obj. - */ -int _CheckObjBufRef(uffs_Object *obj) -{ - uffs_Device *dev = obj->dev; - uffs_Buf *buf; - TreeNode *node = obj->node; - u16 parent, serial, last_serial; - - // check the DIR or FILE block - for (buf = uffs_BufFind(dev, obj->parent, obj->serial, UFFS_ALL_PAGES); - buf != NULL; - buf = uffs_BufFindFrom(dev, buf->next, obj->parent, obj->serial, UFFS_ALL_PAGES)) - { - if (buf->ref_count > 0) { - // oops ... - uffs_Perror(UFFS_MSG_SERIOUS, "someone still hold buf parent = %d, serial = %d, ref_count", - obj->parent, obj->serial, buf->ref_count); - - return buf->ref_count; - } - else { - buf->mark = UFFS_BUF_EMPTY; - } - } - - if (buf == NULL || buf->ref_count == 0) { - // check the DATA block - if (obj->type == UFFS_TYPE_FILE && node->u.file.len > 0) { - - parent = obj->serial; - last_serial = GetFdnByOfs(obj, node->u.file.len - 1); - for (serial = 1; serial <= last_serial; serial++) { - - for (buf = uffs_BufFind(dev, parent, serial, UFFS_ALL_PAGES); - buf != NULL; - buf = uffs_BufFindFrom(dev, buf->next, parent, serial, UFFS_ALL_PAGES)) - { - if (buf->ref_count != 0) { - // oops ... - uffs_Perror(UFFS_MSG_SERIOUS, "someone still hold buf parent = %d, serial = %d, ref_count", - parent, serial, buf->ref_count); - - return buf->ref_count; - } - else { - buf->mark = UFFS_BUF_EMPTY; - } - } - } - } - } - - return 0; -} - - - -/** - * \brief delete uffs object - * - * \param[in] name full name of object - * \param[out] err return error code - * - * \return U_SUCC if object is deleted successfully. - * return U_FAIL if error happen, error code is set to *err. - */ -URET uffs_DeleteObject(const char * name, int *err) -{ - uffs_Object *obj, *work; - TreeNode *node, *d_node; - uffs_Device *dev = NULL; - u16 block; - u16 serial, parent, last_serial; - UBOOL bad = U_FALSE; - URET ret = U_FAIL; - - obj = uffs_GetObject(); - if (obj == NULL) { - if (err) - *err = UEMFILE; - goto ext_unlock; - } - - if (uffs_OpenObject(obj, name, UO_RDWR|UO_DIR) == U_FAIL) { - if (uffs_OpenObject(obj, name, UO_RDWR) == U_FAIL) { - if (err) - *err = UENOENT; - goto ext_unlock; - } - } - - dev = obj->dev; - - // working throught object pool see if the object is opened ... - uffs_ObjectDevLock(obj); - work = NULL; - while ((work = (uffs_Object *)uffs_PoolFindNextAllocated(&_object_pool, work)) != NULL) { - if (work != obj && - work->dev && - work->dev == obj->dev && - work->node && - work->node == obj->node) { - // this object is opened, can't delete it. - if (err) - *err = UEACCES; - goto ext_lock; - } - } - - if (obj->type == UFFS_TYPE_DIR) { - // if the dir is not empty, can't delete it. - node = uffs_TreeFindDirNodeWithParent(dev, obj->serial); - if (node != NULL) { - if (err) - *err = UEACCES; - goto ext_lock; //have sub dirs ? - } - - node = uffs_TreeFindFileNodeWithParent(dev, obj->serial); - if (node != NULL) { - if (err) - *err = UEACCES; - goto ext_lock; //have sub files ? - } - } - - // before erase the block, we need to take care of the buffer ... - uffs_BufFlushAll(dev); - - if (_CheckObjBufRef(obj) > 0) { - if (err) - *err = UEACCES; - goto ext_lock; - } - - node = obj->node; - - // ok, now we are safe to erase DIR/FILE block :-) - block = GET_BLOCK_FROM_NODE(obj); - parent = obj->serial; - last_serial = (obj->type == UFFS_TYPE_FILE && node->u.file.len > 0 ? GetFdnByOfs(obj, node->u.file.len - 1) : 0); - - uffs_BreakFromEntry(dev, obj->type, node); - uffs_FlashEraseBlock(dev, block); - node->u.list.block = block; - node->u.list.u.serial = obj->serial; - - // From now on, the object is gone physically, - // but we need to 'suspend' this node so that no one will re-use - // the serial number during deleting the reset part of object. - - if (HAVE_BADBLOCK(dev)) { - uffs_BadBlockProcessSuspend(dev, node); - bad = U_TRUE; // will be put into 'bad' list later - } - else { - uffs_TreeSuspendAdd(dev, node); - bad = U_FALSE; // will be put into erased list later - } - - // now erase DATA blocks - if (obj->type == UFFS_TYPE_FILE && last_serial > 0) { - for (serial = 1; serial <= last_serial; serial++) { - - uffs_ObjectDevUnLock(obj); - ; // yield CPU to improve responsive when deleting large file. - uffs_ObjectDevLock(obj); - - d_node = uffs_TreeFindDataNode(dev, parent, serial); - if (uffs_Assert(d_node != NULL, "Can't find DATA node parent = %d, serial = %d\n", parent, serial)) { - uffs_BreakFromEntry(dev, UFFS_TYPE_DATA, d_node); - block = d_node->u.data.block; - uffs_FlashEraseBlock(dev, block); - d_node->u.list.block = block; - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, d_node); - else - uffs_TreeInsertToErasedListTail(dev, d_node); - } - } - } - - // now process the suspend node - uffs_TreeRemoveSuspendNode(dev, node); - if (bad) - uffs_TreeInsertToBadBlockList(dev, node); - else - uffs_TreeInsertToErasedListTail(dev, node); - - ret = U_SUCC; - -ext_lock: - uffs_ObjectDevUnLock(obj); -ext_unlock: - do_ReleaseObjectResource(obj); - - uffs_PutObject(obj); - - return ret; -} - -/** - * Remove object under a new parent, change object name. - * - * \param[in|out] obj - * \param[in] new_parent new parent's serial number - * \param[in] new_name new name of the object. - * if new_name == NULL, keep the old name. - * \param[in] name_len new name length. - * - * \return U_SUCC or U_FAIL (obj->err for the reason) - */ -URET uffs_MoveObjectEx(uffs_Object *obj, - int new_parent, const char *new_name, int name_len) -{ - uffs_Buf *buf; - uffs_FileInfo fi; - uffs_Device *dev = obj->dev; - TreeNode *node = obj->node; - - if (dev == NULL || node == NULL || obj->open_succ != U_TRUE) { - obj->err = UEBADF; - goto ext; - } - - uffs_ObjectDevLock(obj); - - obj->parent = new_parent; - - if (name_len > 0) { - - buf = uffs_BufGetEx(dev, obj->type, node, 0, obj->oflag); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't get buf when rename!"); - obj->err = UEIOERR; - goto ext_1; - } - - memcpy(&fi, buf->data, sizeof(uffs_FileInfo)); - - if (new_name[name_len-1] == '/') - name_len--; - - memcpy(fi.name, new_name, name_len); - fi.name[name_len] = 0; - fi.name_len = name_len; - fi.last_modify = uffs_GetCurDateTime(); - - buf->parent = new_parent; // !! need to manually change the 'parent' !! - uffs_BufWrite(dev, buf, &fi, 0, sizeof(uffs_FileInfo)); - uffs_BufPut(dev, buf); - - // !! force a block recover so that all old tag will be expired !! - // This is important so we only need to check - // the first spare when mount UFFS :) - uffs_BufFlushGroupEx(dev, obj->parent, obj->serial, U_TRUE); - - obj->name = new_name; - obj->name_len = name_len; - obj->sum = uffs_MakeSum16(fi.name, fi.name_len); - } - - //update the check sum and new parent of tree node - if (obj->type == UFFS_TYPE_DIR) { - obj->node->u.dir.checksum = obj->sum; - obj->node->u.dir.parent = new_parent; - } - else { - obj->node->u.file.checksum = obj->sum; - obj->node->u.file.parent = new_parent; - } - -ext_1: - uffs_ObjectDevUnLock(obj); -ext: - - return (obj->err == UENOERR ? U_SUCC : U_FAIL); -} - -/** - * \brief rename(move) file or dir. - * \return U_SUCC if success, otherwise return U_FAIL and set error code to *err. - * \note rename/move file between different mount point is not allowed. - */ -URET uffs_RenameObject(const char *old_name, const char *new_name, int *err) -{ - uffs_Object *obj = NULL, *new_obj = NULL; - URET ret = U_FAIL; - int oflag; - - obj = uffs_GetObject(); - new_obj = uffs_GetObject(); - - if (obj == NULL || new_obj == NULL) { - if (err) - *err = UEINVAL; - goto ext; - } - - oflag = UO_RDONLY; - if (uffs_OpenObject(new_obj, new_name, oflag) == U_SUCC) { - uffs_CloseObject(new_obj); - uffs_Perror(UFFS_MSG_NOISY, "new object already exist!"); - if (err) - *err = UEEXIST; - goto ext; - } - oflag |= UO_DIR; - if (uffs_OpenObject(new_obj, new_name, oflag) == U_SUCC) { - uffs_CloseObject(new_obj); - uffs_Perror(UFFS_MSG_NOISY, "new object already exist!"); - if (err) - *err = UEEXIST; - goto ext; - } - - if (uffs_ParseObject(new_obj, new_name) != U_SUCC) { - uffs_Perror(UFFS_MSG_NOISY, "parse new name fail !"); - if (err) - *err = UENOENT; - goto ext; - } - - if (new_obj->name_len == 0) { - uffs_Perror(UFFS_MSG_NOISY, "invalid new name"); - if (err) - *err = UEINVAL; - goto ext; - } - - oflag = UO_RDONLY; - if (uffs_OpenObject(obj, old_name, oflag) != U_SUCC) { - oflag |= UO_DIR; - if (uffs_OpenObject(obj, old_name, oflag) != U_SUCC) { - uffs_Perror(UFFS_MSG_NOISY, "Can't open old object !"); - if (err) - *err = UEACCES; - goto ext; - } - } - - if (obj->dev != new_obj->dev) { - uffs_Perror(UFFS_MSG_NOISY, - "Can't move object between different mount point"); - if (err) - *err = UEACCES; - } - else { - ret = uffs_MoveObjectEx(obj, new_obj->parent, - new_obj->name, new_obj->name_len); - if (ret == U_FAIL && err) - *err = obj->err; - } - - uffs_CloseObject(obj); - -ext: - if (obj) uffs_PutObject(obj); - if (new_obj) { - do_ReleaseObjectResource(new_obj); - uffs_PutObject(new_obj); - } - - return ret; -} - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_init.c b/components/dfs/filesystems/uffs/src/uffs/uffs_init.c deleted file mode 100644 index bc0a5ca893..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_init.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_init.c - * \brief initialize uffs file system device - * \author Ricky Zheng, created 12th May, 2005 - */ - -#include "uffs_config.h" -#include "uffs/uffs_types.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_tree.h" -#include "uffs/uffs_fs.h" -#include "uffs/uffs_badblock.h" -#include "uffs/uffs_utils.h" -#include <string.h> - -#define PFX "init: " - -static URET uffs_InitDeviceConfig(uffs_Device *dev) -{ - if (dev->cfg.dirty_groups == 0) - dev->cfg.dirty_groups = MAX_DIRTY_BUF_GROUPS; - - if (!uffs_Assert(dev->cfg.dirty_groups >= 1 && dev->cfg.dirty_groups <= MAX_DIRTY_BUF_GROUPS, - "invalid config: dirty_groups = %d\n", dev->cfg.dirty_groups)) - return U_FAIL; - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0 - dev->cfg.bc_caches = MAX_CACHED_BLOCK_INFO; - dev->cfg.page_buffers = MAX_PAGE_BUFFERS; - dev->cfg.dirty_pages = MAX_DIRTY_PAGES_IN_A_BLOCK; - dev->cfg.reserved_free_blocks = MINIMUN_ERASED_BLOCK; -#else - if (dev->cfg.bc_caches == 0) - dev->cfg.bc_caches = MAX_CACHED_BLOCK_INFO; - if (dev->cfg.page_buffers == 0) - dev->cfg.page_buffers = MAX_PAGE_BUFFERS; - if (dev->cfg.dirty_pages == 0) - dev->cfg.dirty_pages = MAX_DIRTY_PAGES_IN_A_BLOCK; - if (dev->cfg.reserved_free_blocks == 0) - dev->cfg.reserved_free_blocks = MINIMUN_ERASED_BLOCK; - - if (!uffs_Assert(dev->cfg.page_buffers - CLONE_BUFFERS_THRESHOLD >= 3, "invalid config: page_buffers = %d\n", dev->cfg.page_buffers)) - return U_FAIL; - -#endif - return U_SUCC; -} - -URET uffs_InitDevice(uffs_Device *dev) -{ - URET ret; - - ret = uffs_InitDeviceConfig(dev); - if (ret != U_SUCC) - return U_FAIL; - - if (dev->mem.init) { - if (dev->mem.init(dev) != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "Init memory allocator fail."); - return U_FAIL; - } - } - - memset(&(dev->st), 0, sizeof(uffs_FlashStat)); - - uffs_DeviceInitLock(dev); - uffs_BadBlockInit(dev); - - - if (uffs_FlashInterfaceInit(dev) != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "Can't initialize flash interface !"); - goto fail; - } - - uffs_Perror(UFFS_MSG_NOISY, "init page buf"); - ret = uffs_BufInit(dev, dev->cfg.page_buffers, dev->cfg.dirty_pages); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_DEAD, "Initialize page buffers fail"); - goto fail; - } - uffs_Perror(UFFS_MSG_NOISY, "init block info cache"); - ret = uffs_BlockInfoInitCache(dev, dev->cfg.bc_caches); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_DEAD, "Initialize block info fail"); - goto fail; - } - - ret = uffs_TreeInit(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "fail to init tree buffers"); - goto fail; - } - - ret = uffs_BuildTree(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "fail to build tree"); - goto fail; - } - - return U_SUCC; - -fail: - uffs_DeviceReleaseLock(dev); - - return U_FAIL; -} - -URET uffs_ReleaseDevice(uffs_Device *dev) -{ - URET ret; - - ret = uffs_BlockInfoReleaseCache(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "fail to release block info."); - goto ext; - } - - ret = uffs_BufReleaseAll(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "fail to release page buffers"); - goto ext; - } - - ret = uffs_TreeRelease(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "fail to release tree buffers!"); - goto ext; - } - - ret = uffs_FlashInterfaceRelease(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "fail to release tree buffers!"); - goto ext; - } - - if (dev->mem.release) - ret = dev->mem.release(dev); - - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "fail to release memory allocator!"); - } - - uffs_DeviceReleaseLock(dev); - -ext: - return ret; - -} - -URET uffs_InitFileSystemObjects(void) -{ - if (uffs_InitObjectBuf() == U_SUCC) { - if (uffs_DirEntryBufInit() == U_SUCC) { - uffs_InitGlobalFsLock(); - return U_SUCC; - } - } - - return U_FAIL; -} - -URET uffs_ReleaseFileSystemObjects(void) -{ - if (uffs_ReleaseObjectBuf() == U_SUCC) { - if (uffs_DirEntryBufRelease() == U_SUCC) { - uffs_ReleaseGlobalFsLock(); - return U_SUCC; - } - } - - return U_FAIL; -} diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_mem.c b/components/dfs/filesystems/uffs/src/uffs/uffs_mem.c deleted file mode 100644 index 9763cd7c43..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_mem.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_mem.c - * \brief uffs static memory allocator - * \author Ricky Zheng, created 23th Feb, 2007 - */ - -#include <string.h> -#include "uffs_config.h" -#include "uffs/uffs_types.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_mem.h" - -#define PFX "mem : " - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0 -static void * static_malloc(struct uffs_DeviceSt *dev, unsigned int size) -{ - struct uffs_memAllocatorSt *mem = &dev->mem; - void *p = NULL; - - size += (size % sizeof(long) ? sizeof(long) - (size % sizeof(long)) : 0); - - if (mem->buf_size - mem->pos < (int)size) { - uffs_Perror(UFFS_MSG_SERIOUS, - "Memory alloc failed! (alloc %d, free %d)", - size, mem->buf_size - mem->pos); - } - else { - p = mem->buf_start + mem->pos; - mem->pos += size; - uffs_Perror(UFFS_MSG_NOISY, - "0x%p: Allocated %d, free %d", - p, size, mem->buf_size - mem->pos); - } - - return p; -} - -void uffs_MemSetupStaticAllocator(uffs_MemAllocator *allocator, - void *pool, int size) -{ - allocator->buf_start = (char *)pool; - allocator->buf_size = size; - allocator->pos = 0; - allocator->malloc = static_malloc; - allocator->free = NULL; //never free memory for static memory allocator - - uffs_Perror(UFFS_MSG_NOISY, - "System static memory: %d bytes", allocator->buf_size); - -} - -#endif - - - - - - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_mtb.c b/components/dfs/filesystems/uffs/src/uffs/uffs_mtb.c deleted file mode 100644 index ca7f197249..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_mtb.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_mtb.c - * \brief mount table operations - * \author Ricky Zheng, created 11th July, 2009 - */ -#include "uffs_config.h" -#include "uffs/uffs_types.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_tree.h" -#include "uffs/uffs_mtb.h" -#include "uffs/uffs_fd.h" -#include "uffs/uffs_utils.h" -#include "uffs/uffs_fs.h" -#include <string.h> - -#define PFX "mtb : " - -static struct uffs_MountTableEntrySt *m_head = NULL; // list of mounted entries -static struct uffs_MountTableEntrySt *m_free_head = NULL; // list of unmounted entries - -/** Return mounted entries header */ -uffs_MountTable * uffs_MtbGetMounted(void) -{ - return m_head; -} - -/** Return unmounted entries header */ -uffs_MountTable * uffs_MtbGetUnMounted(void) -{ - return m_free_head; -} - -/** - * \brief Register mount table - * \param mtb mount table entry - * \return 0 succ - * -1 failed (e.g. already registered and mounted) - */ -int uffs_RegisterMountTable(uffs_MountTable *mtb) -{ - uffs_MountTable *work = NULL; - static int dev_num = 0; - - if (mtb == NULL) - return -1; - - for (work = m_head; work; work = work->next) { - if (work == mtb) - return -1; // already mounted ? - } - - for (work = m_free_head; work; work = work->next) { - if (work == mtb) - return 0; // already registered. - } - - /* replace the free head */ - if (m_free_head) - m_free_head->prev = mtb; - mtb->prev = NULL; - mtb->next = m_free_head; - m_free_head = mtb; - - mtb->dev->dev_num = ++dev_num; - - return 0; -} - -/** - * \brief Remove mount entry from the table - * \param mtb mount table entry - * \return 0 removed succ - * -1 entry in used or not in the 'unmounted' list - */ -int uffs_UnRegisterMountTable(uffs_MountTable *mtb) -{ - uffs_MountTable *work = NULL; - - if (mtb == NULL) - return -1; - - for (work = m_head; work; work = work->next) { - if (work == mtb) - return -1; // in the mounted list ? busy, return - } - - for (work = m_free_head; work; work = work->next) { - if (work == mtb) { - // found, remove it from the list - if (work->next) - work->next->prev = work->prev; - if (work->prev) - work->prev->next = work->next; - if (work == m_free_head) - m_free_head = work->next; - - break; - } - } - - return work ? 0 : -1; -} - -static uffs_MountTable * uffs_GetMountTableByMountPoint(const char *mount, uffs_MountTable *head) -{ - uffs_MountTable *work = NULL; - - for (work = head; work; work = work->next) { - if (strcmp(work->mount, mount) == 0) - break; - } - return work; -} - -/** - * \brief mount partition - * \param[in] mount partition mount point - * \return 0 succ - * <0 fail - * - * \note use uffs_RegisterMountTable() register mount entry before you can mount it. - * mount point should ended with '/', e.g. '/sys/' - */ -int uffs_Mount(const char *mount) -{ - uffs_MountTable *mtb; - - if (uffs_GetMountTableByMountPoint(mount, m_head) != NULL) { - uffs_Perror(UFFS_MSG_NOISY, "'%s' already mounted", mount); - return -1; // already mounted ? - } - - mtb = uffs_GetMountTableByMountPoint(mount, m_free_head); - if (mtb == NULL) { - uffs_Perror(UFFS_MSG_NOISY, "'%s' not registered", mount); - return -1; // not registered ? - } - - uffs_Perror(UFFS_MSG_NOISY, - "init device for mount point %s ...", - mtb->mount); - - mtb->dev->par.start = mtb->start_block; - if (mtb->end_block < 0) { - mtb->dev->par.end = - mtb->dev->attr->total_blocks + mtb->end_block; - } - else { - mtb->dev->par.end = mtb->end_block; - } - - if (mtb->dev->Init(mtb->dev) == U_FAIL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "init device for mount point %s fail", - mtb->mount); - return -1; - } - - uffs_Perror(UFFS_MSG_NOISY, "mount partiton: %d,%d", - mtb->dev->par.start, mtb->dev->par.end); - - if (uffs_InitDevice(mtb->dev) != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "init device fail !"); - return -1; - } - - /* now break it from unmounted list */ - if (mtb->prev) - mtb->prev->next = mtb->next; - if (mtb->next) - mtb->next->prev = mtb->prev; - if (m_free_head == mtb) - m_free_head = mtb->next; - - /* link to mounted list */ - mtb->prev = NULL; - mtb->next = m_head; - if (m_head) - m_head->prev = mtb; - m_head = mtb; - - return 0; -} - -/** - * \brief unmount parttion - * \param[in] mount partition mount point - * \return 0 succ - * <0 fail - */ -int uffs_UnMount(const char *mount) -{ - uffs_MountTable *mtb = uffs_GetMountTableByMountPoint(mount, m_head); - - if (mtb == NULL) { - uffs_Perror(UFFS_MSG_NOISY, "'%s' not mounted ?", mount); - return -1; // not mounted ? - } - - if (uffs_GetMountTableByMountPoint(mount, m_free_head) != NULL) { - uffs_Perror(UFFS_MSG_NOISY, "'%s' already unmounted ?", mount); - return -1; // already unmounted ? - } - - if (mtb->dev->ref_count != 0) { - uffs_Perror(UFFS_MSG_NORMAL, "Can't unmount '%s' - busy", mount); - return -1; - } - - if (uffs_ReleaseDevice(mtb->dev) == U_FAIL) { - uffs_Perror(UFFS_MSG_NORMAL, "Can't release device for mount point '%s'", mount); - return -1; - } - - mtb->dev->Release(mtb->dev); - - // break from mounted list - if (mtb->prev) - mtb->prev->next = mtb->next; - if (mtb->next) - mtb->next->prev = mtb->prev; - if (mtb == m_head) - m_head = mtb->next; - - // put to unmounted list - mtb->prev = NULL; - mtb->next = m_free_head; - if (m_free_head) - m_free_head->prev = mtb; - m_free_head = mtb; - - return 0; -} - -/** - * find the matched mount point from a given full absolute path. - * - * \param[in] path full path - * \return the length of mount point. - */ -int uffs_GetMatchedMountPointSize(const char *path) -{ - int pos; - uffs_Device *dev; - - if (path[0] != '/') - return 0; - - pos = strlen(path); - - while (pos > 0) { - if ((dev = uffs_GetDeviceFromMountPointEx(path, pos)) != NULL ) { - uffs_PutDevice(dev); - return pos; - } - else { - if (path[pos-1] == '/') - pos--; - //back forward search the next '/' - for (; pos > 0 && path[pos-1] != '/'; pos--) - ; - } - } - - return pos; -} - -/** - * get device from mount point. - * - * \param[in] mount mount point name. - * \return NULL if mount point is not found. - */ -uffs_Device * uffs_GetDeviceFromMountPoint(const char *mount) -{ - uffs_MountTable *mtb = uffs_GetMountTableByMountPoint(mount, m_head); - - if (mtb) { - mtb->dev->ref_count++; - return mtb->dev; - } - - return NULL; -} - -/** - * get device from mount point. - * - * \param[in] mount mount point name. - * \param[in] len mount point name length. - * \return NULL if mount point is not found. - */ -uffs_Device * uffs_GetDeviceFromMountPointEx(const char *mount, int len) -{ - uffs_MountTable *work = NULL; - - for (work = m_head; work; work = work->next) { - if (strlen(work->mount) == len && - strncmp(mount, work->mount, len) == 0) { - work->dev->ref_count++; - return work->dev; - } - } - - return NULL; -} - - -/** - * return mount point from device - * - * \param[in] dev uffs device - * \return NULL if mount point is not found, - * otherwise return mount point name in mount table. - */ -const char * uffs_GetDeviceMountPoint(uffs_Device *dev) -{ - uffs_MountTable *work = NULL; - - for (work = m_head; work; work = work->next) { - if (work->dev == dev) { - return work->mount; - } - } - - return NULL; -} - -void uffs_PutDevice(uffs_Device *dev) -{ - dev->ref_count--; -} - - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_pool.c b/components/dfs/filesystems/uffs/src/uffs/uffs_pool.c deleted file mode 100644 index 22adc53f30..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_pool.c +++ /dev/null @@ -1,386 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_pool.c - * \brief Fast fixed size memory pool management. - * \author Ricky Zheng, Simon Kallweit - */ - -#include "uffs_config.h" -#include "uffs/uffs_types.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_pool.h" - -/* - - usage: - - #define BUF_SIZE 32 - #define NUM_BUFS 1024 - - static int pool_mem[NUM_BUFS * BUF_SIZE / sizeof(int)]; - static uffs_Pool pool; - - uffs_PoolInit(&pool, pool_mem, sizeof(pool_mem), BUF_SIZE, NUM_BUFS); - - void * p; - p = uffs_PoolGet(&pool); - ... - uffs_PoolPut(p, &pool); - - notice: - - uffs_PoolInit will assert when NUM_BUFS is not at least 1, or BUF_SIZE is - not aligned to the platforms pointer size. - -*/ - - -/** - * \brief Initializes the memory pool. - * \param[in] pool memory pool - * \param[in] mem pool memory - * \param[in] mem_size size of pool memory - * \param[in] buf_size size of a single buffer - * \param[in] num_bufs number of buffers - * \return Returns U_SUCC if successful. - */ -URET uffs_PoolInit(uffs_Pool *pool, - void *mem, u32 mem_size, u32 buf_size, u32 num_bufs) -{ - unsigned int i; - uffs_PoolEntry *e1, *e2; - - if (!uffs_Assert(pool != NULL, "pool missing") || - !uffs_Assert(mem != NULL, "pool memory missing") || - !uffs_Assert(num_bufs > 0, "not enough buffers") || - !uffs_Assert(buf_size % sizeof(void *) == 0, - "buffer size not aligned to pointer size") || - !uffs_Assert(mem_size == num_bufs * buf_size, - "pool memory size is wrong")) - { - return U_FAIL; - } - - pool->mem = (u8 *)mem; - pool->buf_size = buf_size; - pool->num_bufs = num_bufs; - - uffs_SemCreate(&pool->sem); - uffs_SemWait(pool->sem); - - // Initialize the free_list - e1 = e2 = pool->free_list = (uffs_PoolEntry *) pool->mem; - for (i = 1; i < pool->num_bufs; i++) { - e2 = (uffs_PoolEntry *) (pool->mem + i * pool->buf_size); - e1->next = e2; - e1 = e2; - } - e2->next = NULL; - - uffs_SemSignal(pool->sem); - - return U_SUCC; -} - -/** - * \brief verify pointer validity aganist memory pool - * \return U_TRUE if valid, U_FALSE if invalid. - */ -UBOOL uffs_PoolVerify(uffs_Pool *pool, void *p) -{ - return p && - (u8 *)p >= pool->mem && - (u8 *)p < pool->mem + (pool->buf_size * pool->num_bufs) && - (((u8 *)p - pool->mem) % pool->buf_size) == 0 ? U_TRUE : U_FALSE; -} - -/** - * \brief Releases the memory pool. - * \param[in] pool memory pool - * \return Returns U_SUCC if successful. - */ -URET uffs_PoolRelease(uffs_Pool *pool) -{ - if (!uffs_Assert(pool != NULL, "pool missing")) - return U_FAIL; - - uffs_SemDelete(&pool->sem); - - return U_SUCC; -} - -/** - * \brief Get a buffer from the memory pool. - * \param[in] pool memory pool - * \return Returns a pointer to the buffer or NULL if none is available. - */ -void *uffs_PoolGet(uffs_Pool *pool) -{ - uffs_PoolEntry *e; - - if (!uffs_Assert(pool != NULL, "pool missing")) - return NULL; - - e = pool->free_list; - if (e) - pool->free_list = e->next; - - return e; -} - -/** - * \brief Get a buffer from the memory pool. - * This version is locked and should be used when multiple threads access the - * same memory pool. - * \param[in] pool memory pool - * \return Returns a pointer to the buffer or NULL if none is available. - */ -void *uffs_PoolGetLocked(uffs_Pool *pool) -{ - uffs_PoolEntry *e; - - if (!uffs_Assert(pool != NULL, "pool missing")) - return NULL; - - uffs_SemWait(pool->sem); - e = pool->free_list; - if (e) - pool->free_list = e->next; - uffs_SemSignal(pool->sem); - - return e; -} - -/** - * \brief Puts a buffer back to the memory pool. - * \param[in] pool memory pool - * \param[in] p buffer to put back - * \return Returns 0 if successful. - */ -int uffs_PoolPut(uffs_Pool *pool, void *p) -{ - uffs_PoolEntry *e = (uffs_PoolEntry *)p; - - if (!uffs_Assert(pool != NULL, "pool missing")) - return -1; - - if (e) { - e->next = pool->free_list; - pool->free_list = e; - return 0; - } - - return -1; -} - -/** - * \brief Puts a buffer back to the memory pool. - * This version is locked and should be used when multiple threads access the - * same memory pool. - * \param[in] pool memory pool - * \param[in] p buffer to put back - * \return Returns 0 if successful. - */ -int uffs_PoolPutLocked(uffs_Pool *pool, void *p) -{ - uffs_PoolEntry *e = (uffs_PoolEntry *)p; - - if (!uffs_Assert(pool != NULL, "pool missing")) - return -1; - - if (e) { - uffs_SemWait(pool->sem); - e->next = pool->free_list; - pool->free_list = e; - uffs_SemSignal(pool->sem); - return 0; - } - - return -1; -} - -/** - * \brief Gets a buffer by index (offset). - * This method returns a buffer from the memory pool by index. - * \param[in] pool memory pool - * \param[in] index index - * \return Returns a pointer to the buffer. - */ -void *uffs_PoolGetBufByIndex(uffs_Pool *pool, u32 index) -{ - if (!uffs_Assert(pool != NULL, "pool missing") || - !uffs_Assert(index < pool->num_bufs, - "index(%d) out of range(max %d)", index, pool->num_bufs)) - { - return NULL; - } - - return (u8 *) pool->mem + index * pool->buf_size; -} - -/** - * \brief Gets the index (offset) of a buffer. - * This method returns the index of a buffer from the memory pool. - * \param[in] pool memory pool - * \param[in] p buffer to get index from - * \return Returns the index of the buffer. - */ -u32 uffs_PoolGetIndex(uffs_Pool *pool, void *p) -{ - if (!uffs_Assert(pool != NULL, "pool missing") || - !uffs_Assert(p >= (void *) pool->mem && - p < (void *) (pool->mem + pool->num_bufs * pool->buf_size), - "pointer out of range")) - { - uffs_Panic(); - } - - return ((u8 *) p - pool->mem) / pool->buf_size; -} - -/** - * \brief Check given buffer in free list - * \return U_TRUE if it's in free list, U_FALSE if not. - */ -UBOOL uffs_PoolCheckFreeList(uffs_Pool *pool, void *p) -{ - uffs_PoolEntry *e; - for (e = pool->free_list; e; e = e->next) { - if ((void *)e == p) - return U_TRUE; - } - return U_FALSE; -} - -/** - * \brief this is more efficient version for small nodes number memory pool (< 32) - */ -static void * FindNextAllocatedInSmallPool(uffs_Pool *pool, void *from) -{ - u32 map = 0; - uffs_PoolEntry *e; - u32 i; - - for (e = pool->free_list; e; e = e->next) - map |= (1 << uffs_PoolGetIndex(pool, e)); - - for (i = uffs_PoolGetIndex(pool, from); - (map & (1 << i)) && i < 32 && i < pool->num_bufs; - i++); - - return i < 32 && i < pool->num_bufs ? - uffs_PoolGetBufByIndex(pool, i) : NULL; -} - - -/** - * \brief Find next allocated memory block - * - * \param[in] pool memory pool - * \param[in] from search start address, if NULL, from pool->mem - * - * \return next allocated memory block, NULL if not found. - * - * \note This is NOT efficient, don't do it on a pool with large free nodes ! - */ -void * uffs_PoolFindNextAllocated(uffs_Pool *pool, void *from) -{ - uffs_PoolEntry *e = NULL; - u8 *p = (u8 *)from; - - if (p == NULL) - p = pool->mem; - else - p += pool->buf_size; - - if (pool->num_bufs < 32) - return FindNextAllocatedInSmallPool(pool, p); - - // work through the free list, stop if not in free list, - // otherwise move to next entry and search free list again. - - if (pool->free_list) { - while (uffs_PoolVerify(pool, p)) { - e = pool->free_list; - while (e) { - if (p == (u8 *)e) { - p += pool->buf_size; // in free list, move to next entry - break; - } - e = e->next; - } - if (e == NULL) // not in free_list, gotcha - break; - } - } - - return uffs_PoolVerify(pool, p) ? p : NULL ; -} - -/** - * \brief get free memory block count - */ -int uffs_PoolGetFreeCount(uffs_Pool *pool) -{ - int count = 0; - uffs_PoolEntry *e; - - e = pool->free_list; - while (e) { - count++; - e = e->next; - } - - return count; -} - -/** - * \brief put all memory block back, return how many memory blocks were put back - */ -int uffs_PoolPutAll(uffs_Pool *pool) -{ - void *p = NULL; - int count = 0; - - do { - p = uffs_PoolFindNextAllocated(pool, p); - if (p) { - uffs_PoolPut(pool, p); - count++; - } - } while (p); - - return count; -} diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_public.c b/components/dfs/filesystems/uffs/src/uffs/uffs_public.c deleted file mode 100644 index 348b7892d3..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_public.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_public.c - * \brief public and miscellaneous functions - * \author Ricky Zheng, created 10th May, 2005 - */ - -#include "uffs_config.h" -#include "uffs/uffs_types.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_crc.h" - -#include <string.h> - -#define PFX "pub : " - - -int uffs_GetFirstBlockTimeStamp(void) -{ - return 0; -} - -int uffs_GetNextBlockTimeStamp(int prev) -{ - return (prev + 1) % 3; -} - -UBOOL uffs_IsSrcNewerThanObj(int src, int obj) -{ - switch (src - obj) { - case 0: - uffs_Perror(UFFS_MSG_SERIOUS, - "the two block have the same time stamp ?"); - break; - case 1: - case -2: - return U_TRUE; - case -1: - case 2: - return U_FALSE; - default: - uffs_Perror(UFFS_MSG_SERIOUS, "time stamp out of range !"); - break; - } - - return U_FALSE; -} - - -/** - * \brief given a page, search the block to find - * a better page with the same page id - * - * \param[in] dev uffs device - * \param[in] bc block info - * \param[in] page page number to be compared with - * - * \return the better page number, could be the same with the given page. - * if the given page does not have good tag, return UFFS_INVALID_PAGE. - */ -u16 uffs_FindBestPageInBlock(uffs_Device *dev, uffs_BlockInfo *bc, u16 page) -{ - int i; - uffs_Tags *tag, *tag_old; - - if (!uffs_Assert(page != UFFS_INVALID_PAGE, "invalid param !")) - return page; // just in case ... - - uffs_BlockInfoLoad(dev, bc, page); // load old page - tag_old = GET_TAG(bc, page); - - if (!uffs_Assert(TAG_IS_GOOD(tag_old), "try to find a invalid page ?")) - return UFFS_INVALID_PAGE; - - if (page == dev->attr->pages_per_block - 1) // already the last page ? - return page; - - for (i = dev->attr->pages_per_block - 1; i > page; i--) { - uffs_BlockInfoLoad(dev, bc, i); - tag = GET_TAG(bc, i); - if (TAG_IS_GOOD(tag) && - TAG_PAGE_ID(tag) == TAG_PAGE_ID(tag_old) && - TAG_PARENT(tag) == TAG_PARENT(tag_old) && - TAG_SERIAL(tag) == TAG_SERIAL(tag_old)) - { - break; - } - } - - return i; -} - -/** - * \brief find a valid page with given page_id - * \param[in] dev uffs device - * \param[in] bc block info - * \param[in] page_id page_id to be find - * \return the valid page number which has given page_id - * \retval >=0 page number - * \retval UFFS_INVALID_PAGE page not found - */ -u16 uffs_FindPageInBlockWithPageId(uffs_Device *dev, - uffs_BlockInfo *bc, u16 page_id) -{ - u16 page; - uffs_Tags *tag; - - //Indeed, the page which has page_id, should ahead of page_id ... - for (page = page_id; page < dev->attr->pages_per_block; page++) { - uffs_BlockInfoLoad(dev, bc, page); - tag = &(bc->spares[page].tag); - if (TAG_IS_GOOD(tag) && TAG_PAGE_ID(tag) == page_id) - return page; - } - - return UFFS_INVALID_PAGE; -} - -/** - * Are all the pages in the block used ? - */ -UBOOL uffs_IsBlockPagesFullUsed(uffs_Device *dev, uffs_BlockInfo *bc) -{ - uffs_Tags *tag; - - // if the last page is dirty, then the whole block is full - uffs_BlockInfoLoad(dev, bc, dev->attr->pages_per_block - 1); - tag = GET_TAG(bc, dev->attr->pages_per_block - 1); - - return TAG_IS_GOOD(tag) ? U_TRUE : U_FALSE; -} - -/** - * Is this block used ? - * \param[in] dev uffs device - * \param[in] bc block info - * \retval U_TRUE block is used - * \retval U_FALSE block is free - */ -UBOOL uffs_IsThisBlockUsed(uffs_Device *dev, uffs_BlockInfo *bc) -{ - uffs_Tags *tag; - - // if the first page is dirty, then this block is used. - uffs_BlockInfoLoad(dev, bc, 0); - tag = GET_TAG(bc, 0); - - return TAG_IS_DIRTY(tag) ? U_TRUE : U_FALSE; -} - -/** - * get block time stamp from a exist block - * \param[in] dev uffs device - * \param[in] bc block info - */ -int uffs_GetBlockTimeStamp(uffs_Device *dev, uffs_BlockInfo *bc) -{ - if(uffs_IsThisBlockUsed(dev, bc) == U_FALSE) - return uffs_GetFirstBlockTimeStamp(); - else{ - uffs_BlockInfoLoad(dev, bc, 0); - return TAG_BLOCK_TS(GET_TAG(bc, 0)); - } - -} - -/** - * find first free page from 'pageFrom' - * \param[in] dev uffs device - * \param[in] bc block info - * \param[in] pageFrom search from this page - * \return return first free page number from 'pageFrom' - * \retval UFFS_INVALID_PAGE no free page found - * \retval >=0 the first free page number - */ -u16 uffs_FindFirstFreePage(uffs_Device *dev, - uffs_BlockInfo *bc, u16 pageFrom) -{ - u16 i; - - for (i = pageFrom; i < dev->attr->pages_per_block; i++) { - uffs_BlockInfoLoad(dev, bc, i); - if (uffs_IsPageErased(dev, bc, i) == U_TRUE) - return i; - } - - return UFFS_INVALID_PAGE; //free page not found -} - - -/** - * calculate sum of data, 8bit version - * \param[in] p data pointer - * \param[in] len length of data - * \return return sum of data, 8bit - */ -u8 uffs_MakeSum8(const void *p, int len) -{ - return uffs_crc16sum(p, len) & 0xFF; -} - -/** - * calculate sum of datam, 16bit version - * \param[in] p data pointer - * \param[in] len length of data - * \return return sum of data, 16bit - */ -u16 uffs_MakeSum16(const void *p, int len) -{ - return uffs_crc16sum(p, len); -} - -/** - * create a new file on a free block - * \param[in] dev uffs device - * \param[in] parent parent dir serial num - * \param[in] serial serial num of this new file - * \param[in] bc block information - * \param[in] fi file information - * \note parent, serial, bc must be provided before, - * and all information in fi should be filled well before. - */ -URET uffs_CreateNewFile(uffs_Device *dev, - u16 parent, u16 serial, - uffs_BlockInfo *bc, uffs_FileInfo *fi) -{ - uffs_Tags *tag; - uffs_Buf *buf; - - uffs_BlockInfoLoad(dev, bc, 0); - - tag = GET_TAG(bc, 0); - TAG_PARENT(tag) = parent; - TAG_SERIAL(tag) = serial; - TAG_DATA_LEN(tag) = sizeof(uffs_FileInfo); - - buf = uffs_BufGet(dev, parent, serial, 0); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "get buf fail."); - return U_FAIL; - } - - memcpy(buf->data, fi, TAG_DATA_LEN(tag)); - buf->data_len = TAG_DATA_LEN(tag); - - return uffs_BufPut(dev, buf); -} - - -/** - * \brief calculate data length of a file block - * \param[in] dev uffs device - * \param[in] bc block info - */ -int uffs_GetBlockFileDataLength(uffs_Device *dev, uffs_BlockInfo *bc, u8 type) -{ - u16 page_id; - u16 i; - uffs_Tags *tag; - int size = 0; - u16 page; - u16 lastPage = dev->attr->pages_per_block - 1; - - uffs_BlockInfoLoad(dev, bc, lastPage); - tag = GET_TAG(bc, lastPage); - - if (TAG_IS_GOOD(tag)) { - // First try the last page. - // if it's the full loaded file/data block, then we have a quick path. - if (type == UFFS_TYPE_FILE) { - if (TAG_PAGE_ID(tag) == (lastPage - 1)) { - size = dev->com.pg_data_size * (dev->attr->pages_per_block - 2) + TAG_DATA_LEN(tag); - return size; - } - } - if (type == UFFS_TYPE_DATA) { - if (TAG_PAGE_ID(tag) == lastPage) { - size = dev->com.pg_data_size * (dev->attr->pages_per_block - 1) + TAG_DATA_LEN(tag); - return size; - } - } - } - - // ok, it's not the full loaded file/data block, - // need to read all spares.... - uffs_BlockInfoLoad(dev, bc, UFFS_ALL_PAGES); - tag = GET_TAG(bc, 0); - if (uffs_Assert(TAG_IS_GOOD(tag), "block %d page 0 does not have good tag ?", bc->block)) { - if (TAG_TYPE(tag) == UFFS_TYPE_FILE) { - page_id = 1; //In file header block, file data page_id from 1 - i = 1; //search from page 1 - } - else { - page_id = 0; //in normal file data block, page_id from 0 - i = 0; //in normal file data block, search from page 0 - } - for (; i < dev->attr->pages_per_block; i++) { - tag = GET_TAG(bc, i); - if (TAG_IS_GOOD(tag)) { - if (page_id == TAG_PAGE_ID(tag)) { - page = uffs_FindBestPageInBlock(dev, bc, i); - if (uffs_Assert(page != UFFS_INVALID_PAGE, "got an invalid page ?")) { - size += TAG_DATA_LEN(GET_TAG(bc, page)); - page_id++; - } - } - } - } - } - - return size; -} - -/** - * get free pages number - * \param[in] dev uffs device - * \param[in] bc block info - */ -int uffs_GetFreePagesCount(uffs_Device *dev, uffs_BlockInfo *bc) -{ - int count = 0; - int i; - - // search from the last page ... to first page - for (i = dev->attr->pages_per_block - 1; i >= 0; i--) { - uffs_BlockInfoLoad(dev, bc, i); - if (uffs_IsPageErased(dev, bc, (u16)i) == U_TRUE) { - count++; - } - else { - if (TAG_IS_GOOD(GET_TAG(bc, i))) // it won't be any free page if we see a good tag. - break; - } - } - - return count; -} -/** - * \brief Is the block erased ? - * \param[in] dev uffs device - * \param[in] bc block info - * \param[in] page page number to be check - * \retval U_TRUE block is erased, ready to use - * \retval U_FALSE block is dirty, maybe use by file - */ -UBOOL uffs_IsPageErased(uffs_Device *dev, uffs_BlockInfo *bc, u16 page) -{ - uffs_Tags *tag; - - uffs_BlockInfoLoad(dev, bc, page); - tag = GET_TAG(bc, page); - - if (!TAG_IS_SEALED(tag) && - !TAG_IS_DIRTY(tag) && - !TAG_IS_VALID(tag)) { - return U_TRUE; - } - - return U_FALSE; -} - -/** - * get partition used (bytes) - */ -int uffs_GetDeviceUsed(uffs_Device *dev) -{ - return (dev->par.end - dev->par.start + 1 - - dev->tree.bad_count - dev->tree.erased_count - ) * - dev->attr->page_data_size * - dev->attr->pages_per_block; -} - -/** - * get partition free (bytes) - */ -int uffs_GetDeviceFree(uffs_Device *dev) -{ - return dev->tree.erased_count * - dev->attr->page_data_size * - dev->attr->pages_per_block; -} - -/** - * get partition total size (bytes) - */ -int uffs_GetDeviceTotal(uffs_Device *dev) -{ - return (dev->par.end - dev->par.start + 1) * - dev->attr->page_data_size * - dev->attr->pages_per_block; -} - -/** - * load mini hader from flash - */ -URET uffs_LoadMiniHeader(uffs_Device *dev, - int block, u16 page, struct uffs_MiniHeaderSt *header) -{ - int ret; - struct uffs_FlashOpsSt *ops = dev->ops; - - if (ops->ReadPageWithLayout) { - ret = ops->ReadPageWithLayout(dev, block, page, (u8 *)header, - sizeof(struct uffs_MiniHeaderSt), NULL, NULL, NULL); - } - else { - ret = ops->ReadPage(dev, block, page, (u8 *)header, sizeof(struct uffs_MiniHeaderSt), NULL, NULL, 0); - } - - dev->st.page_header_read_count++; - - return UFFS_FLASH_HAVE_ERR(ret) ? U_FAIL : U_SUCC; -} - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_tree.c b/components/dfs/filesystems/uffs/src/uffs/uffs_tree.c deleted file mode 100644 index 7e51a9275f..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_tree.c +++ /dev/null @@ -1,1278 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_tree.c - * \brief seting up uffs tree data structure - * \author Ricky Zheng, created 13th May, 2005 - */ - -#include "uffs_config.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_pool.h" -#include "uffs/uffs_flash.h" -#include "uffs/uffs_badblock.h" - -#include <string.h> - -#define TPOOL(dev) &(dev->mem.tree_pool) - -#define PFX "tree: " - -static void uffs_InsertToFileEntry(uffs_Device *dev, TreeNode *node); -static void uffs_InsertToDirEntry(uffs_Device *dev, TreeNode *node); -static void uffs_InsertToDataEntry(uffs_Device *dev, TreeNode *node); - -static TreeNode * uffs_TreeGetErasedNodeNoCheck(uffs_Device *dev); - - -struct BlockTypeStatSt { - int dir; - int file; - int data; -}; - -/** - * \brief initialize tree buffers - * \param[in] dev uffs device - */ -URET uffs_TreeInit(uffs_Device *dev) -{ - int size; - int num; - uffs_Pool *pool; - int i; - - size = sizeof(TreeNode); - num = dev->par.end - dev->par.start + 1; - - pool = &(dev->mem.tree_pool); - - if (dev->mem.tree_nodes_pool_size == 0) { - if (dev->mem.malloc) { - dev->mem.tree_nodes_pool_buf = dev->mem.malloc(dev, size * num); - if (dev->mem.tree_nodes_pool_buf) - dev->mem.tree_nodes_pool_size = size * num; - } - } - if (size * num > dev->mem.tree_nodes_pool_size) { - uffs_Perror(UFFS_MSG_DEAD, - "Tree buffer require %d but only %d available.", - size * num, dev->mem.tree_nodes_pool_size); - memset(pool, 0, sizeof(uffs_Pool)); - return U_FAIL; - } - uffs_Perror(UFFS_MSG_NOISY, "alloc tree nodes %d bytes.", size * num); - - uffs_PoolInit(pool, dev->mem.tree_nodes_pool_buf, - dev->mem.tree_nodes_pool_size, size, num); - - dev->tree.erased = NULL; - dev->tree.erased_tail = NULL; - dev->tree.erased_count = 0; - dev->tree.bad = NULL; - dev->tree.bad_count = 0; - - for (i = 0; i < DIR_NODE_ENTRY_LEN; i++) { - dev->tree.dir_entry[i] = EMPTY_NODE; - } - - for (i = 0; i < FILE_NODE_ENTRY_LEN; i++) { - dev->tree.file_entry[i] = EMPTY_NODE; - } - - for (i = 0; i < DATA_NODE_ENTRY_LEN; i++) { - dev->tree.data_entry[i] = EMPTY_NODE; - } - - dev->tree.max_serial = ROOT_DIR_SERIAL; - - return U_SUCC; -} -/** - * \brief release tree buffers, call this function when unmount - * \param[in] dev uffs device - */ -URET uffs_TreeRelease(uffs_Device *dev) -{ - uffs_Pool *pool; - - pool = &(dev->mem.tree_pool); - if (pool->mem && dev->mem.free) { - dev->mem.free(dev, pool->mem); - pool->mem = NULL; - dev->mem.tree_nodes_pool_size = 0; - } - uffs_PoolRelease(pool); - memset(pool, 0, sizeof(uffs_Pool)); - - return U_SUCC; -} - -static u16 _GetBlockFromNode(u8 type, TreeNode *node) -{ - switch (type) { - case UFFS_TYPE_DIR: - return node->u.dir.block; - case UFFS_TYPE_FILE: - return node->u.file.block; - case UFFS_TYPE_DATA: - return node->u.data.block; - } - uffs_Perror(UFFS_MSG_SERIOUS, "unkown type, X-block"); - return UFFS_INVALID_BLOCK; -} - -#if 0 -static u16 _GetParentFromNode(u8 type, TreeNode *node) -{ - switch (type) { - case UFFS_TYPE_DIR: - return node->u.dir.parent; - case UFFS_TYPE_FILE: - return node->u.file.parent; - case UFFS_TYPE_DATA: - return node->u.data.parent; - } - uffs_Perror(UFFS_MSG_SERIOUS, "unkown type, X-parent"); - return INVALID_UFFS_SERIAL; -} - - -static u16 _GetSerialFromNode(u8 type, TreeNode *node) -{ - switch (type) { - case UFFS_TYPE_DIR: - return node->u.dir.serial; - case UFFS_TYPE_FILE: - return node->u.file.serial; - case UFFS_TYPE_DATA: - return node->u.data.serial; - } - uffs_Perror(UFFS_MSG_SERIOUS, "unkown type, X-serial"); - return INVALID_UFFS_SERIAL; -} -#endif - -/** - * insert a TreeNode *node to tree - * \param[in] dev uffs device - * \param[in] type type of node - * \param[in] node node to be insert to - */ -void uffs_InsertNodeToTree(uffs_Device *dev, u8 type, TreeNode *node) -{ - switch (type) { - case UFFS_TYPE_DIR: - uffs_InsertToDirEntry(dev, node); - break; - case UFFS_TYPE_FILE: - uffs_InsertToFileEntry(dev, node); - break; - case UFFS_TYPE_DATA: - uffs_InsertToDataEntry(dev, node); - break; - default: - uffs_Perror(UFFS_MSG_SERIOUS, - "unkown type, can't insert to tree"); - break; - } -} - -/** - * find a node from tree - * \param[in] dev uffs device - * \param[in] type type of node - * \param[in] parent parent serial num - * \param[in] serial serial num - */ -TreeNode * uffs_FindFromTree(uffs_Device *dev, - u8 type, u16 parent, u16 serial) -{ - switch (type) { - case UFFS_TYPE_DIR: - return uffs_TreeFindDirNode(dev, serial); - case UFFS_TYPE_FILE: - return uffs_TreeFindFileNode(dev, serial); - case UFFS_TYPE_DATA: - return uffs_TreeFindDataNode(dev, parent, serial); - } - uffs_Perror(UFFS_MSG_SERIOUS, - "unkown type, can't find node"); - return NULL; -} - - - -static URET _BuildValidTreeNode(uffs_Device *dev, - TreeNode *node, //!< empty node - uffs_BlockInfo *bc, - struct BlockTypeStatSt *st) -{ - uffs_Tags *tag; - TreeNode *node_alt; - u16 block, parent, serial, block_alt, block_save; - uffs_BlockInfo *bc_alt; - u8 type; - int page; - UBOOL needToInsertToTree = U_FALSE; - uffs_Buf *buf = NULL; - uffs_FileInfo *info; - u16 data_sum = 0; - - // check the first page on the block ... - uffs_BlockInfoLoad(dev, bc, 0); - - tag = GET_TAG(bc, 0); //get first page's tag - - if (!TAG_IS_DIRTY(tag)) { - // should never go here ... unless mark dirty page failed ? - uffs_Perror(UFFS_MSG_NORMAL, - "First page is clean in a non-erased block ?"); - return U_FAIL; - } - - if (!TAG_IS_VALID(tag)) { - //first page is invalid ? should be erased now! - uffs_Perror(UFFS_MSG_NORMAL, - "first page in block %d is invalid, will be erased now!", - bc->block); - goto process_invalid_block; - } - - block = bc->block; - parent = TAG_PARENT(tag); - serial = TAG_SERIAL(tag); - type = TAG_TYPE(tag); - - // check if there is an 'alternative block' - // (node which has the same serial number) in tree ? - node_alt = uffs_FindFromTree(dev, type, parent, serial); - - if (node_alt != NULL) { - //find a alternate node ! need to check the timestamp ! - - block_alt = _GetBlockFromNode(type, node_alt); - - uffs_Perror(UFFS_MSG_NORMAL, - "Process unclean block (%d vs %d)", block, block_alt); - - if (block_alt == INVALID_UFFS_SERIAL) { - uffs_Perror(UFFS_MSG_SERIOUS, "invalid block ?"); - return U_FAIL; - } - - bc_alt = uffs_BlockInfoGet(dev, block_alt); - if (bc_alt == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't get block info "); - return U_FAIL; - } - uffs_BlockInfoLoad(dev, bc_alt, 0); - if (uffs_IsSrcNewerThanObj ( - TAG_BLOCK_TS(tag), - TAG_BLOCK_TS(GET_TAG(bc_alt, 0))) == U_TRUE) { - - //the node is newer than node_alt, so keep node_alt, and erase node - uffs_FlashEraseBlock(dev, block); - node->u.list.block = block; - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, node); - else - uffs_TreeInsertToErasedListTail(dev, node); - - uffs_BlockInfoPut(dev, bc_alt); //put back bc_alt before we return. - return U_SUCC; - } - else { - //the node is older than node_alt, so keep node, and erase node_alt - //we use node as erased node to insert to erased list - - block_save = _GetBlockFromNode(type, node_alt); - uffs_FlashEraseBlock(dev, block_save); - node->u.list.block = block_save; - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, node); - else - uffs_TreeInsertToErasedListTail(dev, node); - - //put back bc_alt because we don't need it anymore. - uffs_BlockInfoPut(dev, bc_alt); - - //use node_alt to store new informations in following - node = node_alt; - - needToInsertToTree = U_FALSE; - } - } - else { - needToInsertToTree = U_TRUE; - } - - if (type == UFFS_TYPE_DIR || type == UFFS_TYPE_FILE) { - buf = uffs_BufClone(dev, NULL); - if (buf == NULL) - return U_FAIL; - uffs_BlockInfoLoad(dev, bc, UFFS_ALL_PAGES); - page = uffs_FindPageInBlockWithPageId(dev, bc, 0); - if (page == UFFS_INVALID_PAGE) { - uffs_BufFreeClone(dev, buf); - uffs_Perror(UFFS_MSG_SERIOUS, - "Can't find any valid page for page_id=0 ? invalid block !" - "this might be caused by the tag layout change.\n"); - goto process_invalid_block; - } - page = uffs_FindBestPageInBlock(dev, bc, page); - uffs_FlashReadPage(dev, block, page, buf, U_FALSE); - info = (uffs_FileInfo *) (buf->data); - data_sum = uffs_MakeSum16(info->name, info->name_len); - uffs_BufFreeClone(dev, buf); - } - - switch (type) { - case UFFS_TYPE_DIR: - node->u.dir.block = bc->block; - node->u.dir.checksum = data_sum; - node->u.dir.parent = TAG_PARENT(tag); - node->u.dir.serial = TAG_SERIAL(tag); - st->dir++; - break; - case UFFS_TYPE_FILE: - node->u.file.block = bc->block; - node->u.file.checksum = data_sum; - node->u.file.parent = TAG_PARENT(tag); - node->u.file.serial = TAG_SERIAL(tag); - node->u.file.len = uffs_GetBlockFileDataLength(dev, bc, UFFS_TYPE_FILE); - st->file++; - break; - case UFFS_TYPE_DATA: - node->u.data.block = bc->block; - node->u.data.parent = TAG_PARENT(tag); - node->u.data.serial = TAG_SERIAL(tag); - node->u.data.len = uffs_GetBlockFileDataLength(dev, bc, UFFS_TYPE_DATA); - st->data++; - break; - } - - if (needToInsertToTree == U_TRUE) { - uffs_InsertNodeToTree(dev, type, node); - } - - return U_SUCC; - -process_invalid_block: - /* erase the invalid block */ - uffs_FlashEraseBlock(dev, bc->block); - - node->u.list.block = bc->block; - - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, node); - else - uffs_TreeInsertToErasedListTail(dev, node); - - return U_SUCC; -} - - -static URET _ScanAndFixUnCleanPage(uffs_Device *dev, uffs_BlockInfo *bc) -{ - int page; - uffs_Tags *tag; - struct uffs_MiniHeaderSt header; - - /* in most case, the valid block contents fewer free page, - so it's better scan from the last page ... to page 1. - note: scanning page 0 is not necessary, will check it later. - - The worse case: read (pages_per_block - 1) * (mini header + spares) ! - most case: read one spare. - */ - for (page = dev->attr->pages_per_block - 1; page > 0; page--) { - uffs_BlockInfoLoad(dev, bc, page); - tag = GET_TAG(bc, page); - - if (TAG_IS_SEALED(tag)) - break; // tag sealed, no unclean page in this block. - - if (TAG_IS_DIRTY(tag) || TAG_IS_VALID(tag)) { // tag not sealed but dirty/valid ? - uffs_Perror(UFFS_MSG_NORMAL, - "unclean page found, block %d page %d", - bc->block, page); - - // ok, an unclean page found. - // This unclean page can be identified by tag. - // We can leave it as it is, but performing a block recover would be good ? - // There won't be another unclean page in this block ... stop here. - break; - } - - // now we have a clean tag (all 0xFF ?). Need to check mini header to see if it's an unclean page. - if (uffs_LoadMiniHeader(dev, bc->block, page, &header) == U_FAIL) - return U_FAIL; - - if (header.status != 0xFF) { - // page data is dirty? this is an unclean page and we should explicitly mark tag as 'dirty and invalid'. - // This writing does not violate "no partial program" claim, because we are writing to a clean page spare. - uffs_Perror(UFFS_MSG_NORMAL, - "unclean page found, block %d page %d, mark it.", - bc->block, page); - uffs_FlashMarkDirtyPage(dev, bc, page); - } - } - - return U_SUCC; -} - - -static URET _BuildTreeStepOne(uffs_Device *dev) -{ - int block_lt; - uffs_BlockInfo *bc = NULL; - TreeNode *node; - struct uffs_TreeSt *tree; - uffs_Pool *pool; - struct uffs_MiniHeaderSt header; - URET ret = U_SUCC; - struct BlockTypeStatSt st = {0, 0, 0}; - - tree = &(dev->tree); - pool = TPOOL(dev); - - tree->bad = NULL; - tree->bad_count = 0; - tree->erased = NULL; - tree->erased_tail = NULL; - tree->erased_count = 0; - - uffs_Perror(UFFS_MSG_NOISY, "build tree step one"); - -// printf("s:%d e:%d\n", dev->par.start, dev->par.end); - for (block_lt = dev->par.start; block_lt <= dev->par.end; block_lt++) { - bc = uffs_BlockInfoGet(dev, block_lt); - if (bc == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "step one:fail to get block info"); - ret = U_FAIL; - break; - } - node = (TreeNode *)uffs_PoolGet(pool); - if (node == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "insufficient tree node!"); - ret = U_FAIL; - break; - } - - // Need to check bad block at first ! - if (uffs_FlashIsBadBlock(dev, block_lt) == U_TRUE) { - node->u.list.block = block_lt; - uffs_TreeInsertToBadBlockList(dev, node); - uffs_Perror(UFFS_MSG_NORMAL, "found bad block %d", block_lt); - } - else if (uffs_IsPageErased(dev, bc, 0) == U_TRUE) { //@ read one spare: 0 - // page 0 tag shows it's an erased block, we need to check the mini header status to make sure it is clean. - if (uffs_LoadMiniHeader(dev, block_lt, 0, &header) == U_FAIL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "I/O error when reading mini header !" - "block %d page %d", - block_lt, 0); - ret = U_FAIL; - break; - } - - if (header.status != 0xFF) { - // page 0 tag is clean but page data is dirty ??? - // this block should be erased immediately ! - uffs_FlashEraseBlock(dev, block_lt); - } - node->u.list.block = block_lt; - if (HAVE_BADBLOCK(dev)) { - uffs_Perror(UFFS_MSG_NORMAL, - "New bad block (%d) discovered.", block_lt); - uffs_BadBlockProcess(dev, node); - } - else { - // page 0 is clean does not means all pages in this block are clean, - // need to check this block later before use it. - uffs_TreeInsertToErasedListTailEx(dev, node, 1); - } - } - else { - - // this block have valid data page(s). - - ret = _ScanAndFixUnCleanPage(dev, bc); - if (ret == U_FAIL) - break; - - ret = _BuildValidTreeNode(dev, node, bc, &st); - if (ret == U_FAIL) - break; - - } - uffs_BlockInfoPut(dev, bc); - } //end of for - - if(ret == U_FAIL) - uffs_BlockInfoPut(dev, bc); - - uffs_Perror(UFFS_MSG_NORMAL, - "DIR %d, FILE %d, DATA %d", st.dir, st.file, st.data); - - return ret; -} - -static URET _BuildTreeStepTwo(uffs_Device *dev) -{ - //Randomise the start point of erased block to implement wear levelling - u32 startCount = 0; - u32 endPoint; - TreeNode *node; - - uffs_Perror(UFFS_MSG_NOISY, "build tree step two"); - - endPoint = uffs_GetCurDateTime() % (dev->tree.erased_count + 1); - while (startCount < endPoint) { - node = uffs_TreeGetErasedNodeNoCheck(dev); - if (node == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "No erased block ?"); - return U_FAIL; - } - uffs_TreeInsertToErasedListTailEx(dev, node, -1); - startCount++; - } - - return U_SUCC; -} - -TreeNode * uffs_TreeFindFileNode(uffs_Device *dev, u16 serial) -{ - int hash; - u16 x; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - - hash = serial & FILE_NODE_HASH_MASK; - x = tree->file_entry[hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.file.serial == serial) { - return node; - } - else { - x = node->hash_next; - } - } - return NULL; -} - -/** add a node into suspend list */ -void uffs_TreeSuspendAdd(uffs_Device *dev, TreeNode *node) -{ - node->u.list.next = dev->tree.suspend; - node->u.list.prev = NULL; - - if (dev->tree.suspend) - dev->tree.suspend->u.list.prev = node; - dev->tree.suspend = node; -} - -/** search suspend list */ -TreeNode * uffs_TreeFindSuspendNode(uffs_Device *dev, u16 serial) -{ - TreeNode *node = dev->tree.suspend; - while (node) { - if (node->u.list.u.serial == serial) - break; - - node = node->u.list.next; - } - - return node; -} - -/** remove a node from suspend list */ -void uffs_TreeRemoveSuspendNode(uffs_Device *dev, TreeNode *node) -{ - if (node->u.list.prev) - node->u.list.prev->u.list.next = node->u.list.next; - if (node->u.list.next) - node->u.list.next->u.list.prev = node->u.list.prev; - if (node == dev->tree.suspend) - dev->tree.suspend = NULL; -} - -TreeNode * uffs_TreeFindFileNodeWithParent(uffs_Device *dev, u16 parent) -{ - int hash; - u16 x; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - - for (hash = 0; hash < FILE_NODE_ENTRY_LEN; hash++) { - x = tree->file_entry[hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.file.parent == parent) { - return node; - } - else { - x = node->hash_next; - } - } - } - - return NULL; -} - -TreeNode * uffs_TreeFindDirNode(uffs_Device *dev, u16 serial) -{ - int hash; - u16 x; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - - hash = serial & DIR_NODE_HASH_MASK; - x = tree->dir_entry[hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.dir.serial == serial) { - return node; - } - else { - x = node->hash_next; - } - } - return NULL; -} - -TreeNode * uffs_TreeFindDirNodeWithParent(uffs_Device *dev, u16 parent) -{ - int hash; - u16 x; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - - for (hash = 0; hash < DIR_NODE_ENTRY_LEN; hash++) { - x = tree->dir_entry[hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.dir.parent == parent) { - return node; - } - else { - x = node->hash_next; - } - } - } - - return NULL; -} - -TreeNode * uffs_TreeFindFileNodeByName(uffs_Device *dev, - const char *name, - u32 len, - u16 sum, u16 parent) -{ - int i; - u16 x; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - - for (i = 0; i < FILE_NODE_ENTRY_LEN; i++) { - x = tree->file_entry[i]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.file.checksum == sum && node->u.file.parent == parent) { - //read file name from flash, and compare... - if (uffs_TreeCompareFileName(dev, name, len, sum, - node, UFFS_TYPE_FILE) == U_TRUE) { - //Got it! - return node; - } - } - x = node->hash_next; - } - } - - return NULL; -} - -TreeNode * uffs_TreeFindDataNode(uffs_Device *dev, u16 parent, u16 serial) -{ - int hash; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - u16 x; - - hash = GET_DATA_HASH(parent, serial); - x = tree->data_entry[hash]; - while(x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - - if(node->u.data.parent == parent && - node->u.data.serial == serial) - return node; - - x = node->hash_next; - } - - return NULL; -} - -TreeNode * uffs_TreeFindDirNodeByBlock(uffs_Device *dev, u16 block) -{ - int hash; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - u16 x; - - for (hash = 0; hash < DIR_NODE_ENTRY_LEN; hash++) { - x = tree->dir_entry[hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.dir.block == block) - return node; - x = node->hash_next; - } - } - - return NULL; -} - -TreeNode * uffs_TreeFindErasedNodeByBlock(uffs_Device *dev, u16 block) -{ - TreeNode *node; - node = dev->tree.erased; - - while (node) { - if (node->u.list.block == block) - return node; - node = node->u.list.next; - } - - return NULL; -} - -TreeNode * uffs_TreeFindBadNodeByBlock(uffs_Device *dev, u16 block) -{ - TreeNode *node; - node = dev->tree.bad; - - while (node) { - if (node->u.list.block == block) - return node; - node = node->u.list.next; - } - - return NULL; -} - -TreeNode * uffs_TreeFindFileNodeByBlock(uffs_Device *dev, u16 block) -{ - int hash; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - u16 x; - - for (hash = 0; hash < FILE_NODE_ENTRY_LEN; hash++) { - x = tree->file_entry[hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.file.block == block) - return node; - x = node->hash_next; - } - } - - return NULL; -} - -TreeNode * uffs_TreeFindDataNodeByBlock(uffs_Device *dev, u16 block) -{ - int hash; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - u16 x; - - for (hash = 0; hash < DATA_NODE_ENTRY_LEN; hash++) { - x = tree->data_entry[hash]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.data.block == block) - return node; - x = node->hash_next; - } - } - - return NULL; -} - -TreeNode * uffs_TreeFindNodeByBlock(uffs_Device *dev, u16 block, int *region) -{ - TreeNode *node = NULL; - - if (*region & SEARCH_REGION_DATA) { - node = uffs_TreeFindDataNodeByBlock(dev, block); - if (node) { - *region &= SEARCH_REGION_DATA; - return node; - } - } - if (*region & SEARCH_REGION_FILE) { - node = uffs_TreeFindFileNodeByBlock(dev, block); - if (node) { - *region &= SEARCH_REGION_FILE; - return node; - } - } - if (*region & SEARCH_REGION_DIR) { - node = uffs_TreeFindDirNodeByBlock(dev, block); - if (node) { - *region &= SEARCH_REGION_DIR; - return node; - } - } - if (*region & SEARCH_REGION_ERASED) { - node = uffs_TreeFindErasedNodeByBlock(dev, block); - if (node) { - *region &= SEARCH_REGION_ERASED; - return node; - } - } - if (*region & SEARCH_REGION_BAD) { - node = uffs_TreeFindBadNodeByBlock(dev, block); - if (node) { - *region &= SEARCH_REGION_BAD; - return node; - } - } - - return node; -} - -TreeNode * uffs_TreeFindDirNodeByName(uffs_Device *dev, - const char *name, u32 len, - u16 sum, u16 parent) -{ - int i; - u16 x; - TreeNode *node; - struct uffs_TreeSt *tree = &(dev->tree); - - for (i = 0; i < DIR_NODE_ENTRY_LEN; i++) { - x = tree->dir_entry[i]; - while (x != EMPTY_NODE) { - node = FROM_IDX(x, TPOOL(dev)); - if (node->u.dir.checksum == sum && - node->u.dir.parent == parent) { - //read file name from flash, and compare... - if (uffs_TreeCompareFileName(dev, name, len, sum, - node, UFFS_TYPE_DIR) == U_TRUE) { - //Got it! - return node; - } - } - x = node->hash_next; - } - } - - return NULL; - -} - -UBOOL uffs_CompareFileName(const char *src, int src_len, const char *des) -{ - while (src_len-- > 0) { - if(*src++ != *des++) - return U_FALSE; - } - - return U_TRUE; -} - -/** compare [name] with tree [node] represented object name by loading - uffs_FileInfo from storage */ -UBOOL uffs_TreeCompareFileName(uffs_Device *dev, - const char *name, u32 len, u16 sum, - TreeNode *node, int type) -{ - UBOOL matched = U_FALSE; - uffs_FileInfo *fi; - uffs_Buf *buf; - u16 data_sum; - - buf = uffs_BufGetEx(dev, type, node, 0, 0); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, "can't get buf !\n "); - goto ext; - } - fi = (uffs_FileInfo *)(buf->data); - data_sum = uffs_MakeSum16(fi->name, fi->name_len); - - if (data_sum != sum) { - uffs_Perror(UFFS_MSG_NORMAL, - "the obj's sum in storage is different with given sum!"); - goto ext; - } - - if (fi->name_len == len) { - if(uffs_CompareFileName(fi->name, fi->name_len, name) == U_TRUE) { - matched = U_TRUE; - } - } -ext: - if (buf) - uffs_BufPut(dev, buf); - - return matched; -} - - -/* calculate file length, etc */ -static URET _BuildTreeStepThree(uffs_Device *dev) -{ - int i; - u16 x; - TreeNode *work; - TreeNode *node; - struct uffs_TreeSt *tree; - uffs_Pool *pool; - u16 blockSave; - - TreeNode *cache = NULL; - u16 cacheSerial = INVALID_UFFS_SERIAL; - - tree = &(dev->tree); - pool = TPOOL(dev); - - uffs_Perror(UFFS_MSG_NOISY, "build tree step three"); - - for (i = 0; i < DATA_NODE_ENTRY_LEN; i++) { - x = tree->data_entry[i]; - while (x != EMPTY_NODE) { - work = FROM_IDX(x, pool); - if (work->u.data.parent == cacheSerial) { - node = cache; - } - else { - node = uffs_TreeFindFileNode(dev, work->u.data.parent); - cache = node; - cacheSerial = work->u.data.parent; - } - if (node == NULL) { - x = work->hash_next; - //this data block does not belong to any file ? - //should be erased. - uffs_Perror(UFFS_MSG_NORMAL, - "find a orphan data block:%d, " - "parent:%d, serial:%d, will be erased!", - work->u.data.block, - work->u.data.parent, work->u.data.serial); - - uffs_BreakFromEntry(dev, UFFS_TYPE_DATA, work); - blockSave = work->u.data.block; - work->u.list.block = blockSave; - uffs_FlashEraseBlock(dev, blockSave); - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, work); - else - uffs_TreeInsertToErasedListTail(dev, work); - } - else { - node->u.file.len += work->u.data.len; - x = work->hash_next; - } - } - } - - return U_SUCC; -} - -/** - * \brief build tree structure from flash - * \param[in] dev uffs device - */ -URET uffs_BuildTree(uffs_Device *dev) -{ - URET ret; - - /***** step one: scan all page spares, classify DIR/FILE/DATA nodes, - check bad blocks/uncompleted(conflicted) blocks as well *****/ - - /* if the disk is big and full filled of data this step could be - the most time consuming .... */ - - ret = _BuildTreeStepOne(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "build tree step one fail!"); - return ret; - } - - /***** step two: randomize the erased blocks, for ware-leveling purpose *****/ - /* this step is very fast :) */ - ret = _BuildTreeStepTwo(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "build tree step two fail!"); - return ret; - } - - /***** step three: check DATA nodes, find orphan nodes and erase them *****/ - /* if there are a lot of files and disk is fully filled, this step - could be very time consuming ... */ - ret = _BuildTreeStepThree(dev); - if (ret != U_SUCC) { - uffs_Perror(UFFS_MSG_SERIOUS, "build tree step three fail!"); - return ret; - } - - return U_SUCC; -} - -/** - * find a free file or dir serial NO - * \param[in] dev uffs device - * \return if no free serial found, return #INVALID_UFFS_SERIAL - */ -u16 uffs_FindFreeFsnSerial(uffs_Device *dev) -{ - u16 i; - TreeNode *node; - - //TODO!! Do we need a faster serial number generating method? - // it depends on how often creating files or directories - - for (i = ROOT_DIR_SERIAL + 1; i < MAX_UFFS_FSN; i++) { - node = uffs_TreeFindDirNode(dev, i); - if (node == NULL) { - node = uffs_TreeFindFileNode(dev, i); - if (node == NULL) { - node = uffs_TreeFindSuspendNode(dev, i); - if (node == NULL) - return i; - } - } - } - - return INVALID_UFFS_SERIAL; -} - -static TreeNode * uffs_TreeGetErasedNodeNoCheck(uffs_Device *dev) -{ - TreeNode *node = NULL; - if (dev->tree.erased) { - node = dev->tree.erased; - dev->tree.erased->u.list.prev = NULL; - dev->tree.erased = dev->tree.erased->u.list.next; - if(dev->tree.erased == NULL) - dev->tree.erased_tail = NULL; - dev->tree.erased_count--; - } - - return node; -} - -TreeNode * uffs_TreeGetErasedNode(uffs_Device *dev) -{ - TreeNode *node = uffs_TreeGetErasedNodeNoCheck(dev); - u16 block; - - if (node && node->u.list.u.need_check) { - block = node->u.list.block; - if (uffs_FlashCheckErasedBlock(dev, block) != U_SUCC) { - // Hmm, this block is not fully erased ? erase it immediately. - uffs_FlashEraseBlock(dev, block); - node->u.list.u.need_check = 0; - } - } - return node; -} - -static void _InsertToEntry(uffs_Device *dev, u16 *entry, - int hash, TreeNode *node) -{ - node->hash_next = entry[hash]; - node->hash_prev = EMPTY_NODE; - if (entry[hash] != EMPTY_NODE) { - FROM_IDX(entry[hash], TPOOL(dev))->hash_prev = TO_IDX(node, TPOOL(dev)); - } - entry[hash] = TO_IDX(node, TPOOL(dev)); -} - - -/** - * break the node from entry - */ -void uffs_BreakFromEntry(uffs_Device *dev, u8 type, TreeNode *node) -{ - u16 *entry; - int hash; - TreeNode *work; - - switch (type) { - case UFFS_TYPE_DIR: - hash = GET_DIR_HASH(node->u.dir.serial); - entry = &(dev->tree.dir_entry[hash]); - break; - case UFFS_TYPE_FILE: - hash = GET_FILE_HASH(node->u.file.serial); - entry = &(dev->tree.file_entry[hash]); - break; - case UFFS_TYPE_DATA: - hash = GET_DATA_HASH(node->u.data.parent, node->u.data.serial); - entry = &(dev->tree.data_entry[hash]); - break; - default: - uffs_Perror(UFFS_MSG_SERIOUS, "unknown type when break..."); - return; - } - - if (node->hash_prev != EMPTY_NODE) { - work = FROM_IDX(node->hash_prev, &(dev->mem.tree_pool)); - work->hash_next = node->hash_next; - } - if (node->hash_next != EMPTY_NODE) { - work = FROM_IDX(node->hash_next, &(dev->mem.tree_pool)); - work->hash_prev = node->hash_prev; - } - - if (*entry == TO_IDX(node, &(dev->mem.tree_pool))) { - *entry = node->hash_next; - } -} - -static void uffs_InsertToFileEntry(uffs_Device *dev, TreeNode *node) -{ - _InsertToEntry(dev, dev->tree.file_entry, - GET_FILE_HASH(node->u.file.serial), - node); -} - -static void uffs_InsertToDirEntry(uffs_Device *dev, TreeNode *node) -{ - _InsertToEntry(dev, dev->tree.dir_entry, - GET_DIR_HASH(node->u.dir.serial), - node); -} - -static void uffs_InsertToDataEntry(uffs_Device *dev, TreeNode *node) -{ - _InsertToEntry(dev, dev->tree.data_entry, - GET_DATA_HASH(node->u.data.parent, node->u.data.serial), - node); -} - -void uffs_InsertToErasedListHead(uffs_Device *dev, TreeNode *node) -{ - struct uffs_TreeSt *tree; - tree = &(dev->tree); - - node->u.list.next = tree->erased; - node->u.list.prev = NULL; - - if (tree->erased) { - tree->erased->u.list.prev = node; - } - - tree->erased = node; - if (node->u.list.next == tree->erased_tail) { - tree->erased_tail = node; - } - tree->erased_count++; -} - -/** - * insert node to erased list. - * \param need_check: 0 - no need to check later - * 1 - need to check later - * < 0 - keep 'node->u.list.need_check' value - */ -void uffs_TreeInsertToErasedListTailEx(uffs_Device *dev, TreeNode *node, int need_check) -{ - struct uffs_TreeSt *tree; - tree = &(dev->tree); - - if (need_check >= 0) - node->u.list.u.need_check = need_check; - - node->u.list.next = NULL; - node->u.list.prev = tree->erased_tail; - if (tree->erased_tail) { - tree->erased_tail->u.list.next = node; - } - - tree->erased_tail = node; - if(tree->erased == NULL) { - tree->erased = node; - } - tree->erased_count++; -} - -void uffs_TreeInsertToErasedListTail(uffs_Device *dev, TreeNode *node) -{ - // this function is called after the block is erased, so don't need to check. - uffs_TreeInsertToErasedListTailEx(dev, node, 0); -} - -void uffs_TreeInsertToBadBlockList(uffs_Device *dev, TreeNode *node) -{ - struct uffs_TreeSt *tree; - - tree = &(dev->tree); - node->u.list.prev = NULL; - node->u.list.next = tree->bad; - - if (tree->bad) { - tree->bad->u.list.prev = node; - } - - tree->bad = node; - tree->bad_count++; -} - -/** - * set tree node block value - */ -void uffs_TreeSetNodeBlock(u8 type, TreeNode *node, u16 block) -{ - switch (type) { - case UFFS_TYPE_FILE: - node->u.file.block = block; - break; - case UFFS_TYPE_DIR: - node->u.dir.block = block; - break; - case UFFS_TYPE_DATA: - node->u.data.block = block; - break; - } -} - diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_utils.c b/components/dfs/filesystems/uffs/src/uffs/uffs_utils.c deleted file mode 100644 index bf3ea3b6d1..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_utils.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_utils.c - * \brief utilities of uffs - * \author Ricky Zheng, created 12th May, 2005 - */ -#include "uffs_config.h" -#include "uffs/uffs_device.h" -#include "uffs/uffs_utils.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_version.h" -#include "uffs/uffs_badblock.h" -#include "uffs/uffs_fd.h" -#include "uffs/uffs_fs.h" - -#include <stdio.h> -#include <string.h> - -#define PFX "util: " - -#define SPOOL(dev) &((dev)->mem.spare_pool) - -#ifdef CONFIG_USE_GLOBAL_FS_LOCK -static OSSEM _global_lock = OSSEM_NOT_INITED; - -/* global file system lock */ -void uffs_InitGlobalFsLock(void) -{ - uffs_SemCreate(&_global_lock); -} - -void uffs_ReleaseGlobalFsLock(void) -{ - uffs_SemDelete(&_global_lock); -} - -void uffs_GlobalFsLockLock(void) -{ - uffs_SemWait(_global_lock); -} - -void uffs_GlobalFsLockUnlock(void) -{ - uffs_SemSignal(_global_lock); -} - -#else - -void uffs_InitGlobalFsLock(void) {} -void uffs_ReleaseGlobalFsLock(void) {} -void uffs_GlobalFsLockLock(void) {} -void uffs_GlobalFsLockUnlock(void) {} - -#endif - - -#ifdef CONFIG_ENABLE_BAD_BLOCK_VERIFY -static void _ForceFormatAndCheckBlock(uffs_Device *dev, int block) -{ - int i, j; - uffs_Buf *buf = NULL; - UBOOL bad = U_TRUE; - URET ret; - struct uffs_FlashOpsSt *ops = dev->ops; - struct uffs_TagStoreSt ts; - u8 *spare = NULL; - - buf = uffs_BufClone(dev, NULL); - if (buf == NULL) { - uffs_Perror(UFFS_MSG_SERIOUS, - "Alloc page buffer fail ! Format stoped."); - goto ext; - } - - spare = (u8 *)uffs_PoolGet(SPOOL(dev)); - if (spare == NULL) - goto ext; - - //step 1: Erase, fully fill with 0x0, and check - ret = uffs_FlashEraseBlock(dev, block); - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - goto bad_out; - - memset(buf->header, 0, dev->com.pg_size); - memset(&ts, 0, sizeof(ts)); - memset(spare, 0, dev->attr->spare_size); - - for (i = 0; i < dev->attr->pages_per_block; i++) { - if (ops->WritePageWithLayout) - ret = ops->WritePageWithLayout(dev, block, i, buf->header, dev->com.pg_size, NULL, &ts); - else - ret = ops->WritePage(dev, block, i, buf->header, dev->com.pg_size, spare, dev->attr->spare_size); - - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - goto bad_out; - } - for (i = 0; i < dev->attr->pages_per_block; i++) { - memset(buf->header, 0xFF, dev->com.pg_size); - memset(&ts, 0xFF, sizeof(ts)); - memset(spare, 0xFF, dev->attr->spare_size); - - if (ops->ReadPageWithLayout) { - ret = ops->ReadPageWithLayout(dev, block, i, buf->header, dev->com.pg_size, NULL, &ts, NULL); - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - goto bad_out; - for (j = 0; j < dev->com.pg_size; j++) - if (buf->header[j] != 0) - goto bad_out; - for (j = 0; j < sizeof(ts); j++) - if (((u8 *)&ts)[j] != 0) - goto bad_out; - } - else { - ret = ops->ReadPage(dev, block, i, buf->header, dev->com.pg_size, NULL, spare, dev->attr->spare_size); - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - goto bad_out; - for (j = 0; j < dev->com.pg_size; j++) - if (buf->header[j] != 0) - goto bad_out; - for (j = 0; j < dev->attr->spare_size; j++) - if (spare[j] != 0) - goto bad_out; - } - } - - //step 2: Erase, and check - ret = uffs_FlashEraseBlock(dev, block); - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - goto bad_out; - - for (i = 0; i < dev->attr->pages_per_block; i++) { - memset(buf->header, 0, dev->com.pg_size); - memset(&ts, 0, sizeof(ts)); - memset(spare, 0, dev->attr->spare_size); - - if (ops->ReadPageWithLayout) { - ret = ops->ReadPageWithLayout(dev, block, i, buf->header, dev->com.pg_size, NULL, &ts, NULL); - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - goto bad_out; - for (j = 0; j < dev->com.pg_size; j++) - if (buf->header[j] != 0xFF) - goto bad_out; - for (j = 0; j < sizeof(ts); j++) - if (((u8 *)&ts)[j] != 0xFF) - goto bad_out; - } - else { - ret = ops->ReadPage(dev, block, i, buf->header, dev->com.pg_size, NULL, spare, dev->attr->spare_size); - if (UFFS_FLASH_IS_BAD_BLOCK(ret)) - goto bad_out; - for (j = 0; j < dev->com.pg_size; j++) - if (buf->header[j] != 0xFF) - goto bad_out; - for (j = 0; j < dev->attr->spare_size; j++) - if (spare[j] != 0xFF) - goto bad_out; - } - } - - // format succ - bad = U_FALSE; - -bad_out: - if (bad == U_TRUE) - uffs_FlashMarkBadBlock(dev, block); -ext: - if (buf) - uffs_BufFreeClone(dev, buf); - - if (spare) - uffs_PoolPut(SPOOL(dev), spare); - - return; -} -#endif - - - -URET uffs_FormatDevice(uffs_Device *dev, UBOOL force) -{ - u16 i, slot; - URET ret = U_SUCC; - - if (dev == NULL) - return U_FAIL; - - if (dev->ops == NULL) - return U_FAIL; - - uffs_GlobalFsLockLock(); - - ret = uffs_BufFlushAll(dev); - - if (dev->ref_count > 1 && !force) { - uffs_Perror(UFFS_MSG_NORMAL, - "can't format when dev->ref_count = %d", - dev->ref_count); - ret = U_FAIL; - } - - if (ret == U_SUCC && force) { - uffs_DirEntryBufPutAll(dev); - uffs_PutAllObjectBuf(dev); - uffs_FdSignatureIncrease(); - } - - if (ret == U_SUCC && - uffs_BufIsAllFree(dev) == U_FALSE && - !force) - { - uffs_Perror(UFFS_MSG_NORMAL, "some page still in used!"); - ret = U_FAIL; - } - - if (!force) { - for (slot = 0; ret == U_SUCC && slot < dev->cfg.dirty_groups; slot++) { - if (dev->buf.dirtyGroup[slot].count > 0) { - uffs_Perror(UFFS_MSG_SERIOUS, "there still have dirty pages!"); - ret = U_FAIL; - } - } - } - - if (ret == U_SUCC) - uffs_BufSetAllEmpty(dev); - - - if (ret == U_SUCC && uffs_BlockInfoIsAllFree(dev) == U_FALSE && !force) { - uffs_Perror(UFFS_MSG_NORMAL, - "there still have block info cache ? fail to format"); - ret = U_FAIL; - } - - if (ret == U_SUCC) - uffs_BlockInfoExpireAll(dev); - - for (i = dev->par.start; ret == U_SUCC && i <= dev->par.end; i++) { - if (uffs_FlashIsBadBlock(dev, i) == U_FALSE) { - uffs_FlashEraseBlock(dev, i); - if (HAVE_BADBLOCK(dev)) - uffs_BadBlockProcess(dev, NULL); - } - else { -#ifdef CONFIG_ENABLE_BAD_BLOCK_VERIFY - _ForceFormatAndCheckBlock(dev, i); -#endif - } - } - - if (ret == U_SUCC && uffs_TreeRelease(dev) == U_FAIL) { - ret = U_FAIL; - } - - if (ret == U_SUCC && uffs_TreeInit(dev) == U_FAIL) { - ret = U_FAIL; - } - - if (ret == U_SUCC && uffs_BuildTree(dev) == U_FAIL) { - ret = U_FAIL; - } - - uffs_GlobalFsLockUnlock(); - - return ret; -} - -static const char * GetTagName(struct uffs_TagStoreSt *s) -{ - const char *name = "UNKNOWN"; - struct uffs_NodeTypeNameMapSt maps[] = UFFS_TYPE_NAME_MAP; - int i; - - for (i = 0; i < ARRAY_SIZE(maps); i++) { - if (s->type == maps[i].type) - name = maps[i].name; - } - - return name; -} - -static void DumpBufHex(struct uffs_DeviceSt *dev, const u8* buf, int len, dump_msg_cb *dump) -{ - int i; - for (i = 0; i < len; i++) - dump(dev, "%02X ", buf[i]); -} - -// return -1 if do not need to read next tag -static int DumpTag(struct uffs_DeviceSt *dev, int block, int page, uffs_Tags *tag, dump_msg_cb *dump) -{ - struct uffs_TagStoreSt *s = &tag->s; - struct uffs_MiniHeaderSt header; - URET ret; - - if (!TAG_IS_DIRTY(tag)) { - // is a clean page ? - ret = uffs_LoadMiniHeader(dev, block, page, &header); - if (ret == U_FAIL) { - dump(dev, "Fail to load mini header from page 0\n"); - } - else { - if (header.status == 0xFF) - dump(dev, "page %d CLEAN\n", page); - else { - dump(dev, "page %d NOT clean ! header: ", page); - DumpBufHex(dev, (u8 *)&header, sizeof(header), dump); - dump(dev, ", tag: "); - DumpBufHex(dev, (u8 *)s, sizeof(struct uffs_TagStoreSt), dump); - dump(dev, "\n"); - } - } - return -1; - } - - dump(dev, " - page %2d/%2d %s %d/%d len%4d\n", page, s->page_id, GetTagName(s), s->serial, s->parent, s->data_len); - - return 0; -} - -static void DumpBlock(struct uffs_DeviceSt *dev, int block, dump_msg_cb *dump) -{ - int i; - struct uffs_StorageAttrSt *attr = dev->attr; - uffs_Tags tag; - URET ret; - - dump(dev, "--- Block %d ---\n", block); - - if (uffs_FlashIsBadBlock(dev, block)) { - dump(dev, "Bad block\n\n"); - return; - } - - for (i = 0; i < attr->pages_per_block; i++) { - - memset(&tag, 0xFF, sizeof(tag)); - ret = uffs_FlashReadPageTag(dev, block, i, &tag); - - if (ret == UFFS_FLASH_IO_ERR) { - dump(dev, "page %d tag I/O error\n", i); - continue; - } - else if (ret == UFFS_FLASH_ECC_FAIL) { - dump(dev, "page %d tag ECC error\n", i); - continue; - } - else if (ret == UFFS_FLASH_NO_ERR || ret == UFFS_FLASH_ECC_OK) { - if (ret == UFFS_FLASH_ECC_OK) - dump(dev, "page %d tag has bit flip, corrected by ECC\n", i); - - if (DumpTag(dev, block, i, &tag, dump) == 0) - continue; - else - break; - } - else { - dump(dev, "read page %d tag return unexpected: %d\n", i, ret); - continue; - } - } - dump(dev, "\n"); -} - -void uffs_DumpDevice(struct uffs_DeviceSt *dev, dump_msg_cb *dump) -{ - int i; - for (i = dev->par.start; i <= dev->par.end; i++) { - DumpBlock(dev, i, dump); - } -} diff --git a/components/dfs/filesystems/uffs/src/uffs/uffs_version.c b/components/dfs/filesystems/uffs/src/uffs/uffs_version.c deleted file mode 100644 index e6cd98e3f3..0000000000 --- a/components/dfs/filesystems/uffs/src/uffs/uffs_version.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_version.c - * \brief uffs version information - * \author Ricky Zheng, created 8th May, 2005 - */ - -#include "uffs_config.h" -#include "uffs/uffs_version.h" - -#include <stdio.h> -#define PFX "ver : " - - -static char version_buf[16]; - -const char * uffs_Version2Str(int ver) -{ - sprintf(version_buf, "%1d.%02d.%04d", - (ver & 0xff000000) >> 24, (ver & 0xff0000) >> 16, (ver & 0xffff)); - return version_buf; -} - -int uffs_GetVersion(void) -{ - return UFFS_VERSION; -} - -int uffs_GetMainVersion(int ver) -{ - return (ver & 0xff000000) >> 24; -} - -int uffs_GetMinorVersion(int ver) -{ - return (ver & 0xff0000) >> 16; -} - -int uffs_GetTrivialVersion(int ver) -{ - return (ver & 0xff00) >> 8; -}
\ No newline at end of file diff --git a/components/dfs/filesystems/uffs/src/utils/CMakeLists.txt b/components/dfs/filesystems/uffs/src/utils/CMakeLists.txt deleted file mode 100644 index 37660d6f47..0000000000 --- a/components/dfs/filesystems/uffs/src/utils/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -IF (UNIX) - INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/posix) -ENDIF() -IF (WIN32) - INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/platform/win32) -ENDIF() -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/inc) -INCLUDE_DIRECTORIES(${uffs_SOURCE_DIR}/src/emu) - -LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/emu) -LINK_DIRECTORIES(${uffs_BINARY_DIR}/src/uffs) - -SET(mkuffs_SRCS mkuffs.c) -ADD_EXECUTABLE(mkuffs ${mkuffs_SRCS}) -TARGET_LINK_LIBRARIES(mkuffs emu uffs emu platform apitest_server) -IF (UNIX) - TARGET_LINK_LIBRARIES(mkuffs pthread) -ENDIF () - - diff --git a/components/dfs/filesystems/uffs/src/utils/mkuffs.c b/components/dfs/filesystems/uffs/src/utils/mkuffs.c deleted file mode 100644 index 3f92069fe2..0000000000 --- a/components/dfs/filesystems/uffs/src/utils/mkuffs.c +++ /dev/null @@ -1,493 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_test.c - * \brief uffs test main entry - * \author Ricky Zheng - */ - -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include "uffs_config.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" -#include "uffs/uffs_fs.h" -#include "uffs/uffs_utils.h" -#include "uffs/uffs_core.h" -#include "uffs/uffs_mtb.h" - -#include "cmdline.h" -#include "uffs_fileem.h" - -#define PFX NULL -#define MSG(msg,...) uffs_PerrorRaw(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) -#define MSGLN(msg,...) uffs_Perror(UFFS_MSG_NORMAL, msg, ## __VA_ARGS__) - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR > 0 -int main() -{ - MSGLN("Static memory allocator is not supported."); - return 0; -} -#else - -extern struct cli_commandset * get_helper_cmds(void); -extern struct cli_commandset * get_test_cmds(void); -extern void femu_init_uffs_device(uffs_Device *dev); - -static int conf_command_line_mode = 0; -static int conf_verbose_mode = 0; - -static int conf_exec_script = 0; -static char script_command[256]; - -#define DEFAULT_EMU_FILENAME "uffsemfile.bin" -const char * conf_emu_filename = DEFAULT_EMU_FILENAME; - - -/* default basic parameters of the NAND device */ -#define PAGES_PER_BLOCK_DEFAULT 32 -#define PAGE_DATA_SIZE_DEFAULT 512 -#define PAGE_SPARE_SIZE_DEFAULT 16 -#define STATUS_BYTE_OFFSET_DEFAULT 5 -#define TOTAL_BLOCKS_DEFAULT 128 -#define ECC_OPTION_DEFAULT UFFS_ECC_SOFT -//#define ECC_OPTION_DEFAULT UFFS_ECC_HW -//#define ECC_OPTION_DEFAULT UFFS_ECC_HW_AUTO - -#define MAX_MOUNT_TABLES 10 -#define MAX_MOUNT_POINT_NAME 32 - -static int conf_pages_per_block = PAGES_PER_BLOCK_DEFAULT; -static int conf_page_data_size = PAGE_DATA_SIZE_DEFAULT; -static int conf_page_spare_size = PAGE_SPARE_SIZE_DEFAULT; -static int conf_status_byte_offset = STATUS_BYTE_OFFSET_DEFAULT; -static int conf_total_blocks = TOTAL_BLOCKS_DEFAULT; -static int conf_ecc_option = ECC_OPTION_DEFAULT; -static int conf_ecc_size = 0; // 0 - Let UFFS choose the size - -static const char *g_ecc_option_strings[] = UFFS_ECC_OPTION_STRING; - -static struct uffs_MountTableEntrySt conf_mounts[MAX_MOUNT_TABLES] = {{0}}; -static uffs_Device conf_devices[MAX_MOUNT_TABLES] = {{0}}; -static char mount_point_name[MAX_MOUNT_TABLES][MAX_MOUNT_POINT_NAME] = {{0}}; - -static void setup_storage(struct uffs_StorageAttrSt *attr) -{ - attr->total_blocks = conf_total_blocks; /* total blocks */ - attr->page_data_size = conf_page_data_size; /* page data size */ - attr->spare_size = conf_page_spare_size; /* page spare size */ - attr->pages_per_block = conf_pages_per_block; /* pages per block */ - - attr->block_status_offs = conf_status_byte_offset; /* block status offset is 5th byte in spare */ - attr->ecc_opt = conf_ecc_option; /* ECC option */ - attr->ecc_size = conf_ecc_size; /* ECC size */ - attr->layout_opt = UFFS_LAYOUT_UFFS; /* let UFFS handle layout */ -} - - -static void setup_device(uffs_Device *dev) -{ - dev->Init = femu_InitDevice; - dev->Release = femu_ReleaseDevice; - dev->attr = femu_GetStorage(); -} - -static void setup_emu_private(uffs_FileEmu *emu) -{ - memset(emu, 0, sizeof(uffs_FileEmu)); - emu->emu_filename = conf_emu_filename; -} - -static int init_uffs_fs(void) -{ - static int bIsFileSystemInited = 0; - struct uffs_MountTableEntrySt *mtbl = &(conf_mounts[0]); - struct uffs_ConfigSt cfg = { - 0, // bc_caches - default - 0, // page_buffers - default - 0, // dirty_pages - default - 0, // dirty_groups - default - 0, // reserved_free_blocks - default - }; - - if (bIsFileSystemInited) - return -4; - - bIsFileSystemInited = 1; - - while (mtbl->dev) { - - memcpy(&mtbl->dev->cfg, &cfg, sizeof(struct uffs_ConfigSt)); - -#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0 - uffs_MemSetupSystemAllocator(&mtbl->dev->mem); -#endif - setup_device(mtbl->dev); - uffs_RegisterMountTable(mtbl); - mtbl++; - } - - // mount partitions - for (mtbl = &(conf_mounts[0]); mtbl->mount != NULL; mtbl++) { - uffs_Mount(mtbl->mount); - } - - return uffs_InitFileSystemObjects() == U_SUCC ? 0 : -1; -} - -static int release_uffs_fs(void) -{ - int ret = 0; - uffs_MountTable *mtb; - - for (mtb = &(conf_mounts[0]); ret == 0 && mtb->mount != NULL; mtb++) { - uffs_UnMount(mtb->mount); - } - - if (ret == 0) - ret = (uffs_ReleaseFileSystemObjects() == U_SUCC ? 0 : -1); - - return ret; -} - -/* mount point arg: /sys/,100,-1 */ -static int parse_mount_point(char *arg, int m_idx) -{ - int start = 0, end = -1; - char *p = arg; - struct uffs_MountTableEntrySt *mtbl = &(conf_mounts[m_idx]); - - while(*p && *p != ',' && *p != ' ' && *p != '\t') - p++; - - if (*p == 0 || p == arg) - return -1; - - mtbl->mount = &(mount_point_name[m_idx][0]); - memcpy((char *)mtbl->mount, arg, p - arg); - ((char *)(mtbl->mount))[p - arg] = 0; - - p++; - arg = p; - while(*p && *p != ',' && *p != ' ' && *p != '\t') - p++; - - if (p != arg) { - if (sscanf(arg, "%i", &start) < 1) - return -1; - p++; - arg = p; - - while(*p && *p != ',' && *p != ' ' && *p != '\t') - p++; - - if (p != arg) { - if (sscanf(arg, "%i", &end) < 1) - return -1; - } - } - mtbl->start_block = start; - mtbl->end_block = end; - mtbl->dev = &(conf_devices[m_idx]); - - return 0; -} - -static int parse_options(int argc, char *argv[]) -{ - int iarg; - int usage = 0; - int m_idx = 0; - static char em_file[128]; - int i; - - for (iarg = 1; iarg < argc && !usage; iarg++) { - const char *arg = argv[iarg]; - - if (arg[0] == '-') { - if (!strcmp(arg, "-h") || !strcmp(arg, "--help")) { - usage++; - } - else if (!strcmp(arg, "-f") || !strcmp(arg, "--file")) { - if (++iarg >= argc) - usage++; - else { - strcpy(em_file, argv[iarg]); - conf_emu_filename = (const char *)em_file; - } - } - else if (!strcmp(arg, "-c") || !strcmp(arg, "--command-line")) { - conf_command_line_mode = 1; - } - else if (!strcmp(arg, "-p") || !strcmp(arg, "--page-size")) { - if (++iarg >= argc) - usage++; - else if (sscanf(argv[iarg], "%i", &conf_page_data_size) < 1) - usage++; - if (conf_page_data_size <= 0 || conf_page_data_size > UFFS_MAX_PAGE_SIZE) { - MSGLN("ERROR: Invalid page data size"); - usage++; - } - } - else if (!strcmp(arg, "-s") || !strcmp(arg, "--spare-size")) { - if (++iarg >= argc) - usage++; - else if (sscanf(argv[iarg], "%i", &conf_page_spare_size) < 1) - usage++; - if (conf_page_spare_size < sizeof(struct uffs_TagStoreSt) + 1 || - (conf_page_spare_size % 4) != 0 || conf_page_spare_size > UFFS_MAX_SPARE_SIZE) { - MSGLN("ERROR: Invalid spare size"); - usage++; - } - } - else if (!strcmp(arg, "-o") || !strcmp(arg, "--status-offset")) { - if (++iarg >= argc) - usage++; - else if (sscanf(argv[iarg], "%i", &conf_status_byte_offset) < 1) - usage++; - if (conf_status_byte_offset < 0) - usage++; - } - else if (!strcmp(arg, "-b") || !strcmp(arg, "--block-pages")) { - if (++iarg >= argc) - usage++; - else if (sscanf(argv[iarg], "%i", &conf_pages_per_block) < 1) - usage++; - if (conf_pages_per_block < 2) - usage++; - } - else if (!strcmp(arg, "-t") || !strcmp(arg, "--total-blocks")) { - if (++iarg >= argc) - usage++; - else if (sscanf(argv[iarg], "%i", &conf_total_blocks) < 1) - usage++; - if (conf_total_blocks < 2) - usage++; - } - else if (!strcmp(arg, "-v") || !strcmp(arg, "--verbose")) { - conf_verbose_mode++; - } - else if (!strcmp(arg, "-m") || !strcmp(arg, "--mount")) { - if (++iarg > argc) - usage++; - else if (parse_mount_point(argv[iarg], m_idx) < 0) - usage++; - m_idx++; - } - else if (!strcmp(arg, "-e") || !strcmp(arg, "--exec")) { - if (++iarg > argc) - usage++; - else { - sprintf(script_command, "script %s", argv[iarg]); - conf_exec_script = 1; - } - } - else if (!strcmp(arg, "-x") || !strcmp(arg, "--ecc-option")) { - if (++iarg > argc) - usage++; - else { - for (i = 0; i < ARRAY_SIZE(g_ecc_option_strings); i++) { - if (!strcmp(argv[iarg], g_ecc_option_strings[i])) { - conf_ecc_option = i; - break; - } - } - if (i == ARRAY_SIZE(g_ecc_option_strings)) { - MSGLN("ERROR: Invalid ECC option"); - usage++; - } - } - } - else if (!strcmp(arg, "-z") || !strcmp(arg, "--ecc-size")) { - if (++iarg >= argc) - usage++; - else if (sscanf(argv[iarg], "%i", &conf_ecc_size) < 1) - usage++; - if (conf_ecc_size < 0 || conf_ecc_size > UFFS_MAX_ECC_SIZE) { - MSGLN("ERROR: Invalid ecc size"); - usage++; - } - } - else { - MSGLN("Unknown option: %s, try %s --help", arg, argv[0]); - return -1; - } - } - else { - MSGLN("Unexpected parameter: %s, try %s --help", arg, argv[0]); - return -1; - } - } - - if (usage) { - MSGLN("Usage: %s [options]", argv[0]); - MSGLN(" -h --help show usage"); - MSGLN(" -c --command-line command line mode"); - MSGLN(" -v --verbose verbose mode"); - MSGLN(" -f --file <file> uffs image file"); - MSGLN(" -p --page-size <n> page data size, default=%d", PAGE_DATA_SIZE_DEFAULT); - MSGLN(" -s --spare-size <n> page spare size, default=%d", PAGE_SPARE_SIZE_DEFAULT); - MSGLN(" -o --status-offset <n> status byte offset, default=%d", STATUS_BYTE_OFFSET_DEFAULT); - MSGLN(" -b --block-pages <n> pages per block, default=%d", PAGES_PER_BLOCK_DEFAULT); - MSGLN(" -t --total-blocks <n> total blocks"); - MSGLN(" -m --mount <mount_point,start,end> , for example: -m /,0,-1"); - MSGLN(" -x --ecc-option <none|soft|hw|auto> ECC option, default=%s", g_ecc_option_strings[ECC_OPTION_DEFAULT]); - MSGLN(" -z --ecc-size <n> ECC size, default=0 (auto)"); - MSGLN(" -e --exec <file> execute a script file"); - MSGLN(""); - - return -1; - } - - if (m_idx == 0) { - // if not given mount information, use default ('/' for whole partition) - parse_mount_point("/,0,-1", 0); - } - - return 0; -} - - -static void print_mount_points(void) -{ - struct uffs_MountTableEntrySt *m; - - m = &(conf_mounts[0]); - while (m->dev) { - MSGLN ("Mount point: %s, start: %d, end: %d", m->mount, m->start_block, m->end_block); - m++; - } -} - -static void print_params(void) -{ - MSGLN("Parameters summary:"); - MSGLN(" uffs image file: %s", conf_emu_filename); - MSGLN(" page size: %d", conf_page_data_size); - MSGLN(" page spare size: %d", conf_page_spare_size); - MSGLN(" pages per block: %d", conf_pages_per_block); - MSGLN(" total blocks: %d", conf_total_blocks); - MSGLN(" ecc option: %d (%s)", conf_ecc_option, g_ecc_option_strings[conf_ecc_option]); - MSGLN(" ecc size: %d%s", conf_ecc_size, conf_ecc_size == 0 ? " (auto)" : ""); - MSGLN(" bad block status offset: %d", conf_status_byte_offset); - MSGLN(""); -} - -#ifdef UNIX -#include <execinfo.h> -#include <signal.h> -void crash_handler(int sig) -{ - void *array[10]; - size_t size; - - // get void*'s for all entries on the stack - size = backtrace(array, 10); - - // print out all the frames to stderr - fprintf(stderr, "Error: signal %d:\n", sig); - backtrace_symbols_fd(array, size, 2); - exit(1); -} -#endif - -int main(int argc, char *argv[]) -{ - int ret; - -#ifdef UNIX - signal(SIGSEGV, crash_handler); -#endif - - uffs_SetupDebugOutput(); // setup debug output as early as possible - - if (parse_options(argc, argv) < 0) { - return -1; - } - - if (conf_verbose_mode) { - #if 1 - MSGLN("Internal data structure size:"); - MSGLN(" TreeNode: %d", sizeof(TreeNode)); - MSGLN(" struct BlockListSt: %d", sizeof(struct BlockListSt)); - MSGLN(" struct DirhSt: %d", sizeof(struct DirhSt)); - MSGLN(" struct FilehSt: %d", sizeof(struct FilehSt)); - MSGLN(" struct FdataSt: %d", sizeof(struct FdataSt)); - MSGLN(" struct uffs_TagStoreSt: %d", sizeof(struct uffs_TagStoreSt)); - MSGLN(" uffs_Buf: %d", sizeof(uffs_Buf)); - MSGLN(" struct uffs_BlockInfoSt: %d", sizeof(struct uffs_BlockInfoSt)); - MSGLN(""); - #endif - print_params(); - print_mount_points(); - } - - // setup file emulator storage with parameters from command line - setup_storage(femu_GetStorage()); - - // setup file emulator private data - setup_emu_private(femu_GetPrivate()); - - ret = init_uffs_fs(); - if (ret != 0) { - MSGLN ("Init file system fail: %d", ret); - return -1; - } - - cli_add_commandset(get_helper_cmds()); - cli_add_commandset(get_test_cmds()); - if (conf_command_line_mode) { - if (conf_exec_script) { - cli_interpret(script_command); - } - cli_main_entry(); - } - else { - if (conf_exec_script) { - cli_interpret(script_command); - } - else { - cli_main_entry(); - } - } - - release_uffs_fs(); - - return 0; -} -#endif - - - diff --git a/components/dfs/filesystems/uffs/tools/chomp_uffs_perror.rb b/components/dfs/filesystems/uffs/tools/chomp_uffs_perror.rb deleted file mode 100644 index e8b9460ae5..0000000000 --- a/components/dfs/filesystems/uffs/tools/chomp_uffs_perror.rb +++ /dev/null @@ -1,25 +0,0 @@ -#usage: -# find . -name "*.c" | xargs /usr/bin/ruby path/to/chomp_uffs_perror.rb -# - -ARGV.each do |file| - lines = [] - count = 0 - File.open(file).each_line do |line| - if line =~ /^(.*uffs_Perror.+)PFX(\s*".+)$/ - lines << ($1 + $2) - count += 1 - #puts ($1 + $2) - else - lines << line - end - end - if count > 0 - f = File.open(file, "w") - lines.each do |s| - f.puts s - end - f.close - puts "Fix file #{file}, modified lines: #{count}" - end -end diff --git a/components/dfs/filesystems/uffs/tools/format_code.rb b/components/dfs/filesystems/uffs/tools/format_code.rb deleted file mode 100644 index 7847db236a..0000000000 --- a/components/dfs/filesystems/uffs/tools/format_code.rb +++ /dev/null @@ -1,24 +0,0 @@ -#usage: -# find . -name "*.c" | xargs /usr/bin/ruby path/to/format_code.rb -# - -ARGV.each do |file| - lines = [] - count = 0 - File.open(file).each_line do |line| - if line =~ /^(.*)\s$/ - lines << $1.dup - count += 1 - else - lines << line - end - end - if count > 0 - f = File.open(file, "w") - lines.each do |s| - f.puts s - end - f.close - puts "Fix file #{file}, modified lines: #{count}" - end -end diff --git a/components/dfs/filesystems/uffs/tools/make_package.sh b/components/dfs/filesystems/uffs/tools/make_package.sh deleted file mode 100644 index a78c3fa2fd..0000000000 --- a/components/dfs/filesystems/uffs/tools/make_package.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -git ls-tree --name-only --full-name -r $1 | xargs tar -jcvf uffs-$1.tar.bz2
\ No newline at end of file diff --git a/components/dfs/filesystems/uffs/uffs_config.h b/components/dfs/filesystems/uffs/uffs_config.h deleted file mode 100644 index 2f0b6992bb..0000000000 --- a/components/dfs/filesystems/uffs/uffs_config.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_config.h - * \brief basic configuration of uffs - * \author Ricky Zheng - */ - -#ifndef _UFFS_CONFIG_H_ -#define _UFFS_CONFIG_H_ - -/** - * \def UFFS_MAX_PAGE_SIZE - * \note maximum page size UFFS support - */ -#define UFFS_MAX_PAGE_SIZE 2048 - -/** - * \def UFFS_MAX_SPARE_SIZE - */ -#define UFFS_MAX_SPARE_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 8) - -/** - * \def UFFS_MAX_ECC_SIZE - */ -#define UFFS_MAX_ECC_SIZE ((UFFS_MAX_PAGE_SIZE / 256) * 5) - -/** - * \def MAX_CACHED_BLOCK_INFO - * \note uffs cache the block info for opened directories and files, - * a practical value is 5 ~ MAX_OBJECT_HANDLE - */ -#define MAX_CACHED_BLOCK_INFO 50 - -/** - * \def MAX_PAGE_BUFFERS - * \note the bigger value will bring better read/write performance. - * but few writing performance will be improved when this - * value is become larger than 'max pages per block' - */ -#define MAX_PAGE_BUFFERS 40 - - -/** - * \def CLONE_BUFFER_THRESHOLD - * \note reserve buffers for clone. 1 or 2 should be enough. - */ -#define CLONE_BUFFERS_THRESHOLD 2 - -/** - * \def MAX_SPARE_BUFFERS - * \note spare buffers are used for lower level flash operations, - * 5 should be enough. - */ -#define MAX_SPARE_BUFFERS 5 - - -/** - * \def MAX_DIRTY_PAGES_IN_A_BLOCK - * \note this value should be between '2' and the lesser of - * 'max pages per block' and (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1). - * - * the smaller the value the frequently the buffer will be flushed. - */ -#define MAX_DIRTY_PAGES_IN_A_BLOCK 32 - -/** - * \def MAX_DIRTY_BUF_GROUPS - */ -#define MAX_DIRTY_BUF_GROUPS 3 - -/** - * \def CONFIG_ENABLE_UFFS_DEBUG_MSG - * \note Enable debug message output. You must call uffs_InitDebugMessageOutput() - * to initialize debug apart from enable debug feature. - */ -#define CONFIG_ENABLE_UFFS_DEBUG_MSG - -/** - * \def CONFIG_USE_GLOBAL_FS_LOCK - * \note use global lock instead of per-device lock. - * this is required if you use fd APIs in multi-thread environment. - */ -#define CONFIG_USE_GLOBAL_FS_LOCK - - -/** - * \def CONFIG_USE_PER_DEVICE_LOCK - * \note use per-device lock. - * this is required if you use fs APIs in multi-thread environment. - */ -//#define CONFIG_USE_PER_DEVICE_LOCK - - - -/** - * \def CONFIG_USE_STATIC_MEMORY_ALLOCATOR - * \note uffs will use static memory allocator if this is defined. - * to use static memory allocator, you need to provide memory - * buffer when creating uffs_Device. - * - * use UFFS_STATIC_BUFF_SIZE() to calculate memory buffer size. - */ -#define CONFIG_USE_STATIC_MEMORY_ALLOCATOR 0 - -/** - * \def CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR - * \note using system platform's 'malloc' and 'free'. - */ -#define CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR 1 - - - -/** - * \def CONFIG_FLUSH_BUF_AFTER_WRITE - * \note UFFS will write all data directly into flash in - * each 'write' call if you enable this option. - * (which means lesser data lost when power failure but - * poorer writing performance). - * It's not recommended to open this define for normal applications. - */ -#define CONFIG_FLUSH_BUF_AFTER_WRITE - - -/** - * \def CONFIG_UFFS_AUTO_LAYOUT_MTD_COMP - * \note Use Linux MTD compatiable spare placement for UFFS_LAYOUT_AUTO, - * only valid for page data size 512 or 2048. - */ -//#define CONFIG_UFFS_AUTO_LAYOUT_USE_MTD_SCHEME - - -/** - * \def MAX_OBJECT_HANDLE - * maximum number of object handle - */ -#define MAX_OBJECT_HANDLE 50 -#define FD_SIGNATURE_SHIFT 6 - - -/** - * \def MAX_DIR_HANDLE - * maximum number of uffs_DIR - */ -#define MAX_DIR_HANDLE 10 - -/** - * \def MINIMUN_ERASED_BLOCK - * UFFS will not allow appending or creating new files when the free/erased block - * is lower then MINIMUN_ERASED_BLOCK. - */ -#define MINIMUN_ERASED_BLOCK 2 - -/** - * \def CONFIG_CHANGE_MODIFY_TIME - * \note If defined, closing a file which is opened for writing/appending will - * update the file's modify time as well. Disable this feature will save a - * lot of writing activities if you frequently open files for write and close it. - */ -//#define CONFIG_CHANGE_MODIFY_TIME - - -/** - * \def CONFIG_ENABLE_BAD_BLOCK_VERIFY - * \note allow erase and verify block marked as 'bad' when format UFFS partition. - * it's not recommended for most NAND flash. - */ -#define CONFIG_ENABLE_BAD_BLOCK_VERIFY - -/** - * \def CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD - * \note erase block again before mark bad block - */ -//#define CONFIG_ERASE_BLOCK_BEFORE_MARK_BAD - -/** - * \def CONFIG_PAGE_WRITE_VERIFY - * \note verify page data after write, for extra safe data storage. - */ -#define CONFIG_PAGE_WRITE_VERIFY - -/** - * \def CONFIG_BAD_BLOCK_POLICY_STRICT - * \note If this is enabled, UFFS will report the block as 'bad' if any bit-flips found; - * otherwise, UFFS report bad block only when ECC failed or reported - * by low level flash driver. - * - * \note Enable this will ensure your data always be stored on completely good blocks. - */ -#define CONFIG_BAD_BLOCK_POLICY_STRICT - - -/** - * \def CONFIG_ENABLE_PAGE_DATA_CRC - * \note If this is enabled, UFFS save page data CRC16 sum in mini header, - * it provides extra protection for data integrity. - */ -#define CONFIG_ENABLE_PAGE_DATA_CRC - - -/** micros for calculating buffer sizes */ - -/** - * \def UFFS_BLOCK_INFO_BUFFER_SIZE - * \brief calculate memory bytes for block info caches - */ -#define UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) \ - ( \ - ( \ - sizeof(uffs_BlockInfo) + \ - sizeof(uffs_PageSpare) * n_pages_per_block \ - ) * MAX_CACHED_BLOCK_INFO \ - ) - -/** - * \def UFFS_PAGE_BUFFER_SIZE - * \brief calculate memory bytes for page buffers - */ -#define UFFS_PAGE_BUFFER_SIZE(n_page_size) \ - ( \ - ( \ - sizeof(uffs_Buf) + n_page_size \ - ) * MAX_PAGE_BUFFERS \ - ) - -/** - * \def UFFS_TREE_BUFFER_SIZE - * \brief calculate memory bytes for tree nodes - */ -#define UFFS_TREE_BUFFER_SIZE(n_blocks) (sizeof(TreeNode) * n_blocks) - - -#define UFFS_SPARE_BUFFER_SIZE (MAX_SPARE_BUFFERS * UFFS_MAX_SPARE_SIZE) - - -/** - * \def UFFS_STATIC_BUFF_SIZE - * \brief calculate total memory usage of uffs system - */ -#define UFFS_STATIC_BUFF_SIZE(n_pages_per_block, n_page_size, n_blocks) \ - ( \ - UFFS_BLOCK_INFO_BUFFER_SIZE(n_pages_per_block) + \ - UFFS_PAGE_BUFFER_SIZE(n_page_size) + \ - UFFS_TREE_BUFFER_SIZE(n_blocks) + \ - UFFS_SPARE_BUFFER_SIZE \ - ) - - - -/* config check */ -#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD) < 3 -#error "MAX_PAGE_BUFFERS is too small" -#endif - -#if (MAX_DIRTY_PAGES_IN_A_BLOCK < 2) -#error "MAX_DIRTY_PAGES_IN_A_BLOCK should >= 2" -#endif - -#if (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD - 1 < MAX_DIRTY_PAGES_IN_A_BLOCK) -#error "MAX_DIRTY_PAGES_IN_A_BLOCK should < (MAX_PAGE_BUFFERS - CLONE_BUFFERS_THRESHOLD)" -#endif - -#if defined(CONFIG_PAGE_WRITE_VERIFY) && (CLONE_BUFFERS_THRESHOLD < 2) -#error "CLONE_BUFFERS_THRESHOLD should >= 2 when CONFIG_PAGE_WRITE_VERIFY is enabled." -#endif - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 1 -#error "Please enable ONLY one memory allocator" -#endif - -#if CONFIG_USE_STATIC_MEMORY_ALLOCATOR + CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR == 0 -#error "Please enable ONE of memory allocators" -#endif - -#if defined(CONFIG_USE_GLOBAL_FS_LOCK) && defined(CONFIG_USE_PER_DEVICE_LOCK) -#error "enable either CONFIG_USE_GLOBAL_FS_LOCK or CONFIG_USE_PER_DEVICE_LOCK, not both" -#endif - -#if (MAX_OBJECT_HANDLE > (1 << FD_SIGNATURE_SHIFT)) -#error "Please increase FD_SIGNATURE_SHIFT !" -#endif - -#ifdef WIN32 -# pragma warning(disable : 4996) -# pragma warning(disable : 4244) -# pragma warning(disable : 4214) -# pragma warning(disable : 4127) -# pragma warning(disable : 4389) -# pragma warning(disable : 4100) -#endif - -#endif diff --git a/components/dfs/filesystems/uffs/uffs_nandif.c b/components/dfs/filesystems/uffs/uffs_nandif.c deleted file mode 100644 index 00e1bee8d5..0000000000 --- a/components/dfs/filesystems/uffs/uffs_nandif.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * RT-Thread Device Interface for uffs - */ - -#include <rtthread.h> -#include <rtdevice.h> -#include "dfs_uffs.h" - -static int nand_init_flash(uffs_Device *dev) -{ - return UFFS_FLASH_NO_ERR; -} - -static int nand_release_flash(uffs_Device *dev) -{ - return UFFS_FLASH_NO_ERR; -} -static int nand_erase_block(uffs_Device *dev, unsigned block) -{ - int res; - - res = rt_mtd_nand_erase_block(RT_MTD_NAND_DEVICE(dev->_private), block); - - return res == RT_EOK ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR; -} - -#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON) -static int nand_check_block(uffs_Device *dev, unsigned block) -{ - int res; - - res = rt_mtd_nand_check_block(RT_MTD_NAND_DEVICE(dev->_private), block); - - return res == RT_EOK ? UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK; -} - -static int nand_mark_badblock(uffs_Device *dev, unsigned block) -{ - int res; - - res = rt_mtd_nand_mark_badblock(RT_MTD_NAND_DEVICE(dev->_private), block); - - return res == RT_EOK ? UFFS_FLASH_NO_ERR : UFFS_FLASH_IO_ERR; -} -#endif - -#if (RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_NONE) || (RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_SOFT) -static int nand_read_page(uffs_Device *dev, - u32 block, - u32 page, - u8 *data, - int data_len, - u8 *ecc, - rt_uint8_t *spare, - int spare_len) -{ - int res; - - page = block * dev->attr->pages_per_block + page; - if (data == NULL && spare == NULL) - { -#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON) - RT_ASSERT(0); //should not be here -#else - /* check block status: bad or good */ - rt_uint8_t spare[UFFS_MAX_SPARE_SIZE]; - - rt_memset(spare, 0, UFFS_MAX_SPARE_SIZE); - - rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->_private), - page, RT_NULL, 0, - spare, dev->attr->spare_size);//dev->mem.spare_data_size - - res = spare[dev->attr->block_status_offs] == 0xFF ? - UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK; - - return res; -#endif - } - - rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->_private), - page, data, data_len, spare, spare_len); - - return UFFS_FLASH_NO_ERR; -} - -static int nand_write_page(uffs_Device *dev, - u32 block, - u32 page, - const u8 *data, - int data_len, - const u8 *spare, - int spare_len) -{ - int res; - - RT_ASSERT(UFFS_MAX_SPARE_SIZE >= dev->attr->spare_size); - - page = block * dev->attr->pages_per_block + page; - - if (data == NULL && spare == NULL) - { -#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON) - RT_ASSERT(0); //should not be here -#else - /* mark bad block */ - rt_uint8_t spare[UFFS_MAX_SPARE_SIZE]; - - rt_memset(spare, 0xFF, UFFS_MAX_SPARE_SIZE); - spare[dev->attr->block_status_offs] = 0x00; - - res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->_private), - page, RT_NULL, 0, - spare, dev->attr->spare_size);//dev->mem.spare_data_size - if (res != RT_EOK) - goto __error; -#endif - } - - res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->_private), - page, data, data_len, spare, spare_len); - if (res != RT_EOK) - goto __error; - - return UFFS_FLASH_NO_ERR; - -__error: - return UFFS_FLASH_IO_ERR; -} - -const uffs_FlashOps nand_ops = -{ - nand_init_flash, /* InitFlash() */ - nand_release_flash, /* ReleaseFlash() */ - nand_read_page, /* ReadPage() */ - NULL, /* ReadPageWithLayout */ - nand_write_page, /* WritePage() */ - NULL, /* WritePageWithLayout */ -#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON) - nand_check_block, - nand_mark_badblock, -#else - NULL, /* IsBadBlock(), let UFFS take care of it. */ - NULL, /* MarkBadBlock(), let UFFS take care of it. */ -#endif - nand_erase_block, /* EraseBlock() */ -}; - -void uffs_setup_storage(struct uffs_StorageAttrSt *attr, - struct rt_mtd_nand_device *nand) -{ - rt_memset(attr, 0, sizeof(struct uffs_StorageAttrSt)); - -// attr->total_blocks = nand->end_block - nand->start_block + 1;/* no use */ - attr->page_data_size = nand->page_size; /* page data size */ - attr->pages_per_block = nand->pages_per_block; /* pages per block */ - attr->spare_size = nand->oob_size; /* page spare size */ - attr->ecc_opt = RT_CONFIG_UFFS_ECC_MODE; /* ecc option */ - attr->ecc_size = 0; /* ecc size is 0 , the uffs will calculate the ecc size*/ - attr->block_status_offs = attr->ecc_size; /* indicate block bad or good, offset in spare */ - attr->layout_opt = RT_CONFIG_UFFS_LAYOUT; /* let UFFS do the spare layout */ -} - -#elif RT_CONFIG_UFFS_ECC_MODE == UFFS_ECC_HW_AUTO -static int WritePageWithLayout(uffs_Device *dev, - u32 block, - u32 page, - const u8 *data, - int data_len, - const u8 *ecc, //NULL - const uffs_TagStore *ts) -{ - int res; - int spare_len; - rt_uint8_t spare[UFFS_MAX_SPARE_SIZE]; - - RT_ASSERT(UFFS_MAX_SPARE_SIZE >= dev->attr->spare_size); - - page = block * dev->attr->pages_per_block + page; - spare_len = dev->mem.spare_data_size; - - if (data == NULL && ts == NULL) - { -#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON) - RT_ASSERT(0); //should not be here -#else - /* mark bad block */ - rt_memset(spare, 0xFF, UFFS_MAX_SPARE_SIZE); - spare[dev->attr->block_status_offs] = 0x00; - - res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->_private), - page, RT_NULL, 0, - spare, dev->attr->spare_size);//dev->mem.spare_data_size - if (res != RT_EOK) - goto __error; - - dev->st.io_write++; - return UFFS_FLASH_NO_ERR; -#endif - } - - if (data != NULL && data_len != 0) - { - RT_ASSERT(data_len == dev->attr->page_data_size); - - dev->st.page_write_count++; - dev->st.io_write += data_len; - } - - if (ts != RT_NULL) - { - uffs_FlashMakeSpare(dev, ts, RT_NULL, (u8 *)spare); - dev->st.spare_write_count++; - dev->st.io_write += spare_len; - } - - res = rt_mtd_nand_write(RT_MTD_NAND_DEVICE(dev->_private), - page, data, data_len, spare, spare_len); - if (res != RT_EOK) - goto __error; - - return UFFS_FLASH_NO_ERR; - -__error: - return UFFS_FLASH_IO_ERR; -} - -static URET ReadPageWithLayout(uffs_Device *dev, - u32 block, - u32 page, - u8 *data, - int data_len, - u8 *ecc, //NULL - uffs_TagStore *ts, - u8 *ecc_store) //NULL -{ - int res = UFFS_FLASH_NO_ERR; - int spare_len; - rt_uint8_t spare[UFFS_MAX_SPARE_SIZE]; - - RT_ASSERT(UFFS_MAX_SPARE_SIZE >= dev->attr->spare_size); - - page = block * dev->attr->pages_per_block + page; - spare_len = dev->mem.spare_data_size; - - if (data == RT_NULL && ts == RT_NULL) - { -#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON) - RT_ASSERT(0); //should not be here -#else - /* check block good or bad */ - - rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->_private), - page, RT_NULL, 0, - spare, dev->attr->spare_size);//dev->mem.spare_data_size - - dev->st.io_read++; - - res = spare[dev->attr->block_status_offs] == 0xFF ? - UFFS_FLASH_NO_ERR : UFFS_FLASH_BAD_BLK; - return res; -#endif - } - - if (data != RT_NULL) - { - dev->st.io_read += data_len; - dev->st.page_read_count++; - } - - res = rt_mtd_nand_read(RT_MTD_NAND_DEVICE(dev->_private), - page, data, data_len, spare, spare_len); - if (res == 0) - res = UFFS_FLASH_NO_ERR; - else if (res == -1) - { - //TODO ecc correct, add code to use hardware do ecc correct - res = UFFS_FLASH_ECC_OK; - } - else - res = UFFS_FLASH_ECC_FAIL; - - if (ts != RT_NULL) - { - // unload ts and ecc from spare, you can modify it if you like - uffs_FlashUnloadSpare(dev, (const u8 *)spare, ts, RT_NULL); - - if ((spare[spare_len - 1] == 0xFF) && (res == UFFS_FLASH_NO_ERR)) - res = UFFS_FLASH_NOT_SEALED; - - dev->st.io_read += spare_len; - dev->st.spare_read_count++; - } - - return res; -} - -const uffs_FlashOps nand_ops = -{ - nand_init_flash, /* InitFlash() */ - nand_release_flash, /* ReleaseFlash() */ - NULL, /* ReadPage() */ - ReadPageWithLayout, /* ReadPageWithLayout */ - NULL, /* WritePage() */ - WritePageWithLayout,/* WritePageWithLayout */ - -#if defined(RT_UFFS_USE_CHECK_MARK_FUNCITON) - nand_check_block, - nand_mark_badblock, -#else - NULL, /* IsBadBlock(), let UFFS take care of it. */ - NULL, /* MarkBadBlock(), let UFFS take care of it. */ -#endif - nand_erase_block, /* EraseBlock() */ -}; - -static rt_uint8_t hw_flash_data_layout[UFFS_SPARE_LAYOUT_SIZE] = -{ - 0x05, 0x08, 0xFF, 0x00 -}; - -static rt_uint8_t hw_flash_ecc_layout[UFFS_SPARE_LAYOUT_SIZE] = -{ - 0x00, 0x04, 0xFF, 0x00 -}; - -RT_WEAK void uffs_setup_storage(struct uffs_StorageAttrSt *attr, - struct rt_mtd_nand_device *nand) -{ - rt_memset(attr, 0, sizeof(struct uffs_StorageAttrSt)); - -// attr->total_blocks = nand->end_block - nand->start_block + 1;/* no use */ - attr->page_data_size = nand->page_size; /* page data size */ - attr->pages_per_block = nand->pages_per_block; /* pages per block */ - attr->spare_size = nand->oob_size; /* page spare size */ - attr->ecc_opt = RT_CONFIG_UFFS_ECC_MODE; /* ecc option */ - attr->ecc_size = nand->oob_size-nand->oob_free; /* ecc size */ - attr->block_status_offs = attr->ecc_size; /* indicate block bad or good, offset in spare */ - attr->layout_opt = RT_CONFIG_UFFS_LAYOUT; /* let UFFS do the spare layout */ - - /* calculate the ecc layout array */ - hw_flash_data_layout[0] = attr->ecc_size + 1; /* ecc size + 1byte block status */ - hw_flash_data_layout[1] = 0x08; - hw_flash_data_layout[2] = 0xFF; - hw_flash_data_layout[3] = 0x00; - - hw_flash_ecc_layout[0] = 0; - hw_flash_ecc_layout[1] = attr->ecc_size; - hw_flash_ecc_layout[2] = 0xFF; - hw_flash_ecc_layout[3] = 0x00; - - /* initialize _uffs_data_layout and _uffs_ecc_layout */ - rt_memcpy(attr->_uffs_data_layout, hw_flash_data_layout, UFFS_SPARE_LAYOUT_SIZE); - rt_memcpy(attr->_uffs_ecc_layout, hw_flash_ecc_layout, UFFS_SPARE_LAYOUT_SIZE); - - attr->data_layout = attr->_uffs_data_layout; - attr->ecc_layout = attr->_uffs_ecc_layout; -} -#endif diff --git a/components/dfs/filesystems/uffs/uffs_rtthread.c b/components/dfs/filesystems/uffs/uffs_rtthread.c deleted file mode 100644 index bad456f04c..0000000000 --- a/components/dfs/filesystems/uffs/uffs_rtthread.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -/* - This file is part of UFFS, the Ultra-low-cost Flash File System. - - Copyright (C) 2005-2009 Ricky Zheng <[email protected]> - - UFFS is free software; you can redistribute it and/or modify it under - the GNU Library General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - - UFFS is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - or GNU Library General Public License, as applicable, for more details. - - You should have received a copy of the GNU General Public License - and GNU Library General Public License along with UFFS; if not, write - to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - - As a special exception, if other files instantiate templates or use - macros or inline functions from this file, or you compile this file - and link it with other works to produce a work based on this file, - this file does not by itself cause the resulting work to be covered - by the GNU General Public License. However the source code for this - file must still be made available in accordance with section (3) of - the GNU General Public License v2. - - This exception does not invalidate any other reasons why a work based - on this file might be covered by the GNU General Public License. -*/ - -/** - * \file uffs_os_posix.c - * \brief Emulation on POSIX host. This is just a dumb implementation, does not really create semaphores. - * \author Ricky Zheng - */ - -#include "uffs_config.h" -#include "uffs/uffs_os.h" -#include "uffs/uffs_public.h" -//#include <time.h> - -#define PFX "os : " - -int uffs_SemCreate(OSSEM *sem) -{ - static int count = 0; - char name [RT_NAME_MAX+1]; - struct rt_mutex *mutex = RT_NULL; - - rt_snprintf(name, sizeof(name), "usem%d", count++); - mutex = rt_mutex_create(name, RT_IPC_FLAG_FIFO); - if (mutex != RT_NULL) - { - *sem = (OSSEM *)mutex; - return 0; - } - uffs_Perror(UFFS_MSG_SERIOUS, "can't get a semphore"); - return -1; -} - -int uffs_SemWait(OSSEM sem) -{ - return rt_mutex_take((struct rt_mutex *)sem, RT_WAITING_FOREVER); -} - -int uffs_SemSignal(OSSEM sem) -{ - return rt_mutex_release((struct rt_mutex *)sem); -} - -int uffs_SemDelete(OSSEM *sem) -{ - int ret = -1; - - if (sem) { - ret = rt_mutex_delete((struct rt_mutex *)(*sem)); - if (ret == RT_EOK) { - *sem = 0; - } - } - return ret; -} - -int uffs_OSGetTaskId(void) -{ - //TODO: ... return current task ID ... - return 0; -} - -unsigned int uffs_GetCurDateTime(void) -{ - // FIXME: return system time, please modify this for your platform ! - // or just return 0 if you don't care about file time. -#if 0 - time_t tvalue; - - tvalue = time(NULL); - - return (unsigned int)tvalue; -#endif - return 0; -} - -#if CONFIG_USE_SYSTEM_MEMORY_ALLOCATOR > 0 -static void * sys_malloc(struct uffs_DeviceSt *dev, unsigned int size) -{ - dev = dev; - uffs_Perror(UFFS_MSG_NORMAL, "system memory alloc %d bytes", size); - return rt_malloc(size); -} - -static URET sys_free(struct uffs_DeviceSt *dev, void *p) -{ - dev = dev; - rt_free(p); - return U_SUCC; -} - -void uffs_MemSetupSystemAllocator(uffs_MemAllocator *allocator) -{ - allocator->malloc = sys_malloc; - allocator->free = sys_free; -} -#endif - -#if !defined(RT_THREAD) -/* debug message output throught 'printf' */ -static void output_dbg_msg(const char *msg); -static struct uffs_DebugMsgOutputSt m_dbg_ops = { - output_dbg_msg, - NULL, -}; - -static void output_dbg_msg(const char *msg) -{ - rt_kprintf("%s", msg); -} - -void uffs_SetupDebugOutput(void) -{ - uffs_InitDebugMessageOutput(&m_dbg_ops, UFFS_MSG_NOISY); -} -#else - -void uffs_SetupDebugOutput(void) -{ -} -#endif |
