mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
exFAT support
Signed-off-by: flar2 <asegaert@gmail.com>
This commit is contained in:
parent
4bfbd25a70
commit
db77a3c64d
28 changed files with 12322 additions and 0 deletions
|
@ -106,6 +106,7 @@ menu "DOS/FAT/NT Filesystems"
|
|||
|
||||
source "fs/fat/Kconfig"
|
||||
source "fs/ntfs/Kconfig"
|
||||
source "fs/exfat/Kconfig"
|
||||
|
||||
endmenu
|
||||
endif # BLOCK
|
||||
|
|
|
@ -96,6 +96,7 @@ obj-$(CONFIG_CIFS) += cifs/
|
|||
obj-$(CONFIG_NCP_FS) += ncpfs/
|
||||
obj-$(CONFIG_HPFS_FS) += hpfs/
|
||||
obj-$(CONFIG_NTFS_FS) += ntfs/
|
||||
obj-$(CONFIG_EXFAT_FS) += exfat/
|
||||
obj-$(CONFIG_UFS_FS) += ufs/
|
||||
obj-$(CONFIG_EFS_FS) += efs/
|
||||
obj-$(CONFIG_JFFS2_FS) += jffs2/
|
||||
|
|
19
fs/exfat/Kconfig
Normal file
19
fs/exfat/Kconfig
Normal file
|
@ -0,0 +1,19 @@
|
|||
config EXFAT_FS
|
||||
tristate "exFAT filesystem support"
|
||||
select NLS
|
||||
help
|
||||
exFAT driver from Samsung
|
||||
|
||||
config EXFAT_DEFAULT_CODEPAGE
|
||||
int "Default codepage for exFAT"
|
||||
depends on EXFAT_FS
|
||||
default 437
|
||||
help
|
||||
This option should be set to the codepage of your exFAT filesystems.
|
||||
|
||||
config EXFAT_DEFAULT_IOCHARSET
|
||||
string "Default iocharset for exFAT"
|
||||
depends on EXFAT_FS
|
||||
default "utf8"
|
||||
help
|
||||
Set this to the default input/output character set you'd like exFAT to use.
|
4
fs/exfat/Makefile
Normal file
4
fs/exfat/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
|||
obj-$(CONFIG_EXFAT_FS) += exfat.o
|
||||
|
||||
exfat-y := exfat_core.o exfat_api.o exfat_blkdev.o exfat_cache.o exfat_super.o \
|
||||
exfat_data.o exfat_global.o exfat_nls.o exfat_oal.o exfat_upcase.o
|
20
fs/exfat/Makefile.module
Normal file
20
fs/exfat/Makefile.module
Normal file
|
@ -0,0 +1,20 @@
|
|||
EXTRA_FLAGS += -I$(PWD)
|
||||
|
||||
#KDIR := /usr/src/linux/
|
||||
KDIR := /lib/modules/$(shell uname -r)/build
|
||||
PWD := $(shell pwd)
|
||||
|
||||
export CONFIG_EXFAT_FS := m
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) modules
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) clean
|
||||
|
||||
help:
|
||||
$(MAKE) -C $(KDIR) M=$(PWD) help
|
||||
|
||||
.PHONY : install
|
||||
install : all
|
||||
sudo $(MAKE) -C $(KDIR) M=$(PWD) modules_install; sudo depmod
|
71
fs/exfat/README.md
Normal file
71
fs/exfat/README.md
Normal file
|
@ -0,0 +1,71 @@
|
|||
exfat-nofuse
|
||||
============
|
||||
|
||||
Linux non-fuse read/write kernel driver for the exFAT file system.<br />
|
||||
Originally ported from android kernel v3.0.
|
||||
|
||||
|
||||
Kudos to ksv1986 for the mutex patch!<br />
|
||||
Thanks to JackNorris for being awesome and providing the clear_inode() patch.<br />
|
||||
<br />
|
||||
Big thanks to lqs for completing the driver!
|
||||
Big thanks to benpicco for fixing 3.11.y compatibility!
|
||||
|
||||
|
||||
Special thanks to github user AndreiLux for spreading the word about the leak!<br />
|
||||
|
||||
|
||||
Installation as stand alone module:
|
||||
====================================
|
||||
|
||||
make -f Makefile.module KDIR="path to kernel source" CROSS_COMPILE="path to android chain tools (as linaro)/bin/SOMETHING- (see your folder for clues)"
|
||||
|
||||
Example how it's works for me!
|
||||
|
||||
make -f Makefile.module CROSS_COMPILE=../dorimanx-SG2-I9100-Kernel/android-toolchain/bin/arm-eabi- KDIR=../dorimanx-SG2-I9100-Kernel/
|
||||
|
||||
exfat.ko module file will be created in exfat source folder. and will work with kernel source you have used.
|
||||
|
||||
make -f Makefile.module install
|
||||
|
||||
To load the driver manually, run this as root:
|
||||
|
||||
modprobe exfat
|
||||
|
||||
To add to kernel you need to do this:
|
||||
======================================
|
||||
|
||||
cd your kernel source dir
|
||||
|
||||
mkdir fs/exfat
|
||||
|
||||
copy all files (exept .git) from exfat-nofuse to your kernel source fs/exfat/
|
||||
|
||||
see
|
||||
https://github.com/dorimanx/Dorimanx-SG2-I9100-Kernel/commit/e8fc728a68096db9ffcebff40244ebfb60a3de18
|
||||
|
||||
edit fs/Kconfig
|
||||
edit fs/Makefile
|
||||
|
||||
cd your kernel source
|
||||
make menuconfig
|
||||
|
||||
Go to:
|
||||
> File systems > DOS/FAT/NT > check the exfat as MODULE (M)
|
||||
> (437) Default codepage for exFAT
|
||||
> (utf8) Default iocharset for exFAT
|
||||
|
||||
> ESC to main menu
|
||||
> Save an Alternate Configuration File
|
||||
> ESC ESC
|
||||
|
||||
build your kernel.
|
||||
|
||||
and you will have new module!
|
||||
|
||||
exfat.ko
|
||||
|
||||
have fun.
|
||||
|
||||
Free Software for the Free Minds!
|
||||
=====================================
|
675
fs/exfat/exfat.h
Normal file
675
fs/exfat/exfat.h
Normal file
|
@ -0,0 +1,675 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat.h */
|
||||
/* PURPOSE : Header File for exFAT File Manager */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_H
|
||||
#define _EXFAT_H
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_data.h"
|
||||
#include "exfat_oal.h"
|
||||
|
||||
#include "exfat_blkdev.h"
|
||||
#include "exfat_cache.h"
|
||||
#include "exfat_nls.h"
|
||||
#include "exfat_api.h"
|
||||
#include "exfat_cache.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if EXFAT_CONFIG_KERNEL_DEBUG
|
||||
/* For Debugging Purpose */
|
||||
/* IOCTL code 'f' used by
|
||||
* - file systems typically #0~0x1F
|
||||
* - embedded terminal devices #128~
|
||||
* - exts for debugging purpose #99
|
||||
* number 100 and 101 is availble now but has possible conflicts
|
||||
*/
|
||||
#define EXFAT_IOC_GET_DEBUGFLAGS _IOR('f', 100, long)
|
||||
#define EXFAT_IOC_SET_DEBUGFLAGS _IOW('f', 101, long)
|
||||
|
||||
#define EXFAT_DEBUGFLAGS_INVALID_UMOUNT 0x01
|
||||
#define EXFAT_DEBUGFLAGS_ERROR_RW 0x02
|
||||
#endif /* EXFAT_CONFIG_KERNEL_DEBUG */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define MAX_VOLUME 4 // max num of volumes per device
|
||||
|
||||
#define DENTRY_SIZE 32 // dir entry size
|
||||
#define DENTRY_SIZE_BITS 5
|
||||
|
||||
/* PBR entries */
|
||||
#define PBR_SIGNATURE 0xAA55
|
||||
#define EXT_SIGNATURE 0xAA550000
|
||||
#define VOL_LABEL "NO NAME " // size should be 11
|
||||
#define OEM_NAME "MSWIN4.1" // size should be 8
|
||||
#define STR_FAT12 "FAT12 " // size should be 8
|
||||
#define STR_FAT16 "FAT16 " // size should be 8
|
||||
#define STR_FAT32 "FAT32 " // size should be 8
|
||||
#define STR_EXFAT "EXFAT " // size should be 8
|
||||
#define VOL_CLEAN 0x0000
|
||||
#define VOL_DIRTY 0x0002
|
||||
|
||||
/* max number of clusters */
|
||||
#define FAT12_THRESHOLD 4087 // 2^12 - 1 + 2 (clu 0 & 1)
|
||||
#define FAT16_THRESHOLD 65527 // 2^16 - 1 + 2
|
||||
#define FAT32_THRESHOLD 268435457 // 2^28 - 1 + 2
|
||||
#define EXFAT_THRESHOLD 268435457 // 2^28 - 1 + 2
|
||||
|
||||
/* file types */
|
||||
#define TYPE_UNUSED 0x0000
|
||||
#define TYPE_DELETED 0x0001
|
||||
#define TYPE_INVALID 0x0002
|
||||
#define TYPE_CRITICAL_PRI 0x0100
|
||||
#define TYPE_BITMAP 0x0101
|
||||
#define TYPE_UPCASE 0x0102
|
||||
#define TYPE_VOLUME 0x0103
|
||||
#define TYPE_DIR 0x0104
|
||||
#define TYPE_FILE 0x011F
|
||||
#define TYPE_SYMLINK 0x015F
|
||||
#define TYPE_CRITICAL_SEC 0x0200
|
||||
#define TYPE_STREAM 0x0201
|
||||
#define TYPE_EXTEND 0x0202
|
||||
#define TYPE_ACL 0x0203
|
||||
#define TYPE_BENIGN_PRI 0x0400
|
||||
#define TYPE_GUID 0x0401
|
||||
#define TYPE_PADDING 0x0402
|
||||
#define TYPE_ACLTAB 0x0403
|
||||
#define TYPE_BENIGN_SEC 0x0800
|
||||
#define TYPE_ALL 0x0FFF
|
||||
|
||||
/* time modes */
|
||||
#define TM_CREATE 0
|
||||
#define TM_MODIFY 1
|
||||
#define TM_ACCESS 2
|
||||
|
||||
/* checksum types */
|
||||
#define CS_DIR_ENTRY 0
|
||||
#define CS_PBR_SECTOR 1
|
||||
#define CS_DEFAULT 2
|
||||
|
||||
#define CLUSTER_16(x) ((UINT16)(x))
|
||||
#define CLUSTER_32(x) ((UINT32)(x))
|
||||
|
||||
#define START_SECTOR(x) \
|
||||
( (((x)-2) << p_fs->sectors_per_clu_bits) + p_fs->data_start_sector )
|
||||
|
||||
#define IS_LAST_SECTOR_IN_CLUSTER(sec) \
|
||||
( (((sec) - p_fs->data_start_sector + 1) & ((1 << p_fs->sectors_per_clu_bits) -1)) == 0)
|
||||
|
||||
#define GET_CLUSTER_FROM_SECTOR(sec) \
|
||||
((((sec) - p_fs->data_start_sector) >> p_fs->sectors_per_clu_bits) +2)
|
||||
|
||||
#define GET16(p_src) \
|
||||
( ((UINT16)(p_src)[0]) | (((UINT16)(p_src)[1]) << 8) )
|
||||
#define GET32(p_src) \
|
||||
( ((UINT32)(p_src)[0]) | (((UINT32)(p_src)[1]) << 8) | \
|
||||
(((UINT32)(p_src)[2]) << 16) | (((UINT32)(p_src)[3]) << 24) )
|
||||
#define GET64(p_src) \
|
||||
( ((UINT64)(p_src)[0]) | (((UINT64)(p_src)[1]) << 8) | \
|
||||
(((UINT64)(p_src)[2]) << 16) | (((UINT64)(p_src)[3]) << 24) | \
|
||||
(((UINT64)(p_src)[4]) << 32) | (((UINT64)(p_src)[5]) << 40) | \
|
||||
(((UINT64)(p_src)[6]) << 48) | (((UINT64)(p_src)[7]) << 56) )
|
||||
|
||||
|
||||
#define SET16(p_dst,src) \
|
||||
do { \
|
||||
(p_dst)[0]=(UINT8)(src); \
|
||||
(p_dst)[1]=(UINT8)(((UINT16)(src)) >> 8); \
|
||||
} while (0)
|
||||
#define SET32(p_dst,src) \
|
||||
do { \
|
||||
(p_dst)[0]=(UINT8)(src); \
|
||||
(p_dst)[1]=(UINT8)(((UINT32)(src)) >> 8); \
|
||||
(p_dst)[2]=(UINT8)(((UINT32)(src)) >> 16); \
|
||||
(p_dst)[3]=(UINT8)(((UINT32)(src)) >> 24); \
|
||||
} while (0)
|
||||
#define SET64(p_dst,src) \
|
||||
do { \
|
||||
(p_dst)[0]=(UINT8)(src); \
|
||||
(p_dst)[1]=(UINT8)(((UINT64)(src)) >> 8); \
|
||||
(p_dst)[2]=(UINT8)(((UINT64)(src)) >> 16); \
|
||||
(p_dst)[3]=(UINT8)(((UINT64)(src)) >> 24); \
|
||||
(p_dst)[4]=(UINT8)(((UINT64)(src)) >> 32); \
|
||||
(p_dst)[5]=(UINT8)(((UINT64)(src)) >> 40); \
|
||||
(p_dst)[6]=(UINT8)(((UINT64)(src)) >> 48); \
|
||||
(p_dst)[7]=(UINT8)(((UINT64)(src)) >> 56); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
#define GET16_A(p_src) (*((UINT16 *)(p_src)))
|
||||
#define GET32_A(p_src) (*((UINT32 *)(p_src)))
|
||||
#define GET64_A(p_src) (*((UINT64 *)(p_src)))
|
||||
#define SET16_A(p_dst,src) *((UINT16 *)(p_dst)) = (UINT16)(src)
|
||||
#define SET32_A(p_dst,src) *((UINT32 *)(p_dst)) = (UINT32)(src)
|
||||
#define SET64_A(p_dst,src) *((UINT64 *)(p_dst)) = (UINT64)(src)
|
||||
#else
|
||||
#define GET16_A(p_src) GET16(p_src)
|
||||
#define GET32_A(p_src) GET32(p_src)
|
||||
#define GET64_A(p_src) GET64(p_src)
|
||||
#define SET16_A(p_dst,src) SET16(p_dst, src)
|
||||
#define SET32_A(p_dst,src) SET32(p_dst, src)
|
||||
#define SET64_A(p_dst,src) SET64(p_dst, src)
|
||||
#endif
|
||||
|
||||
/* Upcase tabel mecro */
|
||||
#define HIGH_INDEX_BIT (8)
|
||||
#define HIGH_INDEX_MASK (0xFF00)
|
||||
#define LOW_INDEX_BIT (16-HIGH_INDEX_BIT)
|
||||
#define UTBL_ROW_COUNT (1<<LOW_INDEX_BIT)
|
||||
#define UTBL_COL_COUNT (1<<HIGH_INDEX_BIT)
|
||||
|
||||
static inline UINT16 get_col_index(UINT16 i)
|
||||
{
|
||||
return i >> LOW_INDEX_BIT;
|
||||
}
|
||||
static inline UINT16 get_row_index(UINT16 i)
|
||||
{
|
||||
return i & ~HIGH_INDEX_MASK;
|
||||
}
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* MS_DOS FAT partition boot record (512 bytes) */
|
||||
typedef struct {
|
||||
UINT8 jmp_boot[3];
|
||||
UINT8 oem_name[8];
|
||||
UINT8 bpb[109];
|
||||
UINT8 boot_code[390];
|
||||
UINT8 signature[2];
|
||||
} PBR_SECTOR_T;
|
||||
|
||||
/* MS-DOS FAT12/16 BIOS parameter block (51 bytes) */
|
||||
typedef struct {
|
||||
UINT8 sector_size[2];
|
||||
UINT8 sectors_per_clu;
|
||||
UINT8 num_reserved[2];
|
||||
UINT8 num_fats;
|
||||
UINT8 num_root_entries[2];
|
||||
UINT8 num_sectors[2];
|
||||
UINT8 media_type;
|
||||
UINT8 num_fat_sectors[2];
|
||||
UINT8 sectors_in_track[2];
|
||||
UINT8 num_heads[2];
|
||||
UINT8 num_hid_sectors[4];
|
||||
UINT8 num_huge_sectors[4];
|
||||
|
||||
UINT8 phy_drv_no;
|
||||
UINT8 reserved;
|
||||
UINT8 ext_signature;
|
||||
UINT8 vol_serial[4];
|
||||
UINT8 vol_label[11];
|
||||
UINT8 vol_type[8];
|
||||
} BPB16_T;
|
||||
|
||||
/* MS-DOS FAT32 BIOS parameter block (79 bytes) */
|
||||
typedef struct {
|
||||
UINT8 sector_size[2];
|
||||
UINT8 sectors_per_clu;
|
||||
UINT8 num_reserved[2];
|
||||
UINT8 num_fats;
|
||||
UINT8 num_root_entries[2];
|
||||
UINT8 num_sectors[2];
|
||||
UINT8 media_type;
|
||||
UINT8 num_fat_sectors[2];
|
||||
UINT8 sectors_in_track[2];
|
||||
UINT8 num_heads[2];
|
||||
UINT8 num_hid_sectors[4];
|
||||
UINT8 num_huge_sectors[4];
|
||||
UINT8 num_fat32_sectors[4];
|
||||
UINT8 ext_flags[2];
|
||||
UINT8 fs_version[2];
|
||||
UINT8 root_cluster[4];
|
||||
UINT8 fsinfo_sector[2];
|
||||
UINT8 backup_sector[2];
|
||||
UINT8 reserved[12];
|
||||
|
||||
UINT8 phy_drv_no;
|
||||
UINT8 ext_reserved;
|
||||
UINT8 ext_signature;
|
||||
UINT8 vol_serial[4];
|
||||
UINT8 vol_label[11];
|
||||
UINT8 vol_type[8];
|
||||
} BPB32_T;
|
||||
|
||||
/* MS-DOS EXFAT BIOS parameter block (109 bytes) */
|
||||
typedef struct {
|
||||
UINT8 reserved1[53];
|
||||
UINT8 vol_offset[8];
|
||||
UINT8 vol_length[8];
|
||||
UINT8 fat_offset[4];
|
||||
UINT8 fat_length[4];
|
||||
UINT8 clu_offset[4];
|
||||
UINT8 clu_count[4];
|
||||
UINT8 root_cluster[4];
|
||||
UINT8 vol_serial[4];
|
||||
UINT8 fs_version[2];
|
||||
UINT8 vol_flags[2];
|
||||
UINT8 sector_size_bits;
|
||||
UINT8 sectors_per_clu_bits;
|
||||
UINT8 num_fats;
|
||||
UINT8 phy_drv_no;
|
||||
UINT8 perc_in_use;
|
||||
UINT8 reserved2[7];
|
||||
} BPBEX_T;
|
||||
|
||||
/* MS-DOS FAT file system information sector (512 bytes) */
|
||||
typedef struct {
|
||||
UINT8 signature1[4]; // aligned
|
||||
UINT8 reserved1[480];
|
||||
UINT8 signature2[4]; // aligned
|
||||
UINT8 free_cluster[4]; // aligned
|
||||
UINT8 next_cluster[4]; // aligned
|
||||
UINT8 reserved2[14];
|
||||
UINT8 signature3[2];
|
||||
} FSI_SECTOR_T;
|
||||
|
||||
/* MS-DOS FAT directory entry (32 bytes) */
|
||||
typedef struct {
|
||||
UINT8 dummy[32];
|
||||
} DENTRY_T;
|
||||
|
||||
typedef struct {
|
||||
UINT8 name[DOS_NAME_LENGTH];
|
||||
UINT8 attr;
|
||||
UINT8 lcase;
|
||||
UINT8 create_time_ms;
|
||||
UINT8 create_time[2]; // aligned
|
||||
UINT8 create_date[2]; // aligned
|
||||
UINT8 access_date[2]; // aligned
|
||||
UINT8 start_clu_hi[2]; // aligned
|
||||
UINT8 modify_time[2]; // aligned
|
||||
UINT8 modify_date[2]; // aligned
|
||||
UINT8 start_clu_lo[2]; // aligned
|
||||
UINT8 size[4]; // aligned
|
||||
} DOS_DENTRY_T;
|
||||
|
||||
/* MS-DOS FAT extended directory entry (32 bytes) */
|
||||
typedef struct {
|
||||
UINT8 order;
|
||||
UINT8 unicode_0_4[10];
|
||||
UINT8 attr;
|
||||
UINT8 sysid;
|
||||
UINT8 checksum;
|
||||
UINT8 unicode_5_10[12]; // aligned
|
||||
UINT8 start_clu[2]; // aligned
|
||||
UINT8 unicode_11_12[4]; // aligned
|
||||
} EXT_DENTRY_T;
|
||||
|
||||
/* MS-DOS EXFAT file directory entry (32 bytes) */
|
||||
typedef struct {
|
||||
UINT8 type;
|
||||
UINT8 num_ext;
|
||||
UINT8 checksum[2]; // aligned
|
||||
UINT8 attr[2]; // aligned
|
||||
UINT8 reserved1[2];
|
||||
UINT8 create_time[2]; // aligned
|
||||
UINT8 create_date[2]; // aligned
|
||||
UINT8 modify_time[2]; // aligned
|
||||
UINT8 modify_date[2]; // aligned
|
||||
UINT8 access_time[2]; // aligned
|
||||
UINT8 access_date[2]; // aligned
|
||||
UINT8 create_time_ms;
|
||||
UINT8 modify_time_ms;
|
||||
UINT8 access_time_ms;
|
||||
UINT8 reserved2[9];
|
||||
} FILE_DENTRY_T;
|
||||
|
||||
/* MS-DOS EXFAT stream extension directory entry (32 bytes) */
|
||||
typedef struct {
|
||||
UINT8 type;
|
||||
UINT8 flags;
|
||||
UINT8 reserved1;
|
||||
UINT8 name_len;
|
||||
UINT8 name_hash[2]; // aligned
|
||||
UINT8 reserved2[2];
|
||||
UINT8 valid_size[8]; // aligned
|
||||
UINT8 reserved3[4]; // aligned
|
||||
UINT8 start_clu[4]; // aligned
|
||||
UINT8 size[8]; // aligned
|
||||
} STRM_DENTRY_T;
|
||||
|
||||
/* MS-DOS EXFAT file name directory entry (32 bytes) */
|
||||
typedef struct {
|
||||
UINT8 type;
|
||||
UINT8 flags;
|
||||
UINT8 unicode_0_14[30]; // aligned
|
||||
} NAME_DENTRY_T;
|
||||
|
||||
/* MS-DOS EXFAT allocation bitmap directory entry (32 bytes) */
|
||||
typedef struct {
|
||||
UINT8 type;
|
||||
UINT8 flags;
|
||||
UINT8 reserved[18];
|
||||
UINT8 start_clu[4]; // aligned
|
||||
UINT8 size[8]; // aligned
|
||||
} BMAP_DENTRY_T;
|
||||
|
||||
/* MS-DOS EXFAT up-case table directory entry (32 bytes) */
|
||||
typedef struct {
|
||||
UINT8 type;
|
||||
UINT8 reserved1[3];
|
||||
UINT8 checksum[4]; // aligned
|
||||
UINT8 reserved2[12];
|
||||
UINT8 start_clu[4]; // aligned
|
||||
UINT8 size[8]; // aligned
|
||||
} CASE_DENTRY_T;
|
||||
|
||||
/* MS-DOS EXFAT volume label directory entry (32 bytes) */
|
||||
typedef struct {
|
||||
UINT8 type;
|
||||
UINT8 label_len;
|
||||
UINT8 unicode_0_10[22]; // aligned
|
||||
UINT8 reserved[8];
|
||||
} VOLM_DENTRY_T;
|
||||
|
||||
/* unused entry hint information */
|
||||
typedef struct {
|
||||
UINT32 dir;
|
||||
INT32 entry;
|
||||
CHAIN_T clu;
|
||||
} UENTRY_T;
|
||||
|
||||
/* file system volume information structure */
|
||||
typedef struct __FS_STRUCT_T {
|
||||
UINT32 mounted;
|
||||
struct super_block *sb;
|
||||
struct semaphore v_sem;
|
||||
} FS_STRUCT_T;
|
||||
|
||||
typedef struct {
|
||||
INT32 (*alloc_cluster)(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain);
|
||||
void (*free_cluster)(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse);
|
||||
INT32 (*count_used_clusters)(struct super_block *sb);
|
||||
|
||||
INT32 (*init_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type,
|
||||
UINT32 start_clu, UINT64 size);
|
||||
INT32 (*init_ext_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries,
|
||||
UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname);
|
||||
INT32 (*find_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type);
|
||||
void (*delete_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 offset, INT32 num_entries);
|
||||
void (*get_uni_name_from_ext_entry)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname);
|
||||
INT32 (*count_ext_entries)(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry);
|
||||
INT32 (*calc_num_entries)(UNI_NAME_T *p_uniname);
|
||||
|
||||
UINT32 (*get_entry_type)(DENTRY_T *p_entry);
|
||||
void (*set_entry_type)(DENTRY_T *p_entry, UINT32 type);
|
||||
UINT32 (*get_entry_attr)(DENTRY_T *p_entry);
|
||||
void (*set_entry_attr)(DENTRY_T *p_entry, UINT32 attr);
|
||||
UINT8 (*get_entry_flag)(DENTRY_T *p_entry);
|
||||
void (*set_entry_flag)(DENTRY_T *p_entry, UINT8 flag);
|
||||
UINT32 (*get_entry_clu0)(DENTRY_T *p_entry);
|
||||
void (*set_entry_clu0)(DENTRY_T *p_entry, UINT32 clu0);
|
||||
UINT64 (*get_entry_size)(DENTRY_T *p_entry);
|
||||
void (*set_entry_size)(DENTRY_T *p_entry, UINT64 size);
|
||||
void (*get_entry_time)(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode);
|
||||
void (*set_entry_time)(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode);
|
||||
} FS_FUNC_T;
|
||||
|
||||
typedef struct __FS_INFO_T {
|
||||
UINT32 drv; // drive ID
|
||||
UINT32 vol_type; // volume FAT type
|
||||
UINT32 vol_id; // volume serial number
|
||||
|
||||
UINT32 num_sectors; // num of sectors in volume
|
||||
UINT32 num_clusters; // num of clusters in volume
|
||||
UINT32 cluster_size; // cluster size in bytes
|
||||
UINT32 cluster_size_bits;
|
||||
UINT32 sectors_per_clu; // cluster size in sectors
|
||||
UINT32 sectors_per_clu_bits;
|
||||
|
||||
UINT32 PBR_sector; // PBR sector
|
||||
UINT32 FAT1_start_sector; // FAT1 start sector
|
||||
UINT32 FAT2_start_sector; // FAT2 start sector
|
||||
UINT32 root_start_sector; // root dir start sector
|
||||
UINT32 data_start_sector; // data area start sector
|
||||
UINT32 num_FAT_sectors; // num of FAT sectors
|
||||
|
||||
UINT32 root_dir; // root dir cluster
|
||||
UINT32 dentries_in_root; // num of dentries in root dir
|
||||
UINT32 dentries_per_clu; // num of dentries per cluster
|
||||
|
||||
UINT32 vol_flag; // volume dirty flag
|
||||
struct buffer_head *pbr_bh; // PBR sector
|
||||
|
||||
UINT32 map_clu; // allocation bitmap start cluster
|
||||
UINT32 map_sectors; // num of allocation bitmap sectors
|
||||
struct buffer_head **vol_amap; // allocation bitmap
|
||||
|
||||
UINT16 **vol_utbl; // upcase table
|
||||
|
||||
UINT32 clu_srch_ptr; // cluster search pointer
|
||||
UINT32 used_clusters; // number of used clusters
|
||||
UENTRY_T hint_uentry; // unused entry hint information
|
||||
|
||||
UINT32 dev_ejected; // block device operation error flag
|
||||
|
||||
FS_FUNC_T *fs_func;
|
||||
|
||||
/* FAT cache */
|
||||
BUF_CACHE_T FAT_cache_array[FAT_CACHE_SIZE];
|
||||
BUF_CACHE_T FAT_cache_lru_list;
|
||||
BUF_CACHE_T FAT_cache_hash_list[FAT_CACHE_HASH_SIZE];
|
||||
|
||||
/* buf cache */
|
||||
BUF_CACHE_T buf_cache_array[BUF_CACHE_SIZE];
|
||||
BUF_CACHE_T buf_cache_lru_list;
|
||||
BUF_CACHE_T buf_cache_hash_list[BUF_CACHE_HASH_SIZE];
|
||||
} FS_INFO_T;
|
||||
|
||||
#define ES_2_ENTRIES 2
|
||||
#define ES_3_ENTRIES 3
|
||||
#define ES_ALL_ENTRIES 0
|
||||
|
||||
typedef struct {
|
||||
UINT32 sector; // sector number that contains file_entry
|
||||
INT32 offset; // byte offset in the sector
|
||||
INT32 alloc_flag; // flag in stream entry. 01 for cluster chain, 03 for contig. clusteres.
|
||||
UINT32 num_entries;
|
||||
|
||||
// __buf should be the last member
|
||||
void *__buf;
|
||||
} ENTRY_SET_CACHE_T;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* file system initialization & shutdown functions */
|
||||
INT32 ffsInit(void);
|
||||
INT32 ffsShutdown(void);
|
||||
|
||||
/* volume management functions */
|
||||
INT32 ffsMountVol(struct super_block *sb, INT32 drv);
|
||||
INT32 ffsUmountVol(struct super_block *sb);
|
||||
INT32 ffsCheckVol(struct super_block *sb);
|
||||
INT32 ffsGetVolInfo(struct super_block *sb, VOL_INFO_T *info);
|
||||
INT32 ffsSyncVol(struct super_block *sb, INT32 do_sync);
|
||||
|
||||
/* file management functions */
|
||||
INT32 ffsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid);
|
||||
INT32 ffsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid);
|
||||
INT32 ffsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount);
|
||||
INT32 ffsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount);
|
||||
INT32 ffsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size);
|
||||
INT32 ffsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry);
|
||||
INT32 ffsRemoveFile(struct inode *inode, FILE_ID_T *fid);
|
||||
INT32 ffsSetAttr(struct inode *inode, UINT32 attr);
|
||||
INT32 ffsGetStat(struct inode *inode, DIR_ENTRY_T *info);
|
||||
INT32 ffsSetStat(struct inode *inode, DIR_ENTRY_T *info);
|
||||
INT32 ffsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu);
|
||||
|
||||
/* directory management functions */
|
||||
INT32 ffsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid);
|
||||
INT32 ffsReadDir(struct inode *inode, DIR_ENTRY_T *dir_ent);
|
||||
INT32 ffsRemoveDir(struct inode *inode, FILE_ID_T *fid);
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations (NOT TO UPPER LAYER) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* fs management functions */
|
||||
INT32 fs_init(void);
|
||||
INT32 fs_shutdown(void);
|
||||
void fs_set_vol_flags(struct super_block *sb, UINT32 new_flag);
|
||||
void fs_sync(struct super_block *sb, INT32 do_sync);
|
||||
void fs_error(struct super_block *sb);
|
||||
|
||||
/* cluster management functions */
|
||||
INT32 clear_cluster(struct super_block *sb, UINT32 clu);
|
||||
INT32 fat_alloc_cluster(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain);
|
||||
INT32 exfat_alloc_cluster(struct super_block *sb, INT32 num_alloc, CHAIN_T *p_chain);
|
||||
void fat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse);
|
||||
void exfat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, INT32 do_relse);
|
||||
UINT32 find_last_cluster(struct super_block *sb, CHAIN_T *p_chain);
|
||||
INT32 count_num_clusters(struct super_block *sb, CHAIN_T *dir);
|
||||
INT32 fat_count_used_clusters(struct super_block *sb);
|
||||
INT32 exfat_count_used_clusters(struct super_block *sb);
|
||||
void exfat_chain_cont_cluster(struct super_block *sb, UINT32 chain, INT32 len);
|
||||
|
||||
/* allocation bitmap management functions */
|
||||
INT32 load_alloc_bitmap(struct super_block *sb);
|
||||
void free_alloc_bitmap(struct super_block *sb);
|
||||
INT32 set_alloc_bitmap(struct super_block *sb, UINT32 clu);
|
||||
INT32 clr_alloc_bitmap(struct super_block *sb, UINT32 clu);
|
||||
UINT32 test_alloc_bitmap(struct super_block *sb, UINT32 clu);
|
||||
void sync_alloc_bitmap(struct super_block *sb);
|
||||
|
||||
/* upcase table management functions */
|
||||
INT32 load_upcase_table(struct super_block *sb);
|
||||
void free_upcase_table(struct super_block *sb);
|
||||
|
||||
/* dir entry management functions */
|
||||
UINT32 fat_get_entry_type(DENTRY_T *p_entry);
|
||||
UINT32 exfat_get_entry_type(DENTRY_T *p_entry);
|
||||
void fat_set_entry_type(DENTRY_T *p_entry, UINT32 type);
|
||||
void exfat_set_entry_type(DENTRY_T *p_entry, UINT32 type);
|
||||
UINT32 fat_get_entry_attr(DENTRY_T *p_entry);
|
||||
UINT32 exfat_get_entry_attr(DENTRY_T *p_entry);
|
||||
void fat_set_entry_attr(DENTRY_T *p_entry, UINT32 attr);
|
||||
void exfat_set_entry_attr(DENTRY_T *p_entry, UINT32 attr);
|
||||
UINT8 fat_get_entry_flag(DENTRY_T *p_entry);
|
||||
UINT8 exfat_get_entry_flag(DENTRY_T *p_entry);
|
||||
void fat_set_entry_flag(DENTRY_T *p_entry, UINT8 flag);
|
||||
void exfat_set_entry_flag(DENTRY_T *p_entry, UINT8 flag);
|
||||
UINT32 fat_get_entry_clu0(DENTRY_T *p_entry);
|
||||
UINT32 exfat_get_entry_clu0(DENTRY_T *p_entry);
|
||||
void fat_set_entry_clu0(DENTRY_T *p_entry, UINT32 start_clu);
|
||||
void exfat_set_entry_clu0(DENTRY_T *p_entry, UINT32 start_clu);
|
||||
UINT64 fat_get_entry_size(DENTRY_T *p_entry);
|
||||
UINT64 exfat_get_entry_size(DENTRY_T *p_entry);
|
||||
void fat_set_entry_size(DENTRY_T *p_entry, UINT64 size);
|
||||
void exfat_set_entry_size(DENTRY_T *p_entry, UINT64 size);
|
||||
void fat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode);
|
||||
void exfat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode);
|
||||
void fat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode);
|
||||
void exfat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, UINT8 mode);
|
||||
INT32 fat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, UINT32 start_clu, UINT64 size);
|
||||
INT32 exfat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, UINT32 start_clu, UINT64 size);
|
||||
INT32 fat_init_ext_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname);
|
||||
INT32 exfat_init_ext_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 num_entries, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname);
|
||||
void init_dos_entry(DOS_DENTRY_T *ep, UINT32 type, UINT32 start_clu);
|
||||
void init_ext_entry(EXT_DENTRY_T *ep, INT32 order, UINT8 chksum, UINT16 *uniname);
|
||||
void init_file_entry(FILE_DENTRY_T *ep, UINT32 type);
|
||||
void init_strm_entry(STRM_DENTRY_T *ep, UINT8 flags, UINT32 start_clu, UINT64 size);
|
||||
void init_name_entry(NAME_DENTRY_T *ep, UINT16 *uniname);
|
||||
void fat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 order, INT32 num_entries);
|
||||
void exfat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, INT32 order, INT32 num_entries);
|
||||
|
||||
INT32 find_location(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 *sector, INT32 *offset);
|
||||
DENTRY_T *get_entry_with_sector(struct super_block *sb, UINT32 sector, INT32 offset);
|
||||
DENTRY_T *get_entry_in_dir(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 *sector);
|
||||
ENTRY_SET_CACHE_T *get_entry_set_in_dir (struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT32 type, DENTRY_T **file_ep);
|
||||
void release_entry_set (ENTRY_SET_CACHE_T *es);
|
||||
INT32 write_whole_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es);
|
||||
INT32 write_partial_entries_in_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es, DENTRY_T *ep, UINT32 count);
|
||||
INT32 search_deleted_or_unused_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 num_entries);
|
||||
INT32 find_empty_entry(struct inode *inode, CHAIN_T *p_dir, INT32 num_entries);
|
||||
INT32 fat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type);
|
||||
INT32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 num_entries, DOS_NAME_T *p_dosname, UINT32 type);
|
||||
INT32 fat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry);
|
||||
INT32 exfat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, DENTRY_T *p_entry);
|
||||
INT32 count_dos_name_entries(struct super_block *sb, CHAIN_T *p_dir, UINT32 type);
|
||||
void update_dir_checksum(struct super_block *sb, CHAIN_T *p_dir, INT32 entry);
|
||||
void update_dir_checksum_with_entry_set (struct super_block *sb, ENTRY_SET_CACHE_T *es);
|
||||
BOOL is_dir_empty(struct super_block *sb, CHAIN_T *p_dir);
|
||||
|
||||
/* name conversion functions */
|
||||
INT32 get_num_entries_and_dos_name(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, INT32 *entries, DOS_NAME_T *p_dosname);
|
||||
void get_uni_name_from_dos_entry(struct super_block *sb, DOS_DENTRY_T *ep, UNI_NAME_T *p_uniname, UINT8 mode);
|
||||
void fat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname);
|
||||
void exfat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, INT32 entry, UINT16 *uniname);
|
||||
INT32 extract_uni_name_from_ext_entry(EXT_DENTRY_T *ep, UINT16 *uniname, INT32 order);
|
||||
INT32 extract_uni_name_from_name_entry(NAME_DENTRY_T *ep, UINT16 *uniname, INT32 order);
|
||||
INT32 fat_generate_dos_name(struct super_block *sb, CHAIN_T *p_dir, DOS_NAME_T *p_dosname);
|
||||
void fat_attach_count_to_dos_name(UINT8 *dosname, INT32 count);
|
||||
INT32 fat_calc_num_entries(UNI_NAME_T *p_uniname);
|
||||
INT32 exfat_calc_num_entries(UNI_NAME_T *p_uniname);
|
||||
UINT8 calc_checksum_1byte(void *data, INT32 len, UINT8 chksum);
|
||||
UINT16 calc_checksum_2byte(void *data, INT32 len, UINT16 chksum, INT32 type);
|
||||
UINT32 calc_checksum_4byte(void *data, INT32 len, UINT32 chksum, INT32 type);
|
||||
|
||||
/* name resolution functions */
|
||||
INT32 resolve_path(struct inode *inode, UINT8 *path, CHAIN_T *p_dir, UNI_NAME_T *p_uniname);
|
||||
INT32 resolve_name(UINT8 *name, UINT8 **arg);
|
||||
|
||||
/* file operation functions */
|
||||
INT32 fat16_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr);
|
||||
INT32 fat32_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr);
|
||||
INT32 exfat_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr);
|
||||
INT32 create_dir(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
|
||||
INT32 create_file(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, UINT8 mode, FILE_ID_T *fid);
|
||||
void remove_file(struct inode *inode, CHAIN_T *p_dir, INT32 entry);
|
||||
INT32 rename_file(struct inode *inode, CHAIN_T *p_dir, INT32 old_entry, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
|
||||
INT32 move_file(struct inode *inode, CHAIN_T *p_olddir, INT32 oldentry, CHAIN_T *p_newdir, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
|
||||
|
||||
/* sector read/write functions */
|
||||
INT32 sector_read(struct super_block *sb, UINT32 sec, struct buffer_head **bh, INT32 read);
|
||||
INT32 sector_write(struct super_block *sb, UINT32 sec, struct buffer_head *bh, INT32 sync);
|
||||
INT32 multi_sector_read(struct super_block *sb, UINT32 sec, struct buffer_head **bh, INT32 num_secs, INT32 read);
|
||||
INT32 multi_sector_write(struct super_block *sb, UINT32 sec, struct buffer_head *bh, INT32 num_secs, INT32 sync);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_H */
|
||||
|
||||
/* end of exfat.h */
|
563
fs/exfat/exfat_api.c
Normal file
563
fs/exfat/exfat_api.c
Normal file
|
@ -0,0 +1,563 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_api.c */
|
||||
/* PURPOSE : exFAT API Glue Layer */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
#include "exfat_version.h"
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_data.h"
|
||||
#include "exfat_oal.h"
|
||||
|
||||
#include "exfat_part.h"
|
||||
#include "exfat_nls.h"
|
||||
#include "exfat_api.h"
|
||||
#include "exfat_super.h"
|
||||
#include "exfat.h"
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Global Variable Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
extern FS_STRUCT_T fs_struct[];
|
||||
|
||||
extern struct semaphore z_sem;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Local Variable Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Local Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*======================================================================*/
|
||||
/* Global Function Definitions */
|
||||
/* - All functions for global use have same return value format, */
|
||||
/* that is, FFS_SUCCESS on success and several FS error code on */
|
||||
/* various error condition. */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* exFAT Filesystem Init & Exit Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
INT32 FsInit(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
/* initialize all volumes as un-mounted */
|
||||
for (i = 0; i < MAX_DRIVE; i++) {
|
||||
fs_struct[i].mounted = FALSE;
|
||||
fs_struct[i].sb = NULL;
|
||||
sm_init(&(fs_struct[i].v_sem));
|
||||
}
|
||||
|
||||
return(ffsInit());
|
||||
}
|
||||
|
||||
INT32 FsShutdown(void)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
/* unmount all volumes */
|
||||
for (i = 0; i < MAX_DRIVE; i++) {
|
||||
if (!fs_struct[i].mounted) continue;
|
||||
|
||||
ffsUmountVol(fs_struct[i].sb);
|
||||
}
|
||||
|
||||
return(ffsShutdown());
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Volume Management Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* FsMountVol : mount the file system volume */
|
||||
INT32 FsMountVol(struct super_block *sb)
|
||||
{
|
||||
INT32 err, drv;
|
||||
|
||||
sm_P(&z_sem);
|
||||
|
||||
for (drv = 0; drv < MAX_DRIVE; drv++) {
|
||||
if (!fs_struct[drv].mounted) break;
|
||||
}
|
||||
|
||||
if (drv >= MAX_DRIVE) return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[drv].v_sem));
|
||||
|
||||
err = buf_init(sb);
|
||||
if (!err) {
|
||||
err = ffsMountVol(sb, drv);
|
||||
}
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[drv].v_sem));
|
||||
|
||||
if (!err) {
|
||||
fs_struct[drv].mounted = TRUE;
|
||||
fs_struct[drv].sb = sb;
|
||||
} else {
|
||||
buf_shutdown(sb);
|
||||
}
|
||||
|
||||
sm_V(&z_sem);
|
||||
|
||||
return(err);
|
||||
} /* end of FsMountVol */
|
||||
|
||||
/* FsUmountVol : unmount the file system volume */
|
||||
INT32 FsUmountVol(struct super_block *sb)
|
||||
{
|
||||
INT32 err;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
sm_P(&z_sem);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsUmountVol(sb);
|
||||
buf_shutdown(sb);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
fs_struct[p_fs->drv].mounted = FALSE;
|
||||
fs_struct[p_fs->drv].sb = NULL;
|
||||
|
||||
sm_V(&z_sem);
|
||||
|
||||
return(err);
|
||||
} /* end of FsUmountVol */
|
||||
|
||||
/* FsGetVolInfo : get the information of a file system volume */
|
||||
INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
|
||||
{
|
||||
INT32 err;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of pointer parameters */
|
||||
if (info == NULL) return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsGetVolInfo(sb, info);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsGetVolInfo */
|
||||
|
||||
/* FsSyncVol : synchronize a file system volume */
|
||||
INT32 FsSyncVol(struct super_block *sb, INT32 do_sync)
|
||||
{
|
||||
INT32 err;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsSyncVol(sb, do_sync);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsSyncVol */
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* File Operation Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* FsCreateFile : create a file */
|
||||
INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of pointer parameters */
|
||||
if ((fid == NULL) || (path == NULL) || (*path == '\0'))
|
||||
return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsLookupFile(inode, path, fid);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsLookupFile */
|
||||
|
||||
/* FsCreateFile : create a file */
|
||||
INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of pointer parameters */
|
||||
if ((fid == NULL) || (path == NULL) || (*path == '\0'))
|
||||
return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsCreateFile(inode, path, mode, fid);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsCreateFile */
|
||||
|
||||
INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of the given file id */
|
||||
if (fid == NULL) return(FFS_INVALIDFID);
|
||||
|
||||
/* check the validity of pointer parameters */
|
||||
if (buffer == NULL) return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsReadFile(inode, fid, buffer, count, rcount);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsReadFile */
|
||||
|
||||
INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of the given file id */
|
||||
if (fid == NULL) return(FFS_INVALIDFID);
|
||||
|
||||
/* check the validity of pointer parameters */
|
||||
if (buffer == NULL) return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsWriteFile(inode, fid, buffer, count, wcount);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsWriteFile */
|
||||
|
||||
/* FsTruncateFile : resize the file length */
|
||||
INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
PRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);
|
||||
|
||||
err = ffsTruncateFile(inode, old_size, new_size);
|
||||
|
||||
PRINTK("FsTruncateFile exitted (%d)\n", err);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsTruncateFile */
|
||||
|
||||
/* FsMoveFile : move(rename) a old file into a new file */
|
||||
INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = old_parent_inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of the given file id */
|
||||
if (fid == NULL) return(FFS_INVALIDFID);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsMoveFile */
|
||||
|
||||
/* FsRemoveFile : remove a file */
|
||||
INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of the given file id */
|
||||
if (fid == NULL) return(FFS_INVALIDFID);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsRemoveFile(inode, fid);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsRemoveFile */
|
||||
|
||||
/* FsSetAttr : set the attribute of a given file */
|
||||
INT32 FsSetAttr(struct inode *inode, UINT32 attr)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsSetAttr(inode, attr);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsSetAttr */
|
||||
|
||||
/* FsReadStat : get the information of a given file */
|
||||
INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsGetStat(inode, info);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsReadStat */
|
||||
|
||||
/* FsWriteStat : set the information of a given file */
|
||||
INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
PRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);
|
||||
|
||||
err = ffsSetStat(inode, info);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
PRINTK("FsWriteStat exited (%d)\n", err);
|
||||
|
||||
return(err);
|
||||
} /* end of FsWriteStat */
|
||||
|
||||
/* FsMapCluster : return the cluster number in the given cluster offset */
|
||||
INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of pointer parameters */
|
||||
if (clu == NULL) return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsMapCluster(inode, clu_offset, clu);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsMapCluster */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Directory Operation Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* FsCreateDir : create(make) a directory */
|
||||
INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of pointer parameters */
|
||||
if ((fid == NULL) || (path == NULL) || (*path == '\0'))
|
||||
return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsCreateDir(inode, path, fid);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsCreateDir */
|
||||
|
||||
/* FsReadDir : read a directory entry from the opened directory */
|
||||
INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of pointer parameters */
|
||||
if (dir_entry == NULL) return(FFS_ERROR);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsReadDir(inode, dir_entry);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsReadDir */
|
||||
|
||||
/* FsRemoveDir : remove a directory */
|
||||
INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid)
|
||||
{
|
||||
INT32 err;
|
||||
struct super_block *sb = inode->i_sb;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* check the validity of the given file id */
|
||||
if (fid == NULL) return(FFS_INVALIDFID);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
err = ffsRemoveDir(inode, fid);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return(err);
|
||||
} /* end of FsRemoveDir */
|
||||
|
||||
EXPORT_SYMBOL(FsMountVol);
|
||||
EXPORT_SYMBOL(FsUmountVol);
|
||||
EXPORT_SYMBOL(FsGetVolInfo);
|
||||
EXPORT_SYMBOL(FsSyncVol);
|
||||
EXPORT_SYMBOL(FsLookupFile);
|
||||
EXPORT_SYMBOL(FsCreateFile);
|
||||
EXPORT_SYMBOL(FsReadFile);
|
||||
EXPORT_SYMBOL(FsWriteFile);
|
||||
EXPORT_SYMBOL(FsTruncateFile);
|
||||
EXPORT_SYMBOL(FsMoveFile);
|
||||
EXPORT_SYMBOL(FsRemoveFile);
|
||||
EXPORT_SYMBOL(FsSetAttr);
|
||||
EXPORT_SYMBOL(FsReadStat);
|
||||
EXPORT_SYMBOL(FsWriteStat);
|
||||
EXPORT_SYMBOL(FsMapCluster);
|
||||
EXPORT_SYMBOL(FsCreateDir);
|
||||
EXPORT_SYMBOL(FsReadDir);
|
||||
EXPORT_SYMBOL(FsRemoveDir);
|
||||
|
||||
#if EXFAT_CONFIG_KERNEL_DEBUG
|
||||
/* FsReleaseCache: Release FAT & buf cache */
|
||||
INT32 FsReleaseCache(struct super_block *sb)
|
||||
{
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
/* acquire the lock for file system critical section */
|
||||
sm_P(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
FAT_release_all(sb);
|
||||
buf_release_all(sb);
|
||||
|
||||
/* release the lock for file system critical section */
|
||||
sm_V(&(fs_struct[p_fs->drv].v_sem));
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* FsReleaseCache */
|
||||
|
||||
EXPORT_SYMBOL(FsReleaseCache);
|
||||
#endif /* EXFAT_CONFIG_KERNEL_DEBUG */
|
||||
|
||||
/*======================================================================*/
|
||||
/* Local Function Definitions */
|
||||
/*======================================================================*/
|
||||
|
||||
/* end of exfat_api.c */
|
221
fs/exfat/exfat_api.h
Normal file
221
fs/exfat/exfat_api.h
Normal file
|
@ -0,0 +1,221 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_api.h */
|
||||
/* PURPOSE : Header File for exFAT API Glue Layer */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_API_H
|
||||
#define _EXFAT_API_H
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define EXFAT_SUPER_MAGIC (0x2011BAB0L)
|
||||
#define EXFAT_ROOT_INO 1
|
||||
|
||||
/* FAT types */
|
||||
#define FAT12 0x01 // FAT12
|
||||
#define FAT16 0x0E // Win95 FAT16 (LBA)
|
||||
#define FAT32 0x0C // Win95 FAT32 (LBA)
|
||||
#define EXFAT 0x07 // exFAT
|
||||
|
||||
/* file name lengths */
|
||||
#define MAX_CHARSET_SIZE 3 // max size of multi-byte character
|
||||
#define MAX_PATH_DEPTH 15 // max depth of path name
|
||||
#define MAX_NAME_LENGTH 256 // max len of file name including NULL
|
||||
#define MAX_PATH_LENGTH 260 // max len of path name including NULL
|
||||
#define DOS_NAME_LENGTH 11 // DOS file name length excluding NULL
|
||||
#define DOS_PATH_LENGTH 80 // DOS path name length excluding NULL
|
||||
|
||||
/* file attributes */
|
||||
#define ATTR_NORMAL 0x0000
|
||||
#define ATTR_READONLY 0x0001
|
||||
#define ATTR_HIDDEN 0x0002
|
||||
#define ATTR_SYSTEM 0x0004
|
||||
#define ATTR_VOLUME 0x0008
|
||||
#define ATTR_SUBDIR 0x0010
|
||||
#define ATTR_ARCHIVE 0x0020
|
||||
#define ATTR_SYMLINK 0x0040
|
||||
#define ATTR_EXTEND 0x000F
|
||||
#define ATTR_RWMASK 0x007E
|
||||
|
||||
/* file creation modes */
|
||||
#define FM_REGULAR 0x00
|
||||
#define FM_SYMLINK 0x40
|
||||
|
||||
/* return values */
|
||||
#define FFS_SUCCESS 0
|
||||
#define FFS_MEDIAERR 1
|
||||
#define FFS_FORMATERR 2
|
||||
#define FFS_MOUNTED 3
|
||||
#define FFS_NOTMOUNTED 4
|
||||
#define FFS_ALIGNMENTERR 5
|
||||
#define FFS_SEMAPHOREERR 6
|
||||
#define FFS_INVALIDPATH 7
|
||||
#define FFS_INVALIDFID 8
|
||||
#define FFS_NOTFOUND 9
|
||||
#define FFS_FILEEXIST 10
|
||||
#define FFS_PERMISSIONERR 11
|
||||
#define FFS_NOTOPENED 12
|
||||
#define FFS_MAXOPENED 13
|
||||
#define FFS_FULL 14
|
||||
#define FFS_EOF 15
|
||||
#define FFS_DIRBUSY 16
|
||||
#define FFS_MEMORYERR 17
|
||||
#define FFS_NAMETOOLONG 18
|
||||
#define FFS_ERROR 19 // generic error code
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
UINT16 Year;
|
||||
UINT16 Month;
|
||||
UINT16 Day;
|
||||
UINT16 Hour;
|
||||
UINT16 Minute;
|
||||
UINT16 Second;
|
||||
UINT16 MilliSecond;
|
||||
} DATE_TIME_T;
|
||||
|
||||
typedef struct {
|
||||
UINT32 Offset; // start sector number of the partition
|
||||
UINT32 Size; // in sectors
|
||||
} PART_INFO_T;
|
||||
|
||||
typedef struct {
|
||||
UINT32 SecSize; // sector size in bytes
|
||||
UINT32 DevSize; // block device size in sectors
|
||||
} DEV_INFO_T;
|
||||
|
||||
typedef struct {
|
||||
UINT32 FatType;
|
||||
UINT32 ClusterSize;
|
||||
UINT32 NumClusters;
|
||||
UINT32 FreeClusters;
|
||||
UINT32 UsedClusters;
|
||||
} VOL_INFO_T;
|
||||
|
||||
/* directory structure */
|
||||
typedef struct {
|
||||
UINT32 dir;
|
||||
INT32 size;
|
||||
UINT8 flags;
|
||||
} CHAIN_T;
|
||||
|
||||
/* file id structure */
|
||||
typedef struct {
|
||||
CHAIN_T dir;
|
||||
UINT8 flags;
|
||||
INT32 entry;
|
||||
UINT32 type;
|
||||
UINT32 attr;
|
||||
UINT32 start_clu;
|
||||
INT32 hint_last_off;
|
||||
UINT32 hint_last_clu;
|
||||
INT64 rwoffset;
|
||||
UINT64 size;
|
||||
} FILE_ID_T;
|
||||
|
||||
typedef struct {
|
||||
INT8 Name[MAX_NAME_LENGTH *MAX_CHARSET_SIZE];
|
||||
INT8 ShortName[DOS_NAME_LENGTH + 2]; // used only for FAT12/16/32, not used for exFAT
|
||||
UINT32 Attr;
|
||||
UINT64 Size;
|
||||
UINT32 NumSubdirs;
|
||||
DATE_TIME_T CreateTimestamp;
|
||||
DATE_TIME_T ModifyTimestamp;
|
||||
DATE_TIME_T AccessTimestamp;
|
||||
} DIR_ENTRY_T;
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* API FUNCTION DECLARATIONS */
|
||||
/* (CHANGE THIS PART IF REQUIRED) */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* file system initialization & shutdown functions */
|
||||
INT32 FsInit(void);
|
||||
INT32 FsShutdown(void);
|
||||
|
||||
/* volume management functions */
|
||||
INT32 FsMountVol(struct super_block *sb);
|
||||
INT32 FsUmountVol(struct super_block *sb);
|
||||
INT32 FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info);
|
||||
INT32 FsSyncVol(struct super_block *sb, INT32 do_sync);
|
||||
|
||||
/* file management functions */
|
||||
INT32 FsLookupFile(struct inode *inode, UINT8 *path, FILE_ID_T *fid);
|
||||
INT32 FsCreateFile(struct inode *inode, UINT8 *path, UINT8 mode, FILE_ID_T *fid);
|
||||
INT32 FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *rcount);
|
||||
INT32 FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, UINT64 count, UINT64 *wcount);
|
||||
INT32 FsTruncateFile(struct inode *inode, UINT64 old_size, UINT64 new_size);
|
||||
INT32 FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry);
|
||||
INT32 FsRemoveFile(struct inode *inode, FILE_ID_T *fid);
|
||||
INT32 FsSetAttr(struct inode *inode, UINT32 attr);
|
||||
INT32 FsReadStat(struct inode *inode, DIR_ENTRY_T *info);
|
||||
INT32 FsWriteStat(struct inode *inode, DIR_ENTRY_T *info);
|
||||
INT32 FsMapCluster(struct inode *inode, INT32 clu_offset, UINT32 *clu);
|
||||
|
||||
/* directory management functions */
|
||||
INT32 FsCreateDir(struct inode *inode, UINT8 *path, FILE_ID_T *fid);
|
||||
INT32 FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry);
|
||||
INT32 FsRemoveDir(struct inode *inode, FILE_ID_T *fid);
|
||||
|
||||
/* debug functions */
|
||||
INT32 FsReleaseCache(struct super_block *sb);
|
||||
|
||||
/* partition management functions */
|
||||
//INT32 FsSetPartition(INT32 dev, INT32 num_vol, PART_INFO_T *vol_spec);
|
||||
//INT32 FsGetPartition(INT32 dev, INT32 *num_vol, PART_INFO_T *vol_spec);
|
||||
//INT32 FsGetDevInfo(INT32 dev, DEV_INFO_T *info);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_API_H */
|
||||
|
||||
/* end of exfat_api.h */
|
190
fs/exfat/exfat_blkdev.c
Normal file
190
fs/exfat/exfat_blkdev.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_blkdev.c */
|
||||
/* PURPOSE : exFAT Block Device Driver Glue Layer */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_blkdev.h"
|
||||
#include "exfat_data.h"
|
||||
#include "exfat_api.h"
|
||||
#include "exfat_super.h"
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Global Variable Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Local Variable Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*======================================================================*/
|
||||
/* Function Definitions */
|
||||
/*======================================================================*/
|
||||
|
||||
INT32 bdev_init(void)
|
||||
{
|
||||
return(FFS_SUCCESS);
|
||||
}
|
||||
|
||||
INT32 bdev_shutdown(void)
|
||||
{
|
||||
return(FFS_SUCCESS);
|
||||
}
|
||||
|
||||
INT32 bdev_open(struct super_block *sb)
|
||||
{
|
||||
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
|
||||
|
||||
if (p_bd->opened) return(FFS_SUCCESS);
|
||||
|
||||
p_bd->sector_size = bdev_logical_block_size(sb->s_bdev);
|
||||
p_bd->sector_size_bits = my_log2(p_bd->sector_size);
|
||||
p_bd->sector_size_mask = p_bd->sector_size - 1;
|
||||
p_bd->num_sectors = i_size_read(sb->s_bdev->bd_inode) >> p_bd->sector_size_bits;
|
||||
|
||||
p_bd->opened = TRUE;
|
||||
|
||||
return(FFS_SUCCESS);
|
||||
}
|
||||
|
||||
INT32 bdev_close(struct super_block *sb)
|
||||
{
|
||||
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
|
||||
|
||||
if (!p_bd->opened) return(FFS_SUCCESS);
|
||||
|
||||
p_bd->opened = FALSE;
|
||||
return(FFS_SUCCESS);
|
||||
}
|
||||
|
||||
INT32 bdev_read(struct super_block *sb, UINT32 secno, struct buffer_head **bh, UINT32 num_secs, INT32 read)
|
||||
{
|
||||
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
#if EXFAT_CONFIG_KERNEL_DEBUG
|
||||
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
||||
long flags = sbi->debug_flags;
|
||||
|
||||
if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR);
|
||||
#endif /* EXFAT_CONFIG_KERNEL_DEBUG */
|
||||
|
||||
if (!p_bd->opened) return(FFS_MEDIAERR);
|
||||
|
||||
if (*bh) __brelse(*bh);
|
||||
|
||||
if (read)
|
||||
*bh = __bread(sb->s_bdev, secno, num_secs << p_bd->sector_size_bits);
|
||||
else
|
||||
*bh = __getblk(sb->s_bdev, secno, num_secs << p_bd->sector_size_bits);
|
||||
|
||||
if (*bh) return(FFS_SUCCESS);
|
||||
|
||||
WARN(!p_fs->dev_ejected,
|
||||
"[EXFAT] No bh, device seems wrong or to be ejected.\n");
|
||||
|
||||
return(FFS_MEDIAERR);
|
||||
}
|
||||
|
||||
INT32 bdev_write(struct super_block *sb, UINT32 secno, struct buffer_head *bh, UINT32 num_secs, INT32 sync)
|
||||
{
|
||||
INT32 count;
|
||||
struct buffer_head *bh2;
|
||||
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
#if EXFAT_CONFIG_KERNEL_DEBUG
|
||||
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
||||
long flags = sbi->debug_flags;
|
||||
|
||||
if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR);
|
||||
#endif /* EXFAT_CONFIG_KERNEL_DEBUG */
|
||||
|
||||
if (!p_bd->opened) return(FFS_MEDIAERR);
|
||||
|
||||
if (secno == bh->b_blocknr) {
|
||||
lock_buffer(bh);
|
||||
set_buffer_uptodate(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
unlock_buffer(bh);
|
||||
if (sync && (sync_dirty_buffer(bh) != 0))
|
||||
return (FFS_MEDIAERR);
|
||||
} else {
|
||||
count = num_secs << p_bd->sector_size_bits;
|
||||
|
||||
bh2 = __getblk(sb->s_bdev, secno, count);
|
||||
|
||||
if (bh2 == NULL)
|
||||
goto no_bh;
|
||||
|
||||
lock_buffer(bh2);
|
||||
MEMCPY(bh2->b_data, bh->b_data, count);
|
||||
set_buffer_uptodate(bh2);
|
||||
mark_buffer_dirty(bh2);
|
||||
unlock_buffer(bh2);
|
||||
if (sync && (sync_dirty_buffer(bh2) != 0)) {
|
||||
__brelse(bh2);
|
||||
goto no_bh;
|
||||
}
|
||||
__brelse(bh2);
|
||||
}
|
||||
|
||||
return(FFS_SUCCESS);
|
||||
|
||||
no_bh:
|
||||
WARN(!p_fs->dev_ejected,
|
||||
"[EXFAT] No bh, device seems wrong or to be ejected.\n");
|
||||
|
||||
return (FFS_MEDIAERR);
|
||||
}
|
||||
|
||||
INT32 bdev_sync(struct super_block *sb)
|
||||
{
|
||||
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
|
||||
#if EXFAT_CONFIG_KERNEL_DEBUG
|
||||
struct exfat_sb_info *sbi = EXFAT_SB(sb);
|
||||
long flags = sbi->debug_flags;
|
||||
|
||||
if (flags & EXFAT_DEBUGFLAGS_ERROR_RW) return (FFS_MEDIAERR);
|
||||
#endif /* EXFAT_CONFIG_KERNEL_DEBUG */
|
||||
|
||||
if (!p_bd->opened) return(FFS_MEDIAERR);
|
||||
|
||||
return sync_blockdev(sb->s_bdev);
|
||||
}
|
||||
|
||||
/* end of exfat_blkdev.c */
|
83
fs/exfat/exfat_blkdev.h
Normal file
83
fs/exfat/exfat_blkdev.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_blkdev.h */
|
||||
/* PURPOSE : Header File for exFAT Block Device Driver Glue Layer */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_BLKDEV_H
|
||||
#define _EXFAT_BLKDEV_H
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions (Non-Configurable) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
typedef struct __BD_INFO_T {
|
||||
INT32 sector_size; // in bytes
|
||||
INT32 sector_size_bits;
|
||||
INT32 sector_size_mask;
|
||||
INT32 num_sectors; // total number of sectors in this block device
|
||||
BOOL opened; // opened or not
|
||||
} BD_INFO_T;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Variable Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
INT32 bdev_init(void);
|
||||
INT32 bdev_shutdown(void);
|
||||
INT32 bdev_open(struct super_block *sb);
|
||||
INT32 bdev_close(struct super_block *sb);
|
||||
INT32 bdev_read(struct super_block *sb, UINT32 secno, struct buffer_head **bh, UINT32 num_secs, INT32 read);
|
||||
INT32 bdev_write(struct super_block *sb, UINT32 secno, struct buffer_head *bh, UINT32 num_secs, INT32 sync);
|
||||
INT32 bdev_sync(struct super_block *sb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_BLKDEV_H */
|
||||
|
||||
/* end of exfat_blkdev.h */
|
785
fs/exfat/exfat_cache.c
Normal file
785
fs/exfat/exfat_cache.c
Normal file
|
@ -0,0 +1,785 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_cache.c */
|
||||
/* PURPOSE : exFAT Cache Manager */
|
||||
/* (FAT Cache & Buffer Cache) */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Sung-Kwan Kim] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_data.h"
|
||||
|
||||
#include "exfat_cache.h"
|
||||
#include "exfat_super.h"
|
||||
#include "exfat.h"
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Global Variable Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
extern FS_STRUCT_T fs_struct[];
|
||||
|
||||
#define sm_P(s)
|
||||
#define sm_V(s)
|
||||
|
||||
static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content);
|
||||
static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content);
|
||||
|
||||
static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec);
|
||||
static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec);
|
||||
static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp);
|
||||
static void FAT_cache_remove_hash(BUF_CACHE_T *bp);
|
||||
|
||||
static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec);
|
||||
|
||||
static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec);
|
||||
static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec);
|
||||
static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp);
|
||||
static void buf_cache_remove_hash(BUF_CACHE_T *bp);
|
||||
|
||||
static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
|
||||
static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
|
||||
static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
|
||||
static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list);
|
||||
|
||||
/*======================================================================*/
|
||||
/* Cache Initialization Functions */
|
||||
/*======================================================================*/
|
||||
|
||||
INT32 buf_init(struct super_block *sb)
|
||||
{
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
INT32 i;
|
||||
|
||||
/* LRU list */
|
||||
p_fs->FAT_cache_lru_list.next = p_fs->FAT_cache_lru_list.prev = &p_fs->FAT_cache_lru_list;
|
||||
|
||||
for (i = 0; i < FAT_CACHE_SIZE; i++) {
|
||||
p_fs->FAT_cache_array[i].drv = -1;
|
||||
p_fs->FAT_cache_array[i].sec = ~0;
|
||||
p_fs->FAT_cache_array[i].flag = 0;
|
||||
p_fs->FAT_cache_array[i].buf_bh = NULL;
|
||||
p_fs->FAT_cache_array[i].prev = p_fs->FAT_cache_array[i].next = NULL;
|
||||
push_to_mru(&(p_fs->FAT_cache_array[i]), &p_fs->FAT_cache_lru_list);
|
||||
}
|
||||
|
||||
p_fs->buf_cache_lru_list.next = p_fs->buf_cache_lru_list.prev = &p_fs->buf_cache_lru_list;
|
||||
|
||||
for (i = 0; i < BUF_CACHE_SIZE; i++) {
|
||||
p_fs->buf_cache_array[i].drv = -1;
|
||||
p_fs->buf_cache_array[i].sec = ~0;
|
||||
p_fs->buf_cache_array[i].flag = 0;
|
||||
p_fs->buf_cache_array[i].buf_bh = NULL;
|
||||
p_fs->buf_cache_array[i].prev = p_fs->buf_cache_array[i].next = NULL;
|
||||
push_to_mru(&(p_fs->buf_cache_array[i]), &p_fs->buf_cache_lru_list);
|
||||
}
|
||||
|
||||
/* HASH list */
|
||||
for (i = 0; i < FAT_CACHE_HASH_SIZE; i++) {
|
||||
p_fs->FAT_cache_hash_list[i].drv = -1;
|
||||
p_fs->FAT_cache_hash_list[i].sec = ~0;
|
||||
p_fs->FAT_cache_hash_list[i].hash_next = p_fs->FAT_cache_hash_list[i].hash_prev = &(p_fs->FAT_cache_hash_list[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < FAT_CACHE_SIZE; i++) {
|
||||
FAT_cache_insert_hash(sb, &(p_fs->FAT_cache_array[i]));
|
||||
}
|
||||
|
||||
for (i = 0; i < BUF_CACHE_HASH_SIZE; i++) {
|
||||
p_fs->buf_cache_hash_list[i].drv = -1;
|
||||
p_fs->buf_cache_hash_list[i].sec = ~0;
|
||||
p_fs->buf_cache_hash_list[i].hash_next = p_fs->buf_cache_hash_list[i].hash_prev = &(p_fs->buf_cache_hash_list[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < BUF_CACHE_SIZE; i++) {
|
||||
buf_cache_insert_hash(sb, &(p_fs->buf_cache_array[i]));
|
||||
}
|
||||
|
||||
return(FFS_SUCCESS);
|
||||
} /* end of buf_init */
|
||||
|
||||
INT32 buf_shutdown(struct super_block *sb)
|
||||
{
|
||||
return(FFS_SUCCESS);
|
||||
} /* end of buf_shutdown */
|
||||
|
||||
/*======================================================================*/
|
||||
/* FAT Read/Write Functions */
|
||||
/*======================================================================*/
|
||||
|
||||
/* in : sb, loc
|
||||
* out: content
|
||||
* returns 0 on success
|
||||
* -1 on error
|
||||
*/
|
||||
INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content)
|
||||
{
|
||||
INT32 ret;
|
||||
|
||||
sm_P(&f_sem);
|
||||
|
||||
ret = __FAT_read(sb, loc, content);
|
||||
|
||||
sm_V(&f_sem);
|
||||
|
||||
return(ret);
|
||||
} /* end of FAT_read */
|
||||
|
||||
INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content)
|
||||
{
|
||||
INT32 ret;
|
||||
|
||||
sm_P(&f_sem);
|
||||
|
||||
ret = __FAT_write(sb, loc, content);
|
||||
|
||||
sm_V(&f_sem);
|
||||
|
||||
return(ret);
|
||||
} /* end of FAT_write */
|
||||
|
||||
static INT32 __FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content)
|
||||
{
|
||||
INT32 off;
|
||||
UINT32 sec, _content;
|
||||
UINT8 *fat_sector, *fat_entry;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
|
||||
|
||||
if (p_fs->vol_type == FAT12) {
|
||||
sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
|
||||
off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
|
||||
|
||||
if (off == (p_bd->sector_size-1)) {
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
_content = (UINT32) fat_sector[off];
|
||||
|
||||
fat_sector = FAT_getblk(sb, ++sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
_content |= (UINT32) fat_sector[0] << 8;
|
||||
} else {
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
fat_entry = &(fat_sector[off]);
|
||||
_content = GET16(fat_entry);
|
||||
}
|
||||
|
||||
if (loc & 1) _content >>= 4;
|
||||
|
||||
_content &= 0x00000FFF;
|
||||
|
||||
if (_content >= CLUSTER_16(0x0FF8)) {
|
||||
*content = CLUSTER_32(~0);
|
||||
return 0;
|
||||
} else {
|
||||
*content = CLUSTER_32(_content);
|
||||
return 0;
|
||||
}
|
||||
} else if (p_fs->vol_type == FAT16) {
|
||||
sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1));
|
||||
off = (loc << 1) & p_bd->sector_size_mask;
|
||||
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
fat_entry = &(fat_sector[off]);
|
||||
|
||||
_content = GET16_A(fat_entry);
|
||||
|
||||
_content &= 0x0000FFFF;
|
||||
|
||||
if (_content >= CLUSTER_16(0xFFF8)) {
|
||||
*content = CLUSTER_32(~0);
|
||||
return 0;
|
||||
} else {
|
||||
*content = CLUSTER_32(_content);
|
||||
return 0;
|
||||
}
|
||||
} else if (p_fs->vol_type == FAT32) {
|
||||
sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
|
||||
off = (loc << 2) & p_bd->sector_size_mask;
|
||||
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
fat_entry = &(fat_sector[off]);
|
||||
|
||||
_content = GET32_A(fat_entry);
|
||||
|
||||
_content &= 0x0FFFFFFF;
|
||||
|
||||
if (_content >= CLUSTER_32(0x0FFFFFF8)) {
|
||||
*content = CLUSTER_32(~0);
|
||||
return 0;
|
||||
} else {
|
||||
*content = CLUSTER_32(_content);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
|
||||
off = (loc << 2) & p_bd->sector_size_mask;
|
||||
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
fat_entry = &(fat_sector[off]);
|
||||
_content = GET32_A(fat_entry);
|
||||
|
||||
if (_content >= CLUSTER_32(0xFFFFFFF8)) {
|
||||
*content = CLUSTER_32(~0);
|
||||
return 0;
|
||||
} else {
|
||||
*content = CLUSTER_32(_content);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
*content = CLUSTER_32(~0);
|
||||
return 0;
|
||||
} /* end of __FAT_read */
|
||||
|
||||
static INT32 __FAT_write(struct super_block *sb, UINT32 loc, UINT32 content)
|
||||
{
|
||||
INT32 off;
|
||||
UINT32 sec;
|
||||
UINT8 *fat_sector, *fat_entry;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
|
||||
|
||||
if (p_fs->vol_type == FAT12) {
|
||||
|
||||
content &= 0x00000FFF;
|
||||
|
||||
sec = p_fs->FAT1_start_sector + ((loc + (loc >> 1)) >> p_bd->sector_size_bits);
|
||||
off = (loc + (loc >> 1)) & p_bd->sector_size_mask;
|
||||
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
if (loc & 1) { /* odd */
|
||||
|
||||
content <<= 4;
|
||||
|
||||
if (off == (p_bd->sector_size-1)) {
|
||||
fat_sector[off] = (UINT8)(content | (fat_sector[off] & 0x0F));
|
||||
FAT_modify(sb, sec);
|
||||
|
||||
fat_sector = FAT_getblk(sb, ++sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
fat_sector[0] = (UINT8)(content >> 8);
|
||||
} else {
|
||||
fat_entry = &(fat_sector[off]);
|
||||
content |= GET16(fat_entry) & 0x000F;
|
||||
|
||||
SET16(fat_entry, content);
|
||||
}
|
||||
} else { /* even */
|
||||
fat_sector[off] = (UINT8)(content);
|
||||
|
||||
if (off == (p_bd->sector_size-1)) {
|
||||
fat_sector[off] = (UINT8)(content);
|
||||
FAT_modify(sb, sec);
|
||||
|
||||
fat_sector = FAT_getblk(sb, ++sec);
|
||||
fat_sector[0] = (UINT8)((fat_sector[0] & 0xF0) | (content >> 8));
|
||||
} else {
|
||||
fat_entry = &(fat_sector[off]);
|
||||
content |= GET16(fat_entry) & 0xF000;
|
||||
|
||||
SET16(fat_entry, content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (p_fs->vol_type == FAT16) {
|
||||
|
||||
content &= 0x0000FFFF;
|
||||
|
||||
sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-1));
|
||||
off = (loc << 1) & p_bd->sector_size_mask;
|
||||
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
fat_entry = &(fat_sector[off]);
|
||||
|
||||
SET16_A(fat_entry, content);
|
||||
}
|
||||
|
||||
else if (p_fs->vol_type == FAT32) {
|
||||
|
||||
content &= 0x0FFFFFFF;
|
||||
|
||||
sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
|
||||
off = (loc << 2) & p_bd->sector_size_mask;
|
||||
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
fat_entry = &(fat_sector[off]);
|
||||
|
||||
content |= GET32_A(fat_entry) & 0xF0000000;
|
||||
|
||||
SET32_A(fat_entry, content);
|
||||
}
|
||||
|
||||
else { /* p_fs->vol_type == EXFAT */
|
||||
|
||||
sec = p_fs->FAT1_start_sector + (loc >> (p_bd->sector_size_bits-2));
|
||||
off = (loc << 2) & p_bd->sector_size_mask;
|
||||
|
||||
fat_sector = FAT_getblk(sb, sec);
|
||||
if (!fat_sector)
|
||||
return -1;
|
||||
|
||||
fat_entry = &(fat_sector[off]);
|
||||
|
||||
SET32_A(fat_entry, content);
|
||||
}
|
||||
|
||||
FAT_modify(sb, sec);
|
||||
return 0;
|
||||
} /* end of __FAT_write */
|
||||
|
||||
UINT8 *FAT_getblk(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
bp = FAT_cache_find(sb, sec);
|
||||
if (bp != NULL) {
|
||||
move_to_mru(bp, &p_fs->FAT_cache_lru_list);
|
||||
return(bp->buf_bh->b_data);
|
||||
}
|
||||
|
||||
bp = FAT_cache_get(sb, sec);
|
||||
|
||||
FAT_cache_remove_hash(bp);
|
||||
|
||||
bp->drv = p_fs->drv;
|
||||
bp->sec = sec;
|
||||
bp->flag = 0;
|
||||
|
||||
FAT_cache_insert_hash(sb, bp);
|
||||
|
||||
if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) {
|
||||
FAT_cache_remove_hash(bp);
|
||||
bp->drv = -1;
|
||||
bp->sec = ~0;
|
||||
bp->flag = 0;
|
||||
bp->buf_bh = NULL;
|
||||
|
||||
move_to_lru(bp, &p_fs->FAT_cache_lru_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return(bp->buf_bh->b_data);
|
||||
} /* end of FAT_getblk */
|
||||
|
||||
void FAT_modify(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
|
||||
bp = FAT_cache_find(sb, sec);
|
||||
if (bp != NULL) {
|
||||
sector_write(sb, sec, bp->buf_bh, 0);
|
||||
}
|
||||
} /* end of FAT_modify */
|
||||
|
||||
void FAT_release_all(struct super_block *sb)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
sm_P(&f_sem);
|
||||
|
||||
bp = p_fs->FAT_cache_lru_list.next;
|
||||
while (bp != &p_fs->FAT_cache_lru_list) {
|
||||
if (bp->drv == p_fs->drv) {
|
||||
bp->drv = -1;
|
||||
bp->sec = ~0;
|
||||
bp->flag = 0;
|
||||
|
||||
if(bp->buf_bh) {
|
||||
__brelse(bp->buf_bh);
|
||||
bp->buf_bh = NULL;
|
||||
}
|
||||
}
|
||||
bp = bp->next;
|
||||
}
|
||||
|
||||
sm_V(&f_sem);
|
||||
} /* end of FAT_release_all */
|
||||
|
||||
void FAT_sync(struct super_block *sb)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
sm_P(&f_sem);
|
||||
|
||||
bp = p_fs->FAT_cache_lru_list.next;
|
||||
while (bp != &p_fs->FAT_cache_lru_list) {
|
||||
if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
|
||||
sync_dirty_buffer(bp->buf_bh);
|
||||
bp->flag &= ~(DIRTYBIT);
|
||||
}
|
||||
bp = bp->next;
|
||||
}
|
||||
|
||||
sm_V(&f_sem);
|
||||
} /* end of FAT_sync */
|
||||
|
||||
static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
INT32 off;
|
||||
BUF_CACHE_T *bp, *hp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE - 1);
|
||||
|
||||
hp = &(p_fs->FAT_cache_hash_list[off]);
|
||||
for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
|
||||
if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
|
||||
|
||||
WARN(!bp->buf_bh, "[EXFAT] FAT_cache has no bh. "
|
||||
"It will make system panic.\n");
|
||||
|
||||
touch_buffer(bp->buf_bh);
|
||||
return(bp);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
} /* end of FAT_cache_find */
|
||||
|
||||
static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
bp = p_fs->FAT_cache_lru_list.prev;
|
||||
|
||||
|
||||
move_to_mru(bp, &p_fs->FAT_cache_lru_list);
|
||||
return(bp);
|
||||
} /* end of FAT_cache_get */
|
||||
|
||||
static void FAT_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp)
|
||||
{
|
||||
INT32 off;
|
||||
BUF_CACHE_T *hp;
|
||||
FS_INFO_T *p_fs;
|
||||
|
||||
p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (FAT_CACHE_HASH_SIZE-1);
|
||||
|
||||
hp = &(p_fs->FAT_cache_hash_list[off]);
|
||||
bp->hash_next = hp->hash_next;
|
||||
bp->hash_prev = hp;
|
||||
hp->hash_next->hash_prev = bp;
|
||||
hp->hash_next = bp;
|
||||
} /* end of FAT_cache_insert_hash */
|
||||
|
||||
static void FAT_cache_remove_hash(BUF_CACHE_T *bp)
|
||||
{
|
||||
(bp->hash_prev)->hash_next = bp->hash_next;
|
||||
(bp->hash_next)->hash_prev = bp->hash_prev;
|
||||
} /* end of FAT_cache_remove_hash */
|
||||
|
||||
/*======================================================================*/
|
||||
/* Buffer Read/Write Functions */
|
||||
/*======================================================================*/
|
||||
|
||||
UINT8 *buf_getblk(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
UINT8 *buf;
|
||||
|
||||
sm_P(&b_sem);
|
||||
|
||||
buf = __buf_getblk(sb, sec);
|
||||
|
||||
sm_V(&b_sem);
|
||||
|
||||
return(buf);
|
||||
} /* end of buf_getblk */
|
||||
|
||||
static UINT8 *__buf_getblk(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
bp = buf_cache_find(sb, sec);
|
||||
if (bp != NULL) {
|
||||
move_to_mru(bp, &p_fs->buf_cache_lru_list);
|
||||
return(bp->buf_bh->b_data);
|
||||
}
|
||||
|
||||
bp = buf_cache_get(sb, sec);
|
||||
|
||||
buf_cache_remove_hash(bp);
|
||||
|
||||
bp->drv = p_fs->drv;
|
||||
bp->sec = sec;
|
||||
bp->flag = 0;
|
||||
|
||||
buf_cache_insert_hash(sb, bp);
|
||||
|
||||
if (sector_read(sb, sec, &(bp->buf_bh), 1) != FFS_SUCCESS) {
|
||||
buf_cache_remove_hash(bp);
|
||||
bp->drv = -1;
|
||||
bp->sec = ~0;
|
||||
bp->flag = 0;
|
||||
bp->buf_bh = NULL;
|
||||
|
||||
move_to_lru(bp, &p_fs->buf_cache_lru_list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return(bp->buf_bh->b_data);
|
||||
|
||||
} /* end of __buf_getblk */
|
||||
|
||||
void buf_modify(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
|
||||
sm_P(&b_sem);
|
||||
|
||||
bp = buf_cache_find(sb, sec);
|
||||
if (likely(bp != NULL)) {
|
||||
sector_write(sb, sec, bp->buf_bh, 0);
|
||||
}
|
||||
|
||||
WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
|
||||
|
||||
sm_V(&b_sem);
|
||||
} /* end of buf_modify */
|
||||
|
||||
void buf_lock(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
|
||||
sm_P(&b_sem);
|
||||
|
||||
bp = buf_cache_find(sb, sec);
|
||||
if (likely(bp != NULL)) bp->flag |= LOCKBIT;
|
||||
|
||||
WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
|
||||
|
||||
sm_V(&b_sem);
|
||||
} /* end of buf_lock */
|
||||
|
||||
void buf_unlock(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
|
||||
sm_P(&b_sem);
|
||||
|
||||
bp = buf_cache_find(sb, sec);
|
||||
if (likely(bp != NULL)) bp->flag &= ~(LOCKBIT);
|
||||
|
||||
WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%u).\n", sec);
|
||||
|
||||
sm_V(&b_sem);
|
||||
} /* end of buf_unlock */
|
||||
|
||||
void buf_release(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
sm_P(&b_sem);
|
||||
|
||||
bp = buf_cache_find(sb, sec);
|
||||
if (likely(bp != NULL)) {
|
||||
bp->drv = -1;
|
||||
bp->sec = ~0;
|
||||
bp->flag = 0;
|
||||
|
||||
if(bp->buf_bh) {
|
||||
__brelse(bp->buf_bh);
|
||||
bp->buf_bh = NULL;
|
||||
}
|
||||
|
||||
move_to_lru(bp, &p_fs->buf_cache_lru_list);
|
||||
}
|
||||
|
||||
sm_V(&b_sem);
|
||||
} /* end of buf_release */
|
||||
|
||||
void buf_release_all(struct super_block *sb)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
sm_P(&b_sem);
|
||||
|
||||
bp = p_fs->buf_cache_lru_list.next;
|
||||
while (bp != &p_fs->buf_cache_lru_list) {
|
||||
if (bp->drv == p_fs->drv) {
|
||||
bp->drv = -1;
|
||||
bp->sec = ~0;
|
||||
bp->flag = 0;
|
||||
|
||||
if(bp->buf_bh) {
|
||||
__brelse(bp->buf_bh);
|
||||
bp->buf_bh = NULL;
|
||||
}
|
||||
}
|
||||
bp = bp->next;
|
||||
}
|
||||
|
||||
sm_V(&b_sem);
|
||||
} /* end of buf_release_all */
|
||||
|
||||
void buf_sync(struct super_block *sb)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
sm_P(&b_sem);
|
||||
|
||||
bp = p_fs->buf_cache_lru_list.next;
|
||||
while (bp != &p_fs->buf_cache_lru_list) {
|
||||
if ((bp->drv == p_fs->drv) && (bp->flag & DIRTYBIT)) {
|
||||
sync_dirty_buffer(bp->buf_bh);
|
||||
bp->flag &= ~(DIRTYBIT);
|
||||
}
|
||||
bp = bp->next;
|
||||
}
|
||||
|
||||
sm_V(&b_sem);
|
||||
} /* end of buf_sync */
|
||||
|
||||
static BUF_CACHE_T *buf_cache_find(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
INT32 off;
|
||||
BUF_CACHE_T *bp, *hp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
off = (sec + (sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE - 1);
|
||||
|
||||
hp = &(p_fs->buf_cache_hash_list[off]);
|
||||
for (bp = hp->hash_next; bp != hp; bp = bp->hash_next) {
|
||||
if ((bp->drv == p_fs->drv) && (bp->sec == sec)) {
|
||||
touch_buffer(bp->buf_bh);
|
||||
return(bp);
|
||||
}
|
||||
}
|
||||
return(NULL);
|
||||
} /* end of buf_cache_find */
|
||||
|
||||
static BUF_CACHE_T *buf_cache_get(struct super_block *sb, UINT32 sec)
|
||||
{
|
||||
BUF_CACHE_T *bp;
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
bp = p_fs->buf_cache_lru_list.prev;
|
||||
while (bp->flag & LOCKBIT) bp = bp->prev;
|
||||
|
||||
|
||||
move_to_mru(bp, &p_fs->buf_cache_lru_list);
|
||||
return(bp);
|
||||
} /* end of buf_cache_get */
|
||||
|
||||
static void buf_cache_insert_hash(struct super_block *sb, BUF_CACHE_T *bp)
|
||||
{
|
||||
INT32 off;
|
||||
BUF_CACHE_T *hp;
|
||||
FS_INFO_T *p_fs;
|
||||
|
||||
p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
off = (bp->sec + (bp->sec >> p_fs->sectors_per_clu_bits)) & (BUF_CACHE_HASH_SIZE-1);
|
||||
|
||||
hp = &(p_fs->buf_cache_hash_list[off]);
|
||||
bp->hash_next = hp->hash_next;
|
||||
bp->hash_prev = hp;
|
||||
hp->hash_next->hash_prev = bp;
|
||||
hp->hash_next = bp;
|
||||
} /* end of buf_cache_insert_hash */
|
||||
|
||||
static void buf_cache_remove_hash(BUF_CACHE_T *bp)
|
||||
{
|
||||
(bp->hash_prev)->hash_next = bp->hash_next;
|
||||
(bp->hash_next)->hash_prev = bp->hash_prev;
|
||||
} /* end of buf_cache_remove_hash */
|
||||
|
||||
/*======================================================================*/
|
||||
/* Local Function Definitions */
|
||||
/*======================================================================*/
|
||||
|
||||
static void push_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
|
||||
{
|
||||
bp->next = list->next;
|
||||
bp->prev = list;
|
||||
list->next->prev = bp;
|
||||
list->next = bp;
|
||||
} /* end of buf_cache_push_to_mru */
|
||||
|
||||
static void push_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
|
||||
{
|
||||
bp->prev = list->prev;
|
||||
bp->next = list;
|
||||
list->prev->next = bp;
|
||||
list->prev = bp;
|
||||
} /* end of buf_cache_push_to_lru */
|
||||
|
||||
static void move_to_mru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
|
||||
{
|
||||
bp->prev->next = bp->next;
|
||||
bp->next->prev = bp->prev;
|
||||
push_to_mru(bp, list);
|
||||
} /* end of buf_cache_move_to_mru */
|
||||
|
||||
static void move_to_lru(BUF_CACHE_T *bp, BUF_CACHE_T *list)
|
||||
{
|
||||
bp->prev->next = bp->next;
|
||||
bp->next->prev = bp->prev;
|
||||
push_to_lru(bp, list);
|
||||
} /* end of buf_cache_move_to_lru */
|
||||
|
||||
/* end of exfat_cache.c */
|
94
fs/exfat/exfat_cache.h
Normal file
94
fs/exfat/exfat_cache.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_cache.h */
|
||||
/* PURPOSE : Header File for exFAT Cache Manager */
|
||||
/* (FAT Cache & Buffer Cache) */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Sung-Kwan Kim] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_CACHE_H
|
||||
#define _EXFAT_CACHE_H
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define LOCKBIT 0x01
|
||||
#define DIRTYBIT 0x02
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
typedef struct __BUF_CACHE_T {
|
||||
struct __BUF_CACHE_T *next;
|
||||
struct __BUF_CACHE_T *prev;
|
||||
struct __BUF_CACHE_T *hash_next;
|
||||
struct __BUF_CACHE_T *hash_prev;
|
||||
INT32 drv;
|
||||
UINT32 sec;
|
||||
UINT32 flag;
|
||||
struct buffer_head *buf_bh;
|
||||
} BUF_CACHE_T;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
INT32 buf_init(struct super_block *sb);
|
||||
INT32 buf_shutdown(struct super_block *sb);
|
||||
INT32 FAT_read(struct super_block *sb, UINT32 loc, UINT32 *content);
|
||||
INT32 FAT_write(struct super_block *sb, UINT32 loc, UINT32 content);
|
||||
UINT8 *FAT_getblk(struct super_block *sb, UINT32 sec);
|
||||
void FAT_modify(struct super_block *sb, UINT32 sec);
|
||||
void FAT_release_all(struct super_block *sb);
|
||||
void FAT_sync(struct super_block *sb);
|
||||
UINT8 *buf_getblk(struct super_block *sb, UINT32 sec);
|
||||
void buf_modify(struct super_block *sb, UINT32 sec);
|
||||
void buf_lock(struct super_block *sb, UINT32 sec);
|
||||
void buf_unlock(struct super_block *sb, UINT32 sec);
|
||||
void buf_release(struct super_block *sb, UINT32 sec);
|
||||
void buf_release_all(struct super_block *sb);
|
||||
void buf_sync(struct super_block *sb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_CACHE_H */
|
||||
|
||||
/* end of exfat_cache.h */
|
102
fs/exfat/exfat_config.h
Normal file
102
fs/exfat/exfat_config.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_config.h */
|
||||
/* PURPOSE : Header File for exFAT Configuable Policies */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_CONFIG_H
|
||||
#define _EXFAT_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* FFS CONFIGURATIONS */
|
||||
/* (CHANGE THIS PART IF REQUIRED) */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Target OS Platform */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define OS_NONOS 1
|
||||
#define OS_LINUX 2
|
||||
|
||||
#define FFS_CONFIG_OS OS_LINUX
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Set this definition to 1 to support APIs with pointer parameters */
|
||||
/* to 32-bit variables (e.g. read, write, seek, get_filesize) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
#define FFS_CONFIG_LEGACY_32BIT_API 0
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Set this definition to 1 to support APIs with pointer parameters */
|
||||
/* to 32-bit variables (e.g. read, write, seek, get_filesize) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
#define FFS_CONFIG_LEGACY_32BIT_API 0
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Set appropriate definitions to 1's to support the languages */
|
||||
/*----------------------------------------------------------------------*/
|
||||
#define FFS_CONFIG_SUPPORT_CP1250 1 // Central Europe
|
||||
#define FFS_CONFIG_SUPPORT_CP1251 1 // Cyrillic
|
||||
#define FFS_CONFIG_SUPPORT_CP1252 1 // Latin I
|
||||
#define FFS_CONFIG_SUPPORT_CP1253 1 // Greek
|
||||
#define FFS_CONFIG_SUPPORT_CP1254 1 // Turkish
|
||||
#define FFS_CONFIG_SUPPORT_CP1255 1 // Hebrew
|
||||
#define FFS_CONFIG_SUPPORT_CP1256 1 // Arabic
|
||||
#define FFS_CONFIG_SUPPORT_CP1257 1 // Baltic
|
||||
#define FFS_CONFIG_SUPPORT_CP1258 1 // Vietnamese
|
||||
#define FFS_CONFIG_SUPPORT_CP874 1 // Thai
|
||||
#define FFS_CONFIG_SUPPORT_CP932 1 // Japanese
|
||||
#define FFS_CONFIG_SUPPORT_CP936 1 // Simplified Chinese
|
||||
#define FFS_CONFIG_SUPPORT_CP949 1 // Korean
|
||||
#define FFS_CONFIG_SUPPORT_CP950 1 // Traditional Chinese
|
||||
#define FFS_CONFIG_SUPPORT_UTF8 1 // UTF8 encoding
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Feature Config */
|
||||
/*----------------------------------------------------------------------*/
|
||||
#define EXFAT_CONFIG_DISCARD 1 // mount option -o discard support
|
||||
#define EXFAT_CONFIG_KERNEL_DEBUG 1 // kernel debug features via ioctl
|
||||
#define EXFAT_CONFIG_DEBUG_MSG 0 // debugging message on/off
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_CONFIG_H */
|
||||
|
||||
/* end of exfat_config.h */
|
5187
fs/exfat/exfat_core.c
Normal file
5187
fs/exfat/exfat_core.c
Normal file
File diff suppressed because it is too large
Load diff
77
fs/exfat/exfat_data.c
Normal file
77
fs/exfat/exfat_data.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_data.c */
|
||||
/* PURPOSE : exFAT Configuable Data Definitions */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_data.h"
|
||||
#include "exfat_oal.h"
|
||||
|
||||
#include "exfat_blkdev.h"
|
||||
#include "exfat_cache.h"
|
||||
#include "exfat_nls.h"
|
||||
#include "exfat_super.h"
|
||||
#include "exfat.h"
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* GLOBAL VARIABLE DEFINITIONS */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* File Manager */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* file system volume table */
|
||||
FS_STRUCT_T fs_struct[MAX_DRIVE];
|
||||
|
||||
#if 0
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Buffer Manager */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* FAT cache */
|
||||
DECLARE_MUTEX(f_sem);
|
||||
BUF_CACHE_T FAT_cache_array[FAT_CACHE_SIZE];
|
||||
BUF_CACHE_T FAT_cache_lru_list;
|
||||
BUF_CACHE_T FAT_cache_hash_list[FAT_CACHE_HASH_SIZE];
|
||||
|
||||
/* buf cache */
|
||||
DECLARE_MUTEX(b_sem);
|
||||
BUF_CACHE_T buf_cache_array[BUF_CACHE_SIZE];
|
||||
BUF_CACHE_T buf_cache_lru_list;
|
||||
BUF_CACHE_T buf_cache_hash_list[BUF_CACHE_HASH_SIZE];
|
||||
#endif
|
||||
|
||||
/* end of exfat_data.c */
|
83
fs/exfat/exfat_data.h
Normal file
83
fs/exfat/exfat_data.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_data.h */
|
||||
/* PURPOSE : Header File for exFAT Configuable Constants */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_DATA_H
|
||||
#define _EXFAT_DATA_H
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* FFS CONFIGURATIONS */
|
||||
/* (CHANGE THIS PART IF REQUIRED) */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/* max number of block devices */
|
||||
#define MAX_DEVICE 2
|
||||
|
||||
/* max number of volumes on all block devices */
|
||||
#define MAX_DRIVE 2
|
||||
|
||||
/* max number of open files */
|
||||
#define MAX_OPEN 20
|
||||
|
||||
/* max number of root directory entries in FAT12/16 */
|
||||
/* (should be an exponential value of 2) */
|
||||
#define MAX_DENTRY 512
|
||||
|
||||
/* cache size (in number of sectors) */
|
||||
/* (should be an exponential value of 2) */
|
||||
#define FAT_CACHE_SIZE 128
|
||||
#define FAT_CACHE_HASH_SIZE 64
|
||||
#define BUF_CACHE_SIZE 256
|
||||
#define BUF_CACHE_HASH_SIZE 64
|
||||
|
||||
#ifndef CONFIG_EXFAT_DEFAULT_CODEPAGE
|
||||
#define CONFIG_EXFAT_DEFAULT_CODEPAGE 437
|
||||
#define CONFIG_EXFAT_DEFAULT_IOCHARSET "utf8"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_DATA_H */
|
||||
|
||||
/* end of exfat_data.h */
|
168
fs/exfat/exfat_global.c
Normal file
168
fs/exfat/exfat_global.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_global.c */
|
||||
/* PURPOSE : exFAT Miscellaneous Functions */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Global Variable Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* LIBRARY FUNCTION DEFINITIONS -- WELL-KNOWN FUNCTIONS */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* String Manipulation Functions */
|
||||
/* (defined if no system memory functions are available) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
INT32 __wstrchr(UINT16 *str, UINT16 wchar)
|
||||
{
|
||||
while (*str) {
|
||||
if (*(str++) == wchar) return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
INT32 __wstrlen(UINT16 *str)
|
||||
{
|
||||
INT32 length = 0;
|
||||
|
||||
while (*(str++)) length++;
|
||||
return(length);
|
||||
}
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* LIBRARY FUNCTION DEFINITIONS -- OTHER UTILITY FUNCTIONS */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Bitmap Manipulation Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define BITMAP_LOC(v) ((v) >> 3)
|
||||
#define BITMAP_SHIFT(v) ((v) & 0x07)
|
||||
|
||||
void Bitmap_set_all(UINT8 *bitmap, INT32 mapsize)
|
||||
{
|
||||
MEMSET(bitmap, 0xFF, mapsize);
|
||||
} /* end of Bitmap_set_all */
|
||||
|
||||
void Bitmap_clear_all(UINT8 *bitmap, INT32 mapsize)
|
||||
{
|
||||
MEMSET(bitmap, 0x0, mapsize);
|
||||
} /* end of Bitmap_clear_all */
|
||||
|
||||
INT32 Bitmap_test(UINT8 *bitmap, INT32 i)
|
||||
{
|
||||
UINT8 data;
|
||||
|
||||
data = bitmap[BITMAP_LOC(i)];
|
||||
if ((data >> BITMAP_SHIFT(i)) & 0x01) return(1);
|
||||
return(0);
|
||||
} /* end of Bitmap_test */
|
||||
|
||||
void Bitmap_set(UINT8 *bitmap, INT32 i)
|
||||
{
|
||||
bitmap[BITMAP_LOC(i)] |= (0x01 << BITMAP_SHIFT(i));
|
||||
} /* end of Bitmap_set */
|
||||
|
||||
void Bitmap_clear(UINT8 *bitmap, INT32 i)
|
||||
{
|
||||
bitmap[BITMAP_LOC(i)] &= ~(0x01 << BITMAP_SHIFT(i));
|
||||
} /* end of Bitmap_clear */
|
||||
|
||||
void Bitmap_nbits_set(UINT8 *bitmap, INT32 offset, INT32 nbits)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < nbits; i++) {
|
||||
Bitmap_set(bitmap, offset+i);
|
||||
}
|
||||
} /* end of Bitmap_nbits_set */
|
||||
|
||||
void Bitmap_nbits_clear(UINT8 *bitmap, INT32 offset, INT32 nbits)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < nbits; i++) {
|
||||
Bitmap_clear(bitmap, offset+i);
|
||||
}
|
||||
} /* end of Bitmap_nbits_clear */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Library Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* integer to ascii conversion */
|
||||
void my_itoa(INT8 *buf, INT32 v)
|
||||
{
|
||||
INT32 mod[10];
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
mod[i] = (v % 10);
|
||||
v = v / 10;
|
||||
if (v == 0) break;
|
||||
}
|
||||
|
||||
if (i == 10)
|
||||
i--;
|
||||
|
||||
for (; i >= 0; i--) {
|
||||
*buf = (UINT8) ('0' + mod[i]);
|
||||
buf++;
|
||||
}
|
||||
*buf = '\0';
|
||||
} /* end of my_itoa */
|
||||
|
||||
/* value to base 2 log conversion */
|
||||
INT32 my_log2(UINT32 v)
|
||||
{
|
||||
UINT32 bits = 0;
|
||||
|
||||
while (v > 1) {
|
||||
if (v & 0x01) return(-1);
|
||||
v >>= 1;
|
||||
bits++;
|
||||
}
|
||||
return(bits);
|
||||
} /* end of my_log2 */
|
||||
|
||||
/* end of exfat_global.c */
|
214
fs/exfat/exfat_global.h
Normal file
214
fs/exfat/exfat_global.h
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_global.h */
|
||||
/* PURPOSE : Header File for exFAT Global Definitions & Misc Functions */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_GLOBAL_H
|
||||
#define _EXFAT_GLOBAL_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/fs.h>
|
||||
|
||||
#include "exfat_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* CONSTANT & MACRO DEFINITIONS */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Well-Known Constants (DO NOT CHANGE THIS PART !!) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef OK
|
||||
#define OK 0
|
||||
#endif
|
||||
#ifndef FAIL
|
||||
#define FAIL 1
|
||||
#endif
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
/* Min/Max macro */
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* TYPE DEFINITIONS */
|
||||
/* (CHANGE THIS PART IF REQUIRED) */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/* type definitions for primitive types;
|
||||
these should be re-defined to meet its size for each OS platform;
|
||||
these should be used instead of primitive types for portability. */
|
||||
|
||||
typedef char INT8; // 1 byte signed integer
|
||||
typedef short INT16; // 2 byte signed integer
|
||||
typedef int INT32; // 4 byte signed integer
|
||||
typedef long long INT64; // 8 byte signed integer
|
||||
|
||||
typedef unsigned char UINT8; // 1 byte unsigned integer
|
||||
typedef unsigned short UINT16; // 2 byte unsigned integer
|
||||
typedef unsigned int UINT32; // 4 byte unsigned integer
|
||||
typedef unsigned long long UINT64; // 8 byte ussigned integer
|
||||
|
||||
typedef unsigned char BOOL;
|
||||
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* LIBRARY FUNCTION DECLARATIONS -- WELL-KNOWN FUNCTIONS */
|
||||
/* (CHANGE THIS PART IF REQUIRED) */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Memory Manipulation Macros & Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#ifdef MALLOC
|
||||
#undef MALLOC
|
||||
#endif
|
||||
#ifdef FREE
|
||||
#undef FREE
|
||||
#endif
|
||||
#ifdef MEMSET
|
||||
#undef MEMSET
|
||||
#endif
|
||||
#ifdef MEMCPY
|
||||
#undef MEMCPY
|
||||
#endif
|
||||
#ifdef MEMCMP
|
||||
#undef MEMCMP
|
||||
#endif
|
||||
|
||||
#define MALLOC(size) kmalloc(size, GFP_KERNEL)
|
||||
#define FREE(mem) if (mem) kfree(mem)
|
||||
#define MEMSET(mem, value, size) memset(mem, value, size)
|
||||
#define MEMCPY(dest, src, size) memcpy(dest, src, size)
|
||||
#define MEMCMP(mem1, mem2, size) memcmp(mem1, mem2, size)
|
||||
#define COPY_DENTRY(dest, src) memcpy(dest, src, sizeof(DENTRY_T))
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* String Manipulation Macros & Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define STRCPY(dest, src) strcpy(dest, src)
|
||||
#define STRNCPY(dest, src, n) strncpy(dest, src, n)
|
||||
#define STRCAT(str1, str2) strcat(str1, str2)
|
||||
#define STRCMP(str1, str2) strcmp(str1, str2)
|
||||
#define STRNCMP(str1, str2, n) strncmp(str1, str2, n)
|
||||
#define STRLEN(str) strlen(str)
|
||||
|
||||
INT32 __wstrchr(UINT16 *str, UINT16 wchar);
|
||||
INT32 __wstrlen(UINT16 *str);
|
||||
|
||||
#define WSTRCHR(str, wchar) __wstrchr(str, wchar)
|
||||
#define WSTRLEN(str) __wstrlen(str)
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Debugging Macros & Functions */
|
||||
/* EXFAT_CONFIG_DEBUG_MSG is configured in exfat_config.h */
|
||||
/*----------------------------------------------------------------------*/
|
||||
#if EXFAT_CONFIG_DEBUG_MSG
|
||||
#define PRINTK(...) \
|
||||
do { \
|
||||
printk("[EXFAT] " __VA_ARGS__); \
|
||||
} while(0)
|
||||
#else
|
||||
#define PRINTK(...)
|
||||
#endif
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* LIBRARY FUNCTION DECLARATIONS -- OTHER UTILITY FUNCTIONS */
|
||||
/* (DO NOT CHANGE THIS PART !!) */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Bitmap Manipulation Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
void Bitmap_set_all(UINT8 *bitmap, INT32 mapsize);
|
||||
void Bitmap_clear_all(UINT8 *bitmap, INT32 mapsize);
|
||||
INT32 Bitmap_test(UINT8 *bitmap, INT32 i);
|
||||
void Bitmap_set(UINT8 *bitmap, INT32 i);
|
||||
void Bitmap_clear(UINT8 *bitmpa, INT32 i);
|
||||
void Bitmap_nbits_set(UINT8 *bitmap, INT32 offset, INT32 nbits);
|
||||
void Bitmap_nbits_clear(UINT8 *bitmap, INT32 offset, INT32 nbits);
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Miscellaneous Library Functions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
void my_itoa(INT8 *buf, INT32 v);
|
||||
INT32 my_log2(UINT32 v);
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* DEFINITIONS FOR DEBUGGING */
|
||||
/* (CHANGE THIS PART IF REQUIRED) */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
/* debug message ouput macro */
|
||||
#ifdef PRINT
|
||||
#undef PRINT
|
||||
#endif
|
||||
|
||||
#define PRINT printk
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_GLOBAL_H */
|
||||
|
||||
/* end of exfat_global.h */
|
394
fs/exfat/exfat_nls.c
Normal file
394
fs/exfat/exfat_nls.c
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_nls.c */
|
||||
/* PURPOSE : exFAT NLS Manager */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_data.h"
|
||||
|
||||
#include "exfat_nls.h"
|
||||
#include "exfat_api.h"
|
||||
#include "exfat_super.h"
|
||||
#include "exfat.h"
|
||||
|
||||
#include <linux/nls.h>
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Global Variable Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Local Variable Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
static UINT16 bad_dos_chars[] = {
|
||||
/* + , ; = [ ] */
|
||||
0x002B, 0x002C, 0x003B, 0x003D, 0x005B, 0x005D,
|
||||
0xFF0B, 0xFF0C, 0xFF1B, 0xFF1D, 0xFF3B, 0xFF3D,
|
||||
0
|
||||
};
|
||||
|
||||
static UINT16 bad_uni_chars[] = {
|
||||
/* " * / : < > ? \ | */
|
||||
0x0022, 0x002A, 0x002F, 0x003A,
|
||||
0x003C, 0x003E, 0x003F, 0x005C, 0x007C,
|
||||
0
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Local Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
static INT32 convert_uni_to_ch(struct nls_table *nls, UINT8 *ch, UINT16 uni, INT32 *lossy);
|
||||
static INT32 convert_ch_to_uni(struct nls_table *nls, UINT16 *uni, UINT8 *ch, INT32 *lossy);
|
||||
|
||||
/*======================================================================*/
|
||||
/* Global Function Definitions */
|
||||
/*======================================================================*/
|
||||
|
||||
UINT16 nls_upper(struct super_block *sb, UINT16 a)
|
||||
{
|
||||
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
|
||||
|
||||
if (EXFAT_SB(sb)->options.casesensitive)
|
||||
return(a);
|
||||
if (p_fs->vol_utbl != NULL && (p_fs->vol_utbl)[get_col_index(a)] != NULL)
|
||||
return (p_fs->vol_utbl)[get_col_index(a)][get_row_index(a)];
|
||||
else
|
||||
return a;
|
||||
}
|
||||
|
||||
INT32 nls_dosname_cmp(struct super_block *sb, UINT8 *a, UINT8 *b)
|
||||
{
|
||||
return(STRNCMP((void *) a, (void *) b, DOS_NAME_LENGTH));
|
||||
} /* end of nls_dosname_cmp */
|
||||
|
||||
INT32 nls_uniname_cmp(struct super_block *sb, UINT16 *a, UINT16 *b)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < MAX_NAME_LENGTH; i++, a++, b++) {
|
||||
if (nls_upper(sb, *a) != nls_upper(sb, *b)) return(1);
|
||||
if (*a == 0x0) return(0);
|
||||
}
|
||||
return(0);
|
||||
} /* end of nls_uniname_cmp */
|
||||
|
||||
void nls_uniname_to_dosname(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname, INT32 *p_lossy)
|
||||
{
|
||||
INT32 i, j, len, lossy = FALSE;
|
||||
UINT8 buf[MAX_CHARSET_SIZE];
|
||||
UINT8 lower = 0, upper = 0;
|
||||
UINT8 *dosname = p_dosname->name;
|
||||
UINT16 *uniname = p_uniname->name;
|
||||
UINT16 *p, *last_period;
|
||||
struct nls_table *nls = EXFAT_SB(sb)->nls_disk;
|
||||
|
||||
for (i = 0; i < DOS_NAME_LENGTH; i++) {
|
||||
*(dosname+i) = ' ';
|
||||
}
|
||||
|
||||
if (!nls_uniname_cmp(sb, uniname, (UINT16 *) UNI_CUR_DIR_NAME)) {
|
||||
*(dosname) = '.';
|
||||
p_dosname->name_case = 0x0;
|
||||
if (p_lossy != NULL) *p_lossy = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nls_uniname_cmp(sb, uniname, (UINT16 *) UNI_PAR_DIR_NAME)) {
|
||||
*(dosname) = '.';
|
||||
*(dosname+1) = '.';
|
||||
p_dosname->name_case = 0x0;
|
||||
if (p_lossy != NULL) *p_lossy = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
/* search for the last embedded period */
|
||||
last_period = NULL;
|
||||
for (p = uniname; *p; p++) {
|
||||
if (*p == (UINT16) '.') last_period = p;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
while (i < DOS_NAME_LENGTH) {
|
||||
if (i == 8) {
|
||||
if (last_period == NULL) break;
|
||||
|
||||
if (uniname <= last_period) {
|
||||
if (uniname < last_period) lossy = TRUE;
|
||||
uniname = last_period + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (*uniname == (UINT16) '\0') {
|
||||
break;
|
||||
} else if (*uniname == (UINT16) ' ') {
|
||||
lossy = TRUE;
|
||||
} else if (*uniname == (UINT16) '.') {
|
||||
if (uniname < last_period) lossy = TRUE;
|
||||
else i = 8;
|
||||
} else if (WSTRCHR(bad_dos_chars, *uniname)) {
|
||||
lossy = TRUE;
|
||||
*(dosname+i) = '_';
|
||||
i++;
|
||||
} else {
|
||||
len = convert_uni_to_ch(nls, buf, *uniname, &lossy);
|
||||
|
||||
if (len > 1) {
|
||||
if ((i >= 8) && ((i+len) > DOS_NAME_LENGTH)) {
|
||||
break;
|
||||
}
|
||||
if ((i < 8) && ((i+len) > 8)) {
|
||||
i = 8;
|
||||
continue;
|
||||
}
|
||||
|
||||
lower = 0xFF;
|
||||
|
||||
for (j = 0; j < len; j++, i++) {
|
||||
*(dosname+i) = *(buf+j);
|
||||
}
|
||||
} else { /* len == 1 */
|
||||
if ((*buf >= 'a') && (*buf <= 'z')) {
|
||||
*(dosname+i) = *buf - ('a' - 'A');
|
||||
|
||||
if (i < 8) lower |= 0x08;
|
||||
else lower |= 0x10;
|
||||
} else if ((*buf >= 'A') && (*buf <= 'Z')) {
|
||||
*(dosname+i) = *buf;
|
||||
|
||||
if (i < 8) upper |= 0x08;
|
||||
else upper |= 0x10;
|
||||
} else {
|
||||
*(dosname+i) = *buf;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
uniname++;
|
||||
}
|
||||
|
||||
if (*dosname == 0xE5) *dosname = 0x05;
|
||||
if (*uniname != 0x0) lossy = TRUE;
|
||||
|
||||
if (upper & lower) p_dosname->name_case = 0xFF;
|
||||
else p_dosname->name_case = lower;
|
||||
|
||||
if (p_lossy != NULL) *p_lossy = lossy;
|
||||
} /* end of nls_uniname_to_dosname */
|
||||
|
||||
void nls_dosname_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname)
|
||||
{
|
||||
INT32 i = 0, j, n = 0;
|
||||
UINT8 buf[DOS_NAME_LENGTH+2];
|
||||
UINT8 *dosname = p_dosname->name;
|
||||
UINT16 *uniname = p_uniname->name;
|
||||
struct nls_table *nls = EXFAT_SB(sb)->nls_disk;
|
||||
|
||||
if (*dosname == 0x05) {
|
||||
*buf = 0xE5;
|
||||
i++;
|
||||
n++;
|
||||
}
|
||||
|
||||
for ( ; i < 8; i++, n++) {
|
||||
if (*(dosname+i) == ' ') break;
|
||||
|
||||
if ((*(dosname+i) >= 'A') && (*(dosname+i) <= 'Z') && (p_dosname->name_case & 0x08))
|
||||
*(buf+n) = *(dosname+i) + ('a' - 'A');
|
||||
else
|
||||
*(buf+n) = *(dosname+i);
|
||||
}
|
||||
if (*(dosname+8) != ' ') {
|
||||
*(buf+n) = '.';
|
||||
n++;
|
||||
}
|
||||
|
||||
for (i = 8; i < DOS_NAME_LENGTH; i++, n++) {
|
||||
if (*(dosname+i) == ' ') break;
|
||||
|
||||
if ((*(dosname+i) >= 'A') && (*(dosname+i) <= 'Z') && (p_dosname->name_case & 0x10))
|
||||
*(buf+n) = *(dosname+i) + ('a' - 'A');
|
||||
else
|
||||
*(buf+n) = *(dosname+i);
|
||||
}
|
||||
*(buf+n) = '\0';
|
||||
|
||||
i = j = 0;
|
||||
while (j < (MAX_NAME_LENGTH-1)) {
|
||||
if (*(buf+i) == '\0') break;
|
||||
|
||||
i += convert_ch_to_uni(nls, uniname, (buf+i), NULL);
|
||||
|
||||
uniname++;
|
||||
j++;
|
||||
}
|
||||
|
||||
*uniname = (UINT16) '\0';
|
||||
} /* end of nls_dosname_to_uniname */
|
||||
|
||||
void nls_uniname_to_cstring(struct super_block *sb, UINT8 *p_cstring, UNI_NAME_T *p_uniname)
|
||||
{
|
||||
INT32 i, j, len;
|
||||
UINT8 buf[MAX_CHARSET_SIZE];
|
||||
UINT16 *uniname = p_uniname->name;
|
||||
struct nls_table *nls = EXFAT_SB(sb)->nls_io;
|
||||
|
||||
i = 0;
|
||||
while (i < (MAX_NAME_LENGTH-1)) {
|
||||
if (*uniname == (UINT16) '\0') break;
|
||||
|
||||
len = convert_uni_to_ch(nls, buf, *uniname, NULL);
|
||||
|
||||
if (len > 1) {
|
||||
for (j = 0; j < len; j++)
|
||||
*p_cstring++ = (INT8) *(buf+j);
|
||||
} else { /* len == 1 */
|
||||
*p_cstring++ = (INT8) *buf;
|
||||
}
|
||||
|
||||
uniname++;
|
||||
i++;
|
||||
}
|
||||
|
||||
*p_cstring = '\0';
|
||||
} /* end of nls_uniname_to_cstring */
|
||||
|
||||
void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, UINT8 *p_cstring, INT32 *p_lossy)
|
||||
{
|
||||
INT32 i, j, lossy = FALSE;
|
||||
UINT8 *end_of_name;
|
||||
UINT8 upname[MAX_NAME_LENGTH * 2];
|
||||
UINT16 *uniname = p_uniname->name;
|
||||
struct nls_table *nls = EXFAT_SB(sb)->nls_io;
|
||||
|
||||
|
||||
/* strip all trailing spaces */
|
||||
end_of_name = p_cstring + STRLEN((INT8 *) p_cstring);
|
||||
|
||||
while (*(--end_of_name) == ' ') {
|
||||
if (end_of_name < p_cstring) break;
|
||||
}
|
||||
*(++end_of_name) = '\0';
|
||||
|
||||
if (STRCMP((INT8 *) p_cstring, ".") && STRCMP((INT8 *) p_cstring, "..")) {
|
||||
|
||||
/* strip all trailing periods */
|
||||
while (*(--end_of_name) == '.') {
|
||||
if (end_of_name < p_cstring) break;
|
||||
}
|
||||
*(++end_of_name) = '\0';
|
||||
}
|
||||
|
||||
if (*p_cstring == '\0')
|
||||
lossy = TRUE;
|
||||
|
||||
i = j = 0;
|
||||
while (j < (MAX_NAME_LENGTH-1)) {
|
||||
if (*(p_cstring+i) == '\0') break;
|
||||
|
||||
i += convert_ch_to_uni(nls, uniname, (UINT8 *)(p_cstring+i), &lossy);
|
||||
|
||||
if ((*uniname < 0x0020) || WSTRCHR(bad_uni_chars, *uniname))
|
||||
lossy = TRUE;
|
||||
|
||||
SET16_A(upname + j * 2, nls_upper(sb, *uniname));
|
||||
|
||||
uniname++;
|
||||
j++;
|
||||
}
|
||||
|
||||
if (*(p_cstring+i) != '\0')
|
||||
lossy = TRUE;
|
||||
*uniname = (UINT16) '\0';
|
||||
|
||||
p_uniname->name_len = j;
|
||||
p_uniname->name_hash = calc_checksum_2byte((void *) upname, j<<1, 0, CS_DEFAULT);
|
||||
|
||||
if (p_lossy != NULL)
|
||||
*p_lossy = lossy;
|
||||
} /* end of nls_cstring_to_uniname */
|
||||
|
||||
/*======================================================================*/
|
||||
/* Local Function Definitions */
|
||||
/*======================================================================*/
|
||||
|
||||
static INT32 convert_ch_to_uni(struct nls_table *nls, UINT16 *uni, UINT8 *ch, INT32 *lossy)
|
||||
{
|
||||
int len;
|
||||
|
||||
*uni = 0x0;
|
||||
|
||||
if (ch[0] < 0x80) {
|
||||
*uni = (UINT16) ch[0];
|
||||
return(1);
|
||||
}
|
||||
|
||||
if ((len = nls->char2uni(ch, NLS_MAX_CHARSET_SIZE, uni)) < 0) {
|
||||
/* conversion failed */
|
||||
printk("%s: fail to use nls \n", __func__);
|
||||
if (lossy != NULL)
|
||||
*lossy = TRUE;
|
||||
*uni = (UINT16) '_';
|
||||
if (!strcmp(nls->charset, "utf8")) return(1);
|
||||
else return(2);
|
||||
}
|
||||
|
||||
return(len);
|
||||
} /* end of convert_ch_to_uni */
|
||||
|
||||
static INT32 convert_uni_to_ch(struct nls_table *nls, UINT8 *ch, UINT16 uni, INT32 *lossy)
|
||||
{
|
||||
int len;
|
||||
|
||||
ch[0] = 0x0;
|
||||
|
||||
if (uni < 0x0080) {
|
||||
ch[0] = (UINT8) uni;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if ((len = nls->uni2char(uni, ch, NLS_MAX_CHARSET_SIZE)) < 0) {
|
||||
/* conversion failed */
|
||||
printk("%s: fail to use nls \n", __func__);
|
||||
if (lossy != NULL) *lossy = TRUE;
|
||||
ch[0] = '_';
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(len);
|
||||
|
||||
} /* end of convert_uni_to_ch */
|
||||
|
||||
/* end of exfat_nls.c */
|
101
fs/exfat/exfat_nls.h
Normal file
101
fs/exfat/exfat_nls.h
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_nls.h */
|
||||
/* PURPOSE : Header File for exFAT NLS Manager */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_NLS_H
|
||||
#define _EXFAT_NLS_H
|
||||
|
||||
#include <linux/nls.h>
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define NUM_UPCASE 2918
|
||||
|
||||
#define DOS_CUR_DIR_NAME ". "
|
||||
#define DOS_PAR_DIR_NAME ".. "
|
||||
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
#define UNI_CUR_DIR_NAME ".\0"
|
||||
#define UNI_PAR_DIR_NAME ".\0.\0"
|
||||
#else
|
||||
#define UNI_CUR_DIR_NAME "\0."
|
||||
#define UNI_PAR_DIR_NAME "\0.\0."
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* DOS name stucture */
|
||||
typedef struct {
|
||||
UINT8 name[DOS_NAME_LENGTH];
|
||||
UINT8 name_case;
|
||||
} DOS_NAME_T;
|
||||
|
||||
/* unicode name stucture */
|
||||
typedef struct {
|
||||
UINT16 name[MAX_NAME_LENGTH];
|
||||
UINT16 name_hash;
|
||||
UINT8 name_len;
|
||||
} UNI_NAME_T;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* NLS management function */
|
||||
UINT16 nls_upper(struct super_block *sb, UINT16 a);
|
||||
INT32 nls_dosname_cmp(struct super_block *sb, UINT8 *a, UINT8 *b);
|
||||
INT32 nls_uniname_cmp(struct super_block *sb, UINT16 *a, UINT16 *b);
|
||||
void nls_uniname_to_dosname(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname, INT32 *p_lossy);
|
||||
void nls_dosname_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname);
|
||||
void nls_uniname_to_cstring(struct super_block *sb, UINT8 *p_cstring, UNI_NAME_T *p_uniname);
|
||||
void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, UINT8 *p_cstring, INT32 *p_lossy);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_NLS_H */
|
||||
|
||||
/* end of exfat_nls.h */
|
189
fs/exfat/exfat_oal.c
Normal file
189
fs/exfat/exfat_oal.c
Normal file
|
@ -0,0 +1,189 @@
|
|||
/* Some of the source code in this file came from "linux/fs/fat/misc.c". */
|
||||
/*
|
||||
* linux/fs/fat/misc.c
|
||||
*
|
||||
* Written 1992,1993 by Werner Almesberger
|
||||
* 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980
|
||||
* and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_oal.c */
|
||||
/* PURPOSE : exFAT OS Adaptation Layer */
|
||||
/* (Semaphore Functions & Real-Time Clock Functions) */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_api.h"
|
||||
#include "exfat_oal.h"
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* SEMAPHORE FUNCTIONS */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
DECLARE_MUTEX(z_sem);
|
||||
|
||||
INT32 sm_init(struct semaphore *sm)
|
||||
{
|
||||
sema_init(sm, 1);
|
||||
return(0);
|
||||
} /* end of sm_init */
|
||||
|
||||
INT32 sm_P(struct semaphore *sm)
|
||||
{
|
||||
down(sm);
|
||||
return 0;
|
||||
} /* end of sm_P */
|
||||
|
||||
void sm_V(struct semaphore *sm)
|
||||
{
|
||||
up(sm);
|
||||
} /* end of sm_V */
|
||||
|
||||
|
||||
/*======================================================================*/
|
||||
/* */
|
||||
/* REAL-TIME CLOCK FUNCTIONS */
|
||||
/* */
|
||||
/*======================================================================*/
|
||||
|
||||
extern struct timezone sys_tz;
|
||||
|
||||
/*
|
||||
* The epoch of FAT timestamp is 1980.
|
||||
* : bits : value
|
||||
* date: 0 - 4: day (1 - 31)
|
||||
* date: 5 - 8: month (1 - 12)
|
||||
* date: 9 - 15: year (0 - 127) from 1980
|
||||
* time: 0 - 4: sec (0 - 29) 2sec counts
|
||||
* time: 5 - 10: min (0 - 59)
|
||||
* time: 11 - 15: hour (0 - 23)
|
||||
*/
|
||||
#define UNIX_SECS_1980 315532800L
|
||||
|
||||
#if BITS_PER_LONG == 64
|
||||
#define UNIX_SECS_2108 4354819200L
|
||||
#endif
|
||||
/* days between 1.1.70 and 1.1.80 (2 leap days) */
|
||||
#define DAYS_DELTA_DECADE (365 * 10 + 2)
|
||||
/* 120 (2100 - 1980) isn't leap year */
|
||||
#define NO_LEAP_YEAR_2100 (120)
|
||||
#define IS_LEAP_YEAR(y) (!((y) & 3) && (y) != NO_LEAP_YEAR_2100)
|
||||
|
||||
#define SECS_PER_MIN (60)
|
||||
#define SECS_PER_HOUR (60 * SECS_PER_MIN)
|
||||
#define SECS_PER_DAY (24 * SECS_PER_HOUR)
|
||||
|
||||
#define MAKE_LEAP_YEAR(leap_year, year) \
|
||||
do { \
|
||||
if (unlikely(year > NO_LEAP_YEAR_2100)) \
|
||||
leap_year = ((year + 3) / 4) - 1; \
|
||||
else \
|
||||
leap_year = ((year + 3) / 4); \
|
||||
} while(0)
|
||||
|
||||
/* Linear day numbers of the respective 1sts in non-leap years. */
|
||||
static time_t accum_days_in_year[] = {
|
||||
/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */
|
||||
0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0,
|
||||
};
|
||||
|
||||
TIMESTAMP_T *tm_current(TIMESTAMP_T *tp)
|
||||
{
|
||||
struct timespec ts = CURRENT_TIME_SEC;
|
||||
time_t second = ts.tv_sec;
|
||||
time_t day, leap_day, month, year;
|
||||
|
||||
second -= sys_tz.tz_minuteswest * SECS_PER_MIN;
|
||||
|
||||
/* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
|
||||
if (second < UNIX_SECS_1980) {
|
||||
tp->sec = 0;
|
||||
tp->min = 0;
|
||||
tp->hour = 0;
|
||||
tp->day = 1;
|
||||
tp->mon = 1;
|
||||
tp->year = 0;
|
||||
return(tp);
|
||||
}
|
||||
#if BITS_PER_LONG == 64
|
||||
if (second >= UNIX_SECS_2108) {
|
||||
tp->sec = 59;
|
||||
tp->min = 59;
|
||||
tp->hour = 23;
|
||||
tp->day = 31;
|
||||
tp->mon = 12;
|
||||
tp->year = 127;
|
||||
return(tp);
|
||||
}
|
||||
#endif
|
||||
|
||||
day = second / SECS_PER_DAY - DAYS_DELTA_DECADE;
|
||||
year = day / 365;
|
||||
|
||||
MAKE_LEAP_YEAR(leap_day, year);
|
||||
if (year * 365 + leap_day > day)
|
||||
year--;
|
||||
|
||||
MAKE_LEAP_YEAR(leap_day, year);
|
||||
|
||||
day -= year * 365 + leap_day;
|
||||
|
||||
if (IS_LEAP_YEAR(year) && day == accum_days_in_year[3]) {
|
||||
month = 2;
|
||||
} else {
|
||||
if (IS_LEAP_YEAR(year) && day > accum_days_in_year[3])
|
||||
day--;
|
||||
for (month = 1; month < 12; month++) {
|
||||
if (accum_days_in_year[month + 1] > day)
|
||||
break;
|
||||
}
|
||||
}
|
||||
day -= accum_days_in_year[month];
|
||||
|
||||
tp->sec = second % SECS_PER_MIN;
|
||||
tp->min = (second / SECS_PER_MIN) % 60;
|
||||
tp->hour = (second / SECS_PER_HOUR) % 24;
|
||||
tp->day = day + 1;
|
||||
tp->mon = month;
|
||||
tp->year = year;
|
||||
|
||||
return(tp);
|
||||
} /* end of tm_current */
|
||||
|
||||
/* end of exfat_oal.c */
|
88
fs/exfat/exfat_oal.h
Normal file
88
fs/exfat/exfat_oal.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_oal.h */
|
||||
/* PURPOSE : Header File for exFAT OS Adaptation Layer */
|
||||
/* (Semaphore Functions & Real-Time Clock Functions) */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_OAL_H
|
||||
#define _EXFAT_OAL_H
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include <linux/version.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions (Configurable) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions (Non-Configurable) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
typedef struct {
|
||||
UINT16 sec; /* 0 ~ 59 */
|
||||
UINT16 min; /* 0 ~ 59 */
|
||||
UINT16 hour; /* 0 ~ 23 */
|
||||
UINT16 day; /* 1 ~ 31 */
|
||||
UINT16 mon; /* 1 ~ 12 */
|
||||
UINT16 year; /* 0 ~ 127 (since 1980) */
|
||||
} TIMESTAMP_T;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
|
||||
#define DECLARE_MUTEX(m) DEFINE_SEMAPHORE(m)
|
||||
#endif
|
||||
|
||||
INT32 sm_init(struct semaphore *sm);
|
||||
INT32 sm_P(struct semaphore *sm);
|
||||
void sm_V(struct semaphore *sm);
|
||||
|
||||
TIMESTAMP_T *tm_current(TIMESTAMP_T *tm);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_OAL_H */
|
||||
|
||||
/* end of exfat_oal.h */
|
92
fs/exfat/exfat_part.h
Normal file
92
fs/exfat/exfat_part.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_part.h */
|
||||
/* PURPOSE : Header File for exFAT Partition Manager */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#ifndef _EXFAT_PART_H
|
||||
#define _EXFAT_PART_H
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_api.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Constant & Macro Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#define MBR_SIGNATURE 0xAA55
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* MS-DOS FAT master boot record (512 bytes) */
|
||||
typedef struct {
|
||||
UINT8 boot_code[446];
|
||||
UINT8 partition[64];
|
||||
UINT8 signature[2];
|
||||
} MBR_SECTOR_T;
|
||||
|
||||
/* MS-DOS FAT partition table (64 bytes) */
|
||||
typedef struct {
|
||||
UINT8 def_boot;
|
||||
UINT8 bgn_chs[3];
|
||||
UINT8 sys_type;
|
||||
UINT8 end_chs[3];
|
||||
UINT8 start_sector[4];
|
||||
UINT8 num_sectors[4];
|
||||
} PART_ENTRY_T;
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
/* volume management functions */
|
||||
INT32 ffsSetPartition(INT32 dev, INT32 num_vol, PART_INFO_T *vol_spec);
|
||||
INT32 ffsGetPartition(INT32 dev, INT32 *num_vol, PART_INFO_T *vol_spec);
|
||||
INT32 ffsGetDevInfo(INT32 dev, DEV_INFO_T *info);
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* External Function Declarations (NOT TO UPPER LAYER) */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _EXFAT_PART_H */
|
||||
|
||||
/* end of exfat_part.h */
|
2301
fs/exfat/exfat_super.c
Normal file
2301
fs/exfat/exfat_super.c
Normal file
File diff suppressed because it is too large
Load diff
172
fs/exfat/exfat_super.h
Normal file
172
fs/exfat/exfat_super.h
Normal file
|
@ -0,0 +1,172 @@
|
|||
/* Some of the source code in this file came from "linux/fs/fat/fat.h". */
|
||||
|
||||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _EXFAT_LINUX_H
|
||||
#define _EXFAT_LINUX_H
|
||||
|
||||
#include <linux/buffer_head.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/nls.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/swap.h>
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
#include "exfat_data.h"
|
||||
#include "exfat_oal.h"
|
||||
|
||||
#include "exfat_blkdev.h"
|
||||
#include "exfat_cache.h"
|
||||
#include "exfat_part.h"
|
||||
#include "exfat_nls.h"
|
||||
#include "exfat_api.h"
|
||||
#include "exfat.h"
|
||||
|
||||
#define EXFAT_ERRORS_CONT 1 /* ignore error and continue */
|
||||
#define EXFAT_ERRORS_PANIC 2 /* panic on error */
|
||||
#define EXFAT_ERRORS_RO 3 /* remount r/o on error */
|
||||
|
||||
/* ioctl command */
|
||||
#define EXFAT_IOCTL_GET_VOLUME_ID _IOR('r', 0x12, __u32)
|
||||
|
||||
struct exfat_mount_options {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)
|
||||
kuid_t fs_uid;
|
||||
kgid_t fs_gid;
|
||||
#else
|
||||
uid_t fs_uid;
|
||||
gid_t fs_gid;
|
||||
#endif
|
||||
unsigned short fs_fmask;
|
||||
unsigned short fs_dmask;
|
||||
unsigned short allow_utime; /* permission for setting the [am]time */
|
||||
unsigned short codepage; /* codepage for shortname conversions */
|
||||
char *iocharset; /* charset for filename input/display */
|
||||
unsigned char casesensitive;
|
||||
unsigned char errors; /* on error: continue, panic, remount-ro */
|
||||
#if EXFAT_CONFIG_DISCARD
|
||||
unsigned char discard; /* flag on if -o dicard specified and device support discard() */
|
||||
#endif /* EXFAT_CONFIG_DISCARD */
|
||||
};
|
||||
|
||||
#define EXFAT_HASH_BITS 8
|
||||
#define EXFAT_HASH_SIZE (1UL << EXFAT_HASH_BITS)
|
||||
|
||||
/*
|
||||
* EXFAT file system in-core superblock data
|
||||
*/
|
||||
struct exfat_sb_info {
|
||||
FS_INFO_T fs_info;
|
||||
BD_INFO_T bd_info;
|
||||
|
||||
struct exfat_mount_options options;
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,7,00)
|
||||
int s_dirt;
|
||||
struct mutex s_lock;
|
||||
#endif
|
||||
struct nls_table *nls_disk; /* Codepage used on disk */
|
||||
struct nls_table *nls_io; /* Charset used for input and display */
|
||||
|
||||
struct inode *fat_inode;
|
||||
|
||||
spinlock_t inode_hash_lock;
|
||||
struct hlist_head inode_hashtable[EXFAT_HASH_SIZE];
|
||||
#if EXFAT_CONFIG_KERNEL_DEBUG
|
||||
long debug_flags;
|
||||
#endif /* EXFAT_CONFIG_KERNEL_DEBUG */
|
||||
};
|
||||
|
||||
/*
|
||||
* EXFAT file system inode data in memory
|
||||
*/
|
||||
struct exfat_inode_info {
|
||||
FILE_ID_T fid;
|
||||
char *target;
|
||||
/* NOTE: mmu_private is 64bits, so must hold ->i_mutex to access */
|
||||
loff_t mmu_private; /* physically allocated size */
|
||||
loff_t i_pos; /* on-disk position of directory entry or 0 */
|
||||
struct hlist_node i_hash_fat; /* hash by i_location */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,4,00)
|
||||
struct rw_semaphore truncate_lock;
|
||||
#endif
|
||||
struct inode vfs_inode;
|
||||
struct rw_semaphore i_alloc_sem; /* protect bmap against truncate */
|
||||
};
|
||||
|
||||
#define EXFAT_SB(sb) ((struct exfat_sb_info *)((sb)->s_fs_info))
|
||||
|
||||
static inline struct exfat_inode_info *EXFAT_I(struct inode *inode) {
|
||||
return container_of(inode, struct exfat_inode_info, vfs_inode);
|
||||
}
|
||||
|
||||
/*
|
||||
* If ->i_mode can't hold S_IWUGO (i.e. ATTR_RO), we use ->i_attrs to
|
||||
* save ATTR_RO instead of ->i_mode.
|
||||
*
|
||||
* If it's directory and !sbi->options.rodir, ATTR_RO isn't read-only
|
||||
* bit, it's just used as flag for app.
|
||||
*/
|
||||
static inline int exfat_mode_can_hold_ro(struct inode *inode)
|
||||
{
|
||||
struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
|
||||
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
return 0;
|
||||
|
||||
if ((~sbi->options.fs_fmask) & S_IWUGO)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert attribute bits and a mask to the UNIX mode. */
|
||||
static inline mode_t exfat_make_mode(struct exfat_sb_info *sbi,
|
||||
u32 attr, mode_t mode)
|
||||
{
|
||||
if ((attr & ATTR_READONLY) && !(attr & ATTR_SUBDIR))
|
||||
mode &= ~S_IWUGO;
|
||||
|
||||
if (attr & ATTR_SUBDIR)
|
||||
return (mode & ~sbi->options.fs_dmask) | S_IFDIR;
|
||||
else if (attr & ATTR_SYMLINK)
|
||||
return (mode & ~sbi->options.fs_dmask) | S_IFLNK;
|
||||
else
|
||||
return (mode & ~sbi->options.fs_fmask) | S_IFREG;
|
||||
}
|
||||
|
||||
/* Return the FAT attribute byte for this inode */
|
||||
static inline u32 exfat_make_attr(struct inode *inode)
|
||||
{
|
||||
if (exfat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO))
|
||||
return ((EXFAT_I(inode)->fid.attr) | ATTR_READONLY);
|
||||
else
|
||||
return (EXFAT_I(inode)->fid.attr);
|
||||
}
|
||||
|
||||
static inline void exfat_save_attr(struct inode *inode, u32 attr)
|
||||
{
|
||||
if (exfat_mode_can_hold_ro(inode))
|
||||
EXFAT_I(inode)->fid.attr = attr & ATTR_RWMASK;
|
||||
else
|
||||
EXFAT_I(inode)->fid.attr = attr & (ATTR_RWMASK | ATTR_READONLY);
|
||||
}
|
||||
|
||||
#endif /* _EXFAT_LINUX_H */
|
408
fs/exfat/exfat_upcase.c
Normal file
408
fs/exfat/exfat_upcase.c
Normal file
|
@ -0,0 +1,408 @@
|
|||
/*
|
||||
* Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_upcase.c */
|
||||
/* PURPOSE : exFAT Up-case Table */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY (Ver 0.9) */
|
||||
/* */
|
||||
/* - 2010.11.15 [Joosun Hahn] : first writing */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#include "exfat_config.h"
|
||||
#include "exfat_global.h"
|
||||
|
||||
#include "exfat_nls.h"
|
||||
|
||||
UINT8 uni_upcase[NUM_UPCASE<<1] = {
|
||||
0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00,
|
||||
0x08, 0x00, 0x09, 0x00, 0x0A, 0x00, 0x0B, 0x00, 0x0C, 0x00, 0x0D, 0x00, 0x0E, 0x00, 0x0F, 0x00,
|
||||
0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
|
||||
0x18, 0x00, 0x19, 0x00, 0x1A, 0x00, 0x1B, 0x00, 0x1C, 0x00, 0x1D, 0x00, 0x1E, 0x00, 0x1F, 0x00,
|
||||
0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00,
|
||||
0x28, 0x00, 0x29, 0x00, 0x2A, 0x00, 0x2B, 0x00, 0x2C, 0x00, 0x2D, 0x00, 0x2E, 0x00, 0x2F, 0x00,
|
||||
0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00,
|
||||
0x38, 0x00, 0x39, 0x00, 0x3A, 0x00, 0x3B, 0x00, 0x3C, 0x00, 0x3D, 0x00, 0x3E, 0x00, 0x3F, 0x00,
|
||||
0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00,
|
||||
0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00,
|
||||
0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00,
|
||||
0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x5B, 0x00, 0x5C, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x5F, 0x00,
|
||||
0x60, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00,
|
||||
0x48, 0x00, 0x49, 0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, 0x00, 0x4E, 0x00, 0x4F, 0x00,
|
||||
0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00,
|
||||
0x58, 0x00, 0x59, 0x00, 0x5A, 0x00, 0x7B, 0x00, 0x7C, 0x00, 0x7D, 0x00, 0x7E, 0x00, 0x7F, 0x00,
|
||||
0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00,
|
||||
0x88, 0x00, 0x89, 0x00, 0x8A, 0x00, 0x8B, 0x00, 0x8C, 0x00, 0x8D, 0x00, 0x8E, 0x00, 0x8F, 0x00,
|
||||
0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00,
|
||||
0x98, 0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x00, 0x9C, 0x00, 0x9D, 0x00, 0x9E, 0x00, 0x9F, 0x00,
|
||||
0xA0, 0x00, 0xA1, 0x00, 0xA2, 0x00, 0xA3, 0x00, 0xA4, 0x00, 0xA5, 0x00, 0xA6, 0x00, 0xA7, 0x00,
|
||||
0xA8, 0x00, 0xA9, 0x00, 0xAA, 0x00, 0xAB, 0x00, 0xAC, 0x00, 0xAD, 0x00, 0xAE, 0x00, 0xAF, 0x00,
|
||||
0xB0, 0x00, 0xB1, 0x00, 0xB2, 0x00, 0xB3, 0x00, 0xB4, 0x00, 0xB5, 0x00, 0xB6, 0x00, 0xB7, 0x00,
|
||||
0xB8, 0x00, 0xB9, 0x00, 0xBA, 0x00, 0xBB, 0x00, 0xBC, 0x00, 0xBD, 0x00, 0xBE, 0x00, 0xBF, 0x00,
|
||||
0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00,
|
||||
0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00,
|
||||
0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xD7, 0x00,
|
||||
0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0xDF, 0x00,
|
||||
0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, 0x00, 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, 0x00,
|
||||
0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, 0x00, 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, 0x00,
|
||||
0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, 0x00, 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xF7, 0x00,
|
||||
0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, 0x00, 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0x78, 0x01,
|
||||
0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x01, 0x04, 0x01, 0x06, 0x01, 0x06, 0x01,
|
||||
0x08, 0x01, 0x08, 0x01, 0x0A, 0x01, 0x0A, 0x01, 0x0C, 0x01, 0x0C, 0x01, 0x0E, 0x01, 0x0E, 0x01,
|
||||
0x10, 0x01, 0x10, 0x01, 0x12, 0x01, 0x12, 0x01, 0x14, 0x01, 0x14, 0x01, 0x16, 0x01, 0x16, 0x01,
|
||||
0x18, 0x01, 0x18, 0x01, 0x1A, 0x01, 0x1A, 0x01, 0x1C, 0x01, 0x1C, 0x01, 0x1E, 0x01, 0x1E, 0x01,
|
||||
0x20, 0x01, 0x20, 0x01, 0x22, 0x01, 0x22, 0x01, 0x24, 0x01, 0x24, 0x01, 0x26, 0x01, 0x26, 0x01,
|
||||
0x28, 0x01, 0x28, 0x01, 0x2A, 0x01, 0x2A, 0x01, 0x2C, 0x01, 0x2C, 0x01, 0x2E, 0x01, 0x2E, 0x01,
|
||||
0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x32, 0x01, 0x34, 0x01, 0x34, 0x01, 0x36, 0x01, 0x36, 0x01,
|
||||
0x38, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3B, 0x01, 0x3B, 0x01, 0x3D, 0x01, 0x3D, 0x01, 0x3F, 0x01,
|
||||
0x3F, 0x01, 0x41, 0x01, 0x41, 0x01, 0x43, 0x01, 0x43, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, 0x01,
|
||||
0x47, 0x01, 0x49, 0x01, 0x4A, 0x01, 0x4A, 0x01, 0x4C, 0x01, 0x4C, 0x01, 0x4E, 0x01, 0x4E, 0x01,
|
||||
0x50, 0x01, 0x50, 0x01, 0x52, 0x01, 0x52, 0x01, 0x54, 0x01, 0x54, 0x01, 0x56, 0x01, 0x56, 0x01,
|
||||
0x58, 0x01, 0x58, 0x01, 0x5A, 0x01, 0x5A, 0x01, 0x5C, 0x01, 0x5C, 0x01, 0x5E, 0x01, 0x5E, 0x01,
|
||||
0x60, 0x01, 0x60, 0x01, 0x62, 0x01, 0x62, 0x01, 0x64, 0x01, 0x64, 0x01, 0x66, 0x01, 0x66, 0x01,
|
||||
0x68, 0x01, 0x68, 0x01, 0x6A, 0x01, 0x6A, 0x01, 0x6C, 0x01, 0x6C, 0x01, 0x6E, 0x01, 0x6E, 0x01,
|
||||
0x70, 0x01, 0x70, 0x01, 0x72, 0x01, 0x72, 0x01, 0x74, 0x01, 0x74, 0x01, 0x76, 0x01, 0x76, 0x01,
|
||||
0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7B, 0x01, 0x7B, 0x01, 0x7D, 0x01, 0x7D, 0x01, 0x7F, 0x01,
|
||||
0x43, 0x02, 0x81, 0x01, 0x82, 0x01, 0x82, 0x01, 0x84, 0x01, 0x84, 0x01, 0x86, 0x01, 0x87, 0x01,
|
||||
0x87, 0x01, 0x89, 0x01, 0x8A, 0x01, 0x8B, 0x01, 0x8B, 0x01, 0x8D, 0x01, 0x8E, 0x01, 0x8F, 0x01,
|
||||
0x90, 0x01, 0x91, 0x01, 0x91, 0x01, 0x93, 0x01, 0x94, 0x01, 0xF6, 0x01, 0x96, 0x01, 0x97, 0x01,
|
||||
0x98, 0x01, 0x98, 0x01, 0x3D, 0x02, 0x9B, 0x01, 0x9C, 0x01, 0x9D, 0x01, 0x20, 0x02, 0x9F, 0x01,
|
||||
0xA0, 0x01, 0xA0, 0x01, 0xA2, 0x01, 0xA2, 0x01, 0xA4, 0x01, 0xA4, 0x01, 0xA6, 0x01, 0xA7, 0x01,
|
||||
0xA7, 0x01, 0xA9, 0x01, 0xAA, 0x01, 0xAB, 0x01, 0xAC, 0x01, 0xAC, 0x01, 0xAE, 0x01, 0xAF, 0x01,
|
||||
0xAF, 0x01, 0xB1, 0x01, 0xB2, 0x01, 0xB3, 0x01, 0xB3, 0x01, 0xB5, 0x01, 0xB5, 0x01, 0xB7, 0x01,
|
||||
0xB8, 0x01, 0xB8, 0x01, 0xBA, 0x01, 0xBB, 0x01, 0xBC, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xF7, 0x01,
|
||||
0xC0, 0x01, 0xC1, 0x01, 0xC2, 0x01, 0xC3, 0x01, 0xC4, 0x01, 0xC5, 0x01, 0xC4, 0x01, 0xC7, 0x01,
|
||||
0xC8, 0x01, 0xC7, 0x01, 0xCA, 0x01, 0xCB, 0x01, 0xCA, 0x01, 0xCD, 0x01, 0xCD, 0x01, 0xCF, 0x01,
|
||||
0xCF, 0x01, 0xD1, 0x01, 0xD1, 0x01, 0xD3, 0x01, 0xD3, 0x01, 0xD5, 0x01, 0xD5, 0x01, 0xD7, 0x01,
|
||||
0xD7, 0x01, 0xD9, 0x01, 0xD9, 0x01, 0xDB, 0x01, 0xDB, 0x01, 0x8E, 0x01, 0xDE, 0x01, 0xDE, 0x01,
|
||||
0xE0, 0x01, 0xE0, 0x01, 0xE2, 0x01, 0xE2, 0x01, 0xE4, 0x01, 0xE4, 0x01, 0xE6, 0x01, 0xE6, 0x01,
|
||||
0xE8, 0x01, 0xE8, 0x01, 0xEA, 0x01, 0xEA, 0x01, 0xEC, 0x01, 0xEC, 0x01, 0xEE, 0x01, 0xEE, 0x01,
|
||||
0xF0, 0x01, 0xF1, 0x01, 0xF2, 0x01, 0xF1, 0x01, 0xF4, 0x01, 0xF4, 0x01, 0xF6, 0x01, 0xF7, 0x01,
|
||||
0xF8, 0x01, 0xF8, 0x01, 0xFA, 0x01, 0xFA, 0x01, 0xFC, 0x01, 0xFC, 0x01, 0xFE, 0x01, 0xFE, 0x01,
|
||||
0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x04, 0x02, 0x04, 0x02, 0x06, 0x02, 0x06, 0x02,
|
||||
0x08, 0x02, 0x08, 0x02, 0x0A, 0x02, 0x0A, 0x02, 0x0C, 0x02, 0x0C, 0x02, 0x0E, 0x02, 0x0E, 0x02,
|
||||
0x10, 0x02, 0x10, 0x02, 0x12, 0x02, 0x12, 0x02, 0x14, 0x02, 0x14, 0x02, 0x16, 0x02, 0x16, 0x02,
|
||||
0x18, 0x02, 0x18, 0x02, 0x1A, 0x02, 0x1A, 0x02, 0x1C, 0x02, 0x1C, 0x02, 0x1E, 0x02, 0x1E, 0x02,
|
||||
0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x22, 0x02, 0x24, 0x02, 0x24, 0x02, 0x26, 0x02, 0x26, 0x02,
|
||||
0x28, 0x02, 0x28, 0x02, 0x2A, 0x02, 0x2A, 0x02, 0x2C, 0x02, 0x2C, 0x02, 0x2E, 0x02, 0x2E, 0x02,
|
||||
0x30, 0x02, 0x30, 0x02, 0x32, 0x02, 0x32, 0x02, 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02,
|
||||
0x38, 0x02, 0x39, 0x02, 0x65, 0x2C, 0x3B, 0x02, 0x3B, 0x02, 0x3D, 0x02, 0x66, 0x2C, 0x3F, 0x02,
|
||||
0x40, 0x02, 0x41, 0x02, 0x41, 0x02, 0x43, 0x02, 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x46, 0x02,
|
||||
0x48, 0x02, 0x48, 0x02, 0x4A, 0x02, 0x4A, 0x02, 0x4C, 0x02, 0x4C, 0x02, 0x4E, 0x02, 0x4E, 0x02,
|
||||
0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x81, 0x01, 0x86, 0x01, 0x55, 0x02, 0x89, 0x01, 0x8A, 0x01,
|
||||
0x58, 0x02, 0x8F, 0x01, 0x5A, 0x02, 0x90, 0x01, 0x5C, 0x02, 0x5D, 0x02, 0x5E, 0x02, 0x5F, 0x02,
|
||||
0x93, 0x01, 0x61, 0x02, 0x62, 0x02, 0x94, 0x01, 0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 0x67, 0x02,
|
||||
0x97, 0x01, 0x96, 0x01, 0x6A, 0x02, 0x62, 0x2C, 0x6C, 0x02, 0x6D, 0x02, 0x6E, 0x02, 0x9C, 0x01,
|
||||
0x70, 0x02, 0x71, 0x02, 0x9D, 0x01, 0x73, 0x02, 0x74, 0x02, 0x9F, 0x01, 0x76, 0x02, 0x77, 0x02,
|
||||
0x78, 0x02, 0x79, 0x02, 0x7A, 0x02, 0x7B, 0x02, 0x7C, 0x02, 0x64, 0x2C, 0x7E, 0x02, 0x7F, 0x02,
|
||||
0xA6, 0x01, 0x81, 0x02, 0x82, 0x02, 0xA9, 0x01, 0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02,
|
||||
0xAE, 0x01, 0x44, 0x02, 0xB1, 0x01, 0xB2, 0x01, 0x45, 0x02, 0x8D, 0x02, 0x8E, 0x02, 0x8F, 0x02,
|
||||
0x90, 0x02, 0x91, 0x02, 0xB7, 0x01, 0x93, 0x02, 0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02,
|
||||
0x98, 0x02, 0x99, 0x02, 0x9A, 0x02, 0x9B, 0x02, 0x9C, 0x02, 0x9D, 0x02, 0x9E, 0x02, 0x9F, 0x02,
|
||||
0xA0, 0x02, 0xA1, 0x02, 0xA2, 0x02, 0xA3, 0x02, 0xA4, 0x02, 0xA5, 0x02, 0xA6, 0x02, 0xA7, 0x02,
|
||||
0xA8, 0x02, 0xA9, 0x02, 0xAA, 0x02, 0xAB, 0x02, 0xAC, 0x02, 0xAD, 0x02, 0xAE, 0x02, 0xAF, 0x02,
|
||||
0xB0, 0x02, 0xB1, 0x02, 0xB2, 0x02, 0xB3, 0x02, 0xB4, 0x02, 0xB5, 0x02, 0xB6, 0x02, 0xB7, 0x02,
|
||||
0xB8, 0x02, 0xB9, 0x02, 0xBA, 0x02, 0xBB, 0x02, 0xBC, 0x02, 0xBD, 0x02, 0xBE, 0x02, 0xBF, 0x02,
|
||||
0xC0, 0x02, 0xC1, 0x02, 0xC2, 0x02, 0xC3, 0x02, 0xC4, 0x02, 0xC5, 0x02, 0xC6, 0x02, 0xC7, 0x02,
|
||||
0xC8, 0x02, 0xC9, 0x02, 0xCA, 0x02, 0xCB, 0x02, 0xCC, 0x02, 0xCD, 0x02, 0xCE, 0x02, 0xCF, 0x02,
|
||||
0xD0, 0x02, 0xD1, 0x02, 0xD2, 0x02, 0xD3, 0x02, 0xD4, 0x02, 0xD5, 0x02, 0xD6, 0x02, 0xD7, 0x02,
|
||||
0xD8, 0x02, 0xD9, 0x02, 0xDA, 0x02, 0xDB, 0x02, 0xDC, 0x02, 0xDD, 0x02, 0xDE, 0x02, 0xDF, 0x02,
|
||||
0xE0, 0x02, 0xE1, 0x02, 0xE2, 0x02, 0xE3, 0x02, 0xE4, 0x02, 0xE5, 0x02, 0xE6, 0x02, 0xE7, 0x02,
|
||||
0xE8, 0x02, 0xE9, 0x02, 0xEA, 0x02, 0xEB, 0x02, 0xEC, 0x02, 0xED, 0x02, 0xEE, 0x02, 0xEF, 0x02,
|
||||
0xF0, 0x02, 0xF1, 0x02, 0xF2, 0x02, 0xF3, 0x02, 0xF4, 0x02, 0xF5, 0x02, 0xF6, 0x02, 0xF7, 0x02,
|
||||
0xF8, 0x02, 0xF9, 0x02, 0xFA, 0x02, 0xFB, 0x02, 0xFC, 0x02, 0xFD, 0x02, 0xFE, 0x02, 0xFF, 0x02,
|
||||
0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, 0x03,
|
||||
0x08, 0x03, 0x09, 0x03, 0x0A, 0x03, 0x0B, 0x03, 0x0C, 0x03, 0x0D, 0x03, 0x0E, 0x03, 0x0F, 0x03,
|
||||
0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03, 0x14, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03,
|
||||
0x18, 0x03, 0x19, 0x03, 0x1A, 0x03, 0x1B, 0x03, 0x1C, 0x03, 0x1D, 0x03, 0x1E, 0x03, 0x1F, 0x03,
|
||||
0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, 0x03, 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03,
|
||||
0x28, 0x03, 0x29, 0x03, 0x2A, 0x03, 0x2B, 0x03, 0x2C, 0x03, 0x2D, 0x03, 0x2E, 0x03, 0x2F, 0x03,
|
||||
0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03, 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03,
|
||||
0x38, 0x03, 0x39, 0x03, 0x3A, 0x03, 0x3B, 0x03, 0x3C, 0x03, 0x3D, 0x03, 0x3E, 0x03, 0x3F, 0x03,
|
||||
0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, 0x44, 0x03, 0x45, 0x03, 0x46, 0x03, 0x47, 0x03,
|
||||
0x48, 0x03, 0x49, 0x03, 0x4A, 0x03, 0x4B, 0x03, 0x4C, 0x03, 0x4D, 0x03, 0x4E, 0x03, 0x4F, 0x03,
|
||||
0x50, 0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, 0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03,
|
||||
0x58, 0x03, 0x59, 0x03, 0x5A, 0x03, 0x5B, 0x03, 0x5C, 0x03, 0x5D, 0x03, 0x5E, 0x03, 0x5F, 0x03,
|
||||
0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, 0x64, 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03,
|
||||
0x68, 0x03, 0x69, 0x03, 0x6A, 0x03, 0x6B, 0x03, 0x6C, 0x03, 0x6D, 0x03, 0x6E, 0x03, 0x6F, 0x03,
|
||||
0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, 0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03,
|
||||
0x78, 0x03, 0x79, 0x03, 0x7A, 0x03, 0xFD, 0x03, 0xFE, 0x03, 0xFF, 0x03, 0x7E, 0x03, 0x7F, 0x03,
|
||||
0x80, 0x03, 0x81, 0x03, 0x82, 0x03, 0x83, 0x03, 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03,
|
||||
0x88, 0x03, 0x89, 0x03, 0x8A, 0x03, 0x8B, 0x03, 0x8C, 0x03, 0x8D, 0x03, 0x8E, 0x03, 0x8F, 0x03,
|
||||
0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03,
|
||||
0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03,
|
||||
0xA0, 0x03, 0xA1, 0x03, 0xA2, 0x03, 0xA3, 0x03, 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03,
|
||||
0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, 0x86, 0x03, 0x88, 0x03, 0x89, 0x03, 0x8A, 0x03,
|
||||
0xB0, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03,
|
||||
0x98, 0x03, 0x99, 0x03, 0x9A, 0x03, 0x9B, 0x03, 0x9C, 0x03, 0x9D, 0x03, 0x9E, 0x03, 0x9F, 0x03,
|
||||
0xA0, 0x03, 0xA1, 0x03, 0xA3, 0x03, 0xA3, 0x03, 0xA4, 0x03, 0xA5, 0x03, 0xA6, 0x03, 0xA7, 0x03,
|
||||
0xA8, 0x03, 0xA9, 0x03, 0xAA, 0x03, 0xAB, 0x03, 0x8C, 0x03, 0x8E, 0x03, 0x8F, 0x03, 0xCF, 0x03,
|
||||
0xD0, 0x03, 0xD1, 0x03, 0xD2, 0x03, 0xD3, 0x03, 0xD4, 0x03, 0xD5, 0x03, 0xD6, 0x03, 0xD7, 0x03,
|
||||
0xD8, 0x03, 0xD8, 0x03, 0xDA, 0x03, 0xDA, 0x03, 0xDC, 0x03, 0xDC, 0x03, 0xDE, 0x03, 0xDE, 0x03,
|
||||
0xE0, 0x03, 0xE0, 0x03, 0xE2, 0x03, 0xE2, 0x03, 0xE4, 0x03, 0xE4, 0x03, 0xE6, 0x03, 0xE6, 0x03,
|
||||
0xE8, 0x03, 0xE8, 0x03, 0xEA, 0x03, 0xEA, 0x03, 0xEC, 0x03, 0xEC, 0x03, 0xEE, 0x03, 0xEE, 0x03,
|
||||
0xF0, 0x03, 0xF1, 0x03, 0xF9, 0x03, 0xF3, 0x03, 0xF4, 0x03, 0xF5, 0x03, 0xF6, 0x03, 0xF7, 0x03,
|
||||
0xF7, 0x03, 0xF9, 0x03, 0xFA, 0x03, 0xFA, 0x03, 0xFC, 0x03, 0xFD, 0x03, 0xFE, 0x03, 0xFF, 0x03,
|
||||
0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04,
|
||||
0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04,
|
||||
0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04,
|
||||
0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04,
|
||||
0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04,
|
||||
0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04,
|
||||
0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04,
|
||||
0x18, 0x04, 0x19, 0x04, 0x1A, 0x04, 0x1B, 0x04, 0x1C, 0x04, 0x1D, 0x04, 0x1E, 0x04, 0x1F, 0x04,
|
||||
0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04,
|
||||
0x28, 0x04, 0x29, 0x04, 0x2A, 0x04, 0x2B, 0x04, 0x2C, 0x04, 0x2D, 0x04, 0x2E, 0x04, 0x2F, 0x04,
|
||||
0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04,
|
||||
0x08, 0x04, 0x09, 0x04, 0x0A, 0x04, 0x0B, 0x04, 0x0C, 0x04, 0x0D, 0x04, 0x0E, 0x04, 0x0F, 0x04,
|
||||
0x60, 0x04, 0x60, 0x04, 0x62, 0x04, 0x62, 0x04, 0x64, 0x04, 0x64, 0x04, 0x66, 0x04, 0x66, 0x04,
|
||||
0x68, 0x04, 0x68, 0x04, 0x6A, 0x04, 0x6A, 0x04, 0x6C, 0x04, 0x6C, 0x04, 0x6E, 0x04, 0x6E, 0x04,
|
||||
0x70, 0x04, 0x70, 0x04, 0x72, 0x04, 0x72, 0x04, 0x74, 0x04, 0x74, 0x04, 0x76, 0x04, 0x76, 0x04,
|
||||
0x78, 0x04, 0x78, 0x04, 0x7A, 0x04, 0x7A, 0x04, 0x7C, 0x04, 0x7C, 0x04, 0x7E, 0x04, 0x7E, 0x04,
|
||||
0x80, 0x04, 0x80, 0x04, 0x82, 0x04, 0x83, 0x04, 0x84, 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04,
|
||||
0x88, 0x04, 0x89, 0x04, 0x8A, 0x04, 0x8A, 0x04, 0x8C, 0x04, 0x8C, 0x04, 0x8E, 0x04, 0x8E, 0x04,
|
||||
0x90, 0x04, 0x90, 0x04, 0x92, 0x04, 0x92, 0x04, 0x94, 0x04, 0x94, 0x04, 0x96, 0x04, 0x96, 0x04,
|
||||
0x98, 0x04, 0x98, 0x04, 0x9A, 0x04, 0x9A, 0x04, 0x9C, 0x04, 0x9C, 0x04, 0x9E, 0x04, 0x9E, 0x04,
|
||||
0xA0, 0x04, 0xA0, 0x04, 0xA2, 0x04, 0xA2, 0x04, 0xA4, 0x04, 0xA4, 0x04, 0xA6, 0x04, 0xA6, 0x04,
|
||||
0xA8, 0x04, 0xA8, 0x04, 0xAA, 0x04, 0xAA, 0x04, 0xAC, 0x04, 0xAC, 0x04, 0xAE, 0x04, 0xAE, 0x04,
|
||||
0xB0, 0x04, 0xB0, 0x04, 0xB2, 0x04, 0xB2, 0x04, 0xB4, 0x04, 0xB4, 0x04, 0xB6, 0x04, 0xB6, 0x04,
|
||||
0xB8, 0x04, 0xB8, 0x04, 0xBA, 0x04, 0xBA, 0x04, 0xBC, 0x04, 0xBC, 0x04, 0xBE, 0x04, 0xBE, 0x04,
|
||||
0xC0, 0x04, 0xC1, 0x04, 0xC1, 0x04, 0xC3, 0x04, 0xC3, 0x04, 0xC5, 0x04, 0xC5, 0x04, 0xC7, 0x04,
|
||||
0xC7, 0x04, 0xC9, 0x04, 0xC9, 0x04, 0xCB, 0x04, 0xCB, 0x04, 0xCD, 0x04, 0xCD, 0x04, 0xC0, 0x04,
|
||||
0xD0, 0x04, 0xD0, 0x04, 0xD2, 0x04, 0xD2, 0x04, 0xD4, 0x04, 0xD4, 0x04, 0xD6, 0x04, 0xD6, 0x04,
|
||||
0xD8, 0x04, 0xD8, 0x04, 0xDA, 0x04, 0xDA, 0x04, 0xDC, 0x04, 0xDC, 0x04, 0xDE, 0x04, 0xDE, 0x04,
|
||||
0xE0, 0x04, 0xE0, 0x04, 0xE2, 0x04, 0xE2, 0x04, 0xE4, 0x04, 0xE4, 0x04, 0xE6, 0x04, 0xE6, 0x04,
|
||||
0xE8, 0x04, 0xE8, 0x04, 0xEA, 0x04, 0xEA, 0x04, 0xEC, 0x04, 0xEC, 0x04, 0xEE, 0x04, 0xEE, 0x04,
|
||||
0xF0, 0x04, 0xF0, 0x04, 0xF2, 0x04, 0xF2, 0x04, 0xF4, 0x04, 0xF4, 0x04, 0xF6, 0x04, 0xF6, 0x04,
|
||||
0xF8, 0x04, 0xF8, 0x04, 0xFA, 0x04, 0xFA, 0x04, 0xFC, 0x04, 0xFC, 0x04, 0xFE, 0x04, 0xFE, 0x04,
|
||||
0x00, 0x05, 0x00, 0x05, 0x02, 0x05, 0x02, 0x05, 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, 0x05,
|
||||
0x08, 0x05, 0x08, 0x05, 0x0A, 0x05, 0x0A, 0x05, 0x0C, 0x05, 0x0C, 0x05, 0x0E, 0x05, 0x0E, 0x05,
|
||||
0x10, 0x05, 0x10, 0x05, 0x12, 0x05, 0x12, 0x05, 0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05,
|
||||
0x18, 0x05, 0x19, 0x05, 0x1A, 0x05, 0x1B, 0x05, 0x1C, 0x05, 0x1D, 0x05, 0x1E, 0x05, 0x1F, 0x05,
|
||||
0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, 0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05,
|
||||
0x28, 0x05, 0x29, 0x05, 0x2A, 0x05, 0x2B, 0x05, 0x2C, 0x05, 0x2D, 0x05, 0x2E, 0x05, 0x2F, 0x05,
|
||||
0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05,
|
||||
0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05,
|
||||
0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05,
|
||||
0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05,
|
||||
0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05,
|
||||
0x58, 0x05, 0x59, 0x05, 0x5A, 0x05, 0x5B, 0x05, 0x5C, 0x05, 0x5D, 0x05, 0x5E, 0x05, 0x5F, 0x05,
|
||||
0x60, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05,
|
||||
0x38, 0x05, 0x39, 0x05, 0x3A, 0x05, 0x3B, 0x05, 0x3C, 0x05, 0x3D, 0x05, 0x3E, 0x05, 0x3F, 0x05,
|
||||
0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05,
|
||||
0x48, 0x05, 0x49, 0x05, 0x4A, 0x05, 0x4B, 0x05, 0x4C, 0x05, 0x4D, 0x05, 0x4E, 0x05, 0x4F, 0x05,
|
||||
0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0xFF, 0xFF,
|
||||
0xF6, 0x17, 0x63, 0x2C, 0x7E, 0x1D, 0x7F, 0x1D, 0x80, 0x1D, 0x81, 0x1D, 0x82, 0x1D, 0x83, 0x1D,
|
||||
0x84, 0x1D, 0x85, 0x1D, 0x86, 0x1D, 0x87, 0x1D, 0x88, 0x1D, 0x89, 0x1D, 0x8A, 0x1D, 0x8B, 0x1D,
|
||||
0x8C, 0x1D, 0x8D, 0x1D, 0x8E, 0x1D, 0x8F, 0x1D, 0x90, 0x1D, 0x91, 0x1D, 0x92, 0x1D, 0x93, 0x1D,
|
||||
0x94, 0x1D, 0x95, 0x1D, 0x96, 0x1D, 0x97, 0x1D, 0x98, 0x1D, 0x99, 0x1D, 0x9A, 0x1D, 0x9B, 0x1D,
|
||||
0x9C, 0x1D, 0x9D, 0x1D, 0x9E, 0x1D, 0x9F, 0x1D, 0xA0, 0x1D, 0xA1, 0x1D, 0xA2, 0x1D, 0xA3, 0x1D,
|
||||
0xA4, 0x1D, 0xA5, 0x1D, 0xA6, 0x1D, 0xA7, 0x1D, 0xA8, 0x1D, 0xA9, 0x1D, 0xAA, 0x1D, 0xAB, 0x1D,
|
||||
0xAC, 0x1D, 0xAD, 0x1D, 0xAE, 0x1D, 0xAF, 0x1D, 0xB0, 0x1D, 0xB1, 0x1D, 0xB2, 0x1D, 0xB3, 0x1D,
|
||||
0xB4, 0x1D, 0xB5, 0x1D, 0xB6, 0x1D, 0xB7, 0x1D, 0xB8, 0x1D, 0xB9, 0x1D, 0xBA, 0x1D, 0xBB, 0x1D,
|
||||
0xBC, 0x1D, 0xBD, 0x1D, 0xBE, 0x1D, 0xBF, 0x1D, 0xC0, 0x1D, 0xC1, 0x1D, 0xC2, 0x1D, 0xC3, 0x1D,
|
||||
0xC4, 0x1D, 0xC5, 0x1D, 0xC6, 0x1D, 0xC7, 0x1D, 0xC8, 0x1D, 0xC9, 0x1D, 0xCA, 0x1D, 0xCB, 0x1D,
|
||||
0xCC, 0x1D, 0xCD, 0x1D, 0xCE, 0x1D, 0xCF, 0x1D, 0xD0, 0x1D, 0xD1, 0x1D, 0xD2, 0x1D, 0xD3, 0x1D,
|
||||
0xD4, 0x1D, 0xD5, 0x1D, 0xD6, 0x1D, 0xD7, 0x1D, 0xD8, 0x1D, 0xD9, 0x1D, 0xDA, 0x1D, 0xDB, 0x1D,
|
||||
0xDC, 0x1D, 0xDD, 0x1D, 0xDE, 0x1D, 0xDF, 0x1D, 0xE0, 0x1D, 0xE1, 0x1D, 0xE2, 0x1D, 0xE3, 0x1D,
|
||||
0xE4, 0x1D, 0xE5, 0x1D, 0xE6, 0x1D, 0xE7, 0x1D, 0xE8, 0x1D, 0xE9, 0x1D, 0xEA, 0x1D, 0xEB, 0x1D,
|
||||
0xEC, 0x1D, 0xED, 0x1D, 0xEE, 0x1D, 0xEF, 0x1D, 0xF0, 0x1D, 0xF1, 0x1D, 0xF2, 0x1D, 0xF3, 0x1D,
|
||||
0xF4, 0x1D, 0xF5, 0x1D, 0xF6, 0x1D, 0xF7, 0x1D, 0xF8, 0x1D, 0xF9, 0x1D, 0xFA, 0x1D, 0xFB, 0x1D,
|
||||
0xFC, 0x1D, 0xFD, 0x1D, 0xFE, 0x1D, 0xFF, 0x1D, 0x00, 0x1E, 0x00, 0x1E, 0x02, 0x1E, 0x02, 0x1E,
|
||||
0x04, 0x1E, 0x04, 0x1E, 0x06, 0x1E, 0x06, 0x1E, 0x08, 0x1E, 0x08, 0x1E, 0x0A, 0x1E, 0x0A, 0x1E,
|
||||
0x0C, 0x1E, 0x0C, 0x1E, 0x0E, 0x1E, 0x0E, 0x1E, 0x10, 0x1E, 0x10, 0x1E, 0x12, 0x1E, 0x12, 0x1E,
|
||||
0x14, 0x1E, 0x14, 0x1E, 0x16, 0x1E, 0x16, 0x1E, 0x18, 0x1E, 0x18, 0x1E, 0x1A, 0x1E, 0x1A, 0x1E,
|
||||
0x1C, 0x1E, 0x1C, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x20, 0x1E, 0x20, 0x1E, 0x22, 0x1E, 0x22, 0x1E,
|
||||
0x24, 0x1E, 0x24, 0x1E, 0x26, 0x1E, 0x26, 0x1E, 0x28, 0x1E, 0x28, 0x1E, 0x2A, 0x1E, 0x2A, 0x1E,
|
||||
0x2C, 0x1E, 0x2C, 0x1E, 0x2E, 0x1E, 0x2E, 0x1E, 0x30, 0x1E, 0x30, 0x1E, 0x32, 0x1E, 0x32, 0x1E,
|
||||
0x34, 0x1E, 0x34, 0x1E, 0x36, 0x1E, 0x36, 0x1E, 0x38, 0x1E, 0x38, 0x1E, 0x3A, 0x1E, 0x3A, 0x1E,
|
||||
0x3C, 0x1E, 0x3C, 0x1E, 0x3E, 0x1E, 0x3E, 0x1E, 0x40, 0x1E, 0x40, 0x1E, 0x42, 0x1E, 0x42, 0x1E,
|
||||
0x44, 0x1E, 0x44, 0x1E, 0x46, 0x1E, 0x46, 0x1E, 0x48, 0x1E, 0x48, 0x1E, 0x4A, 0x1E, 0x4A, 0x1E,
|
||||
0x4C, 0x1E, 0x4C, 0x1E, 0x4E, 0x1E, 0x4E, 0x1E, 0x50, 0x1E, 0x50, 0x1E, 0x52, 0x1E, 0x52, 0x1E,
|
||||
0x54, 0x1E, 0x54, 0x1E, 0x56, 0x1E, 0x56, 0x1E, 0x58, 0x1E, 0x58, 0x1E, 0x5A, 0x1E, 0x5A, 0x1E,
|
||||
0x5C, 0x1E, 0x5C, 0x1E, 0x5E, 0x1E, 0x5E, 0x1E, 0x60, 0x1E, 0x60, 0x1E, 0x62, 0x1E, 0x62, 0x1E,
|
||||
0x64, 0x1E, 0x64, 0x1E, 0x66, 0x1E, 0x66, 0x1E, 0x68, 0x1E, 0x68, 0x1E, 0x6A, 0x1E, 0x6A, 0x1E,
|
||||
0x6C, 0x1E, 0x6C, 0x1E, 0x6E, 0x1E, 0x6E, 0x1E, 0x70, 0x1E, 0x70, 0x1E, 0x72, 0x1E, 0x72, 0x1E,
|
||||
0x74, 0x1E, 0x74, 0x1E, 0x76, 0x1E, 0x76, 0x1E, 0x78, 0x1E, 0x78, 0x1E, 0x7A, 0x1E, 0x7A, 0x1E,
|
||||
0x7C, 0x1E, 0x7C, 0x1E, 0x7E, 0x1E, 0x7E, 0x1E, 0x80, 0x1E, 0x80, 0x1E, 0x82, 0x1E, 0x82, 0x1E,
|
||||
0x84, 0x1E, 0x84, 0x1E, 0x86, 0x1E, 0x86, 0x1E, 0x88, 0x1E, 0x88, 0x1E, 0x8A, 0x1E, 0x8A, 0x1E,
|
||||
0x8C, 0x1E, 0x8C, 0x1E, 0x8E, 0x1E, 0x8E, 0x1E, 0x90, 0x1E, 0x90, 0x1E, 0x92, 0x1E, 0x92, 0x1E,
|
||||
0x94, 0x1E, 0x94, 0x1E, 0x96, 0x1E, 0x97, 0x1E, 0x98, 0x1E, 0x99, 0x1E, 0x9A, 0x1E, 0x9B, 0x1E,
|
||||
0x9C, 0x1E, 0x9D, 0x1E, 0x9E, 0x1E, 0x9F, 0x1E, 0xA0, 0x1E, 0xA0, 0x1E, 0xA2, 0x1E, 0xA2, 0x1E,
|
||||
0xA4, 0x1E, 0xA4, 0x1E, 0xA6, 0x1E, 0xA6, 0x1E, 0xA8, 0x1E, 0xA8, 0x1E, 0xAA, 0x1E, 0xAA, 0x1E,
|
||||
0xAC, 0x1E, 0xAC, 0x1E, 0xAE, 0x1E, 0xAE, 0x1E, 0xB0, 0x1E, 0xB0, 0x1E, 0xB2, 0x1E, 0xB2, 0x1E,
|
||||
0xB4, 0x1E, 0xB4, 0x1E, 0xB6, 0x1E, 0xB6, 0x1E, 0xB8, 0x1E, 0xB8, 0x1E, 0xBA, 0x1E, 0xBA, 0x1E,
|
||||
0xBC, 0x1E, 0xBC, 0x1E, 0xBE, 0x1E, 0xBE, 0x1E, 0xC0, 0x1E, 0xC0, 0x1E, 0xC2, 0x1E, 0xC2, 0x1E,
|
||||
0xC4, 0x1E, 0xC4, 0x1E, 0xC6, 0x1E, 0xC6, 0x1E, 0xC8, 0x1E, 0xC8, 0x1E, 0xCA, 0x1E, 0xCA, 0x1E,
|
||||
0xCC, 0x1E, 0xCC, 0x1E, 0xCE, 0x1E, 0xCE, 0x1E, 0xD0, 0x1E, 0xD0, 0x1E, 0xD2, 0x1E, 0xD2, 0x1E,
|
||||
0xD4, 0x1E, 0xD4, 0x1E, 0xD6, 0x1E, 0xD6, 0x1E, 0xD8, 0x1E, 0xD8, 0x1E, 0xDA, 0x1E, 0xDA, 0x1E,
|
||||
0xDC, 0x1E, 0xDC, 0x1E, 0xDE, 0x1E, 0xDE, 0x1E, 0xE0, 0x1E, 0xE0, 0x1E, 0xE2, 0x1E, 0xE2, 0x1E,
|
||||
0xE4, 0x1E, 0xE4, 0x1E, 0xE6, 0x1E, 0xE6, 0x1E, 0xE8, 0x1E, 0xE8, 0x1E, 0xEA, 0x1E, 0xEA, 0x1E,
|
||||
0xEC, 0x1E, 0xEC, 0x1E, 0xEE, 0x1E, 0xEE, 0x1E, 0xF0, 0x1E, 0xF0, 0x1E, 0xF2, 0x1E, 0xF2, 0x1E,
|
||||
0xF4, 0x1E, 0xF4, 0x1E, 0xF6, 0x1E, 0xF6, 0x1E, 0xF8, 0x1E, 0xF8, 0x1E, 0xFA, 0x1E, 0xFB, 0x1E,
|
||||
0xFC, 0x1E, 0xFD, 0x1E, 0xFE, 0x1E, 0xFF, 0x1E, 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F,
|
||||
0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, 0x08, 0x1F, 0x09, 0x1F, 0x0A, 0x1F, 0x0B, 0x1F,
|
||||
0x0C, 0x1F, 0x0D, 0x1F, 0x0E, 0x1F, 0x0F, 0x1F, 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F,
|
||||
0x1C, 0x1F, 0x1D, 0x1F, 0x16, 0x1F, 0x17, 0x1F, 0x18, 0x1F, 0x19, 0x1F, 0x1A, 0x1F, 0x1B, 0x1F,
|
||||
0x1C, 0x1F, 0x1D, 0x1F, 0x1E, 0x1F, 0x1F, 0x1F, 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F,
|
||||
0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, 0x28, 0x1F, 0x29, 0x1F, 0x2A, 0x1F, 0x2B, 0x1F,
|
||||
0x2C, 0x1F, 0x2D, 0x1F, 0x2E, 0x1F, 0x2F, 0x1F, 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F,
|
||||
0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, 0x38, 0x1F, 0x39, 0x1F, 0x3A, 0x1F, 0x3B, 0x1F,
|
||||
0x3C, 0x1F, 0x3D, 0x1F, 0x3E, 0x1F, 0x3F, 0x1F, 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F,
|
||||
0x4C, 0x1F, 0x4D, 0x1F, 0x46, 0x1F, 0x47, 0x1F, 0x48, 0x1F, 0x49, 0x1F, 0x4A, 0x1F, 0x4B, 0x1F,
|
||||
0x4C, 0x1F, 0x4D, 0x1F, 0x4E, 0x1F, 0x4F, 0x1F, 0x50, 0x1F, 0x59, 0x1F, 0x52, 0x1F, 0x5B, 0x1F,
|
||||
0x54, 0x1F, 0x5D, 0x1F, 0x56, 0x1F, 0x5F, 0x1F, 0x58, 0x1F, 0x59, 0x1F, 0x5A, 0x1F, 0x5B, 0x1F,
|
||||
0x5C, 0x1F, 0x5D, 0x1F, 0x5E, 0x1F, 0x5F, 0x1F, 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F,
|
||||
0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, 0x68, 0x1F, 0x69, 0x1F, 0x6A, 0x1F, 0x6B, 0x1F,
|
||||
0x6C, 0x1F, 0x6D, 0x1F, 0x6E, 0x1F, 0x6F, 0x1F, 0xBA, 0x1F, 0xBB, 0x1F, 0xC8, 0x1F, 0xC9, 0x1F,
|
||||
0xCA, 0x1F, 0xCB, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F, 0xF8, 0x1F, 0xF9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F,
|
||||
0xFA, 0x1F, 0xFB, 0x1F, 0x7E, 0x1F, 0x7F, 0x1F, 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F,
|
||||
0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, 0x88, 0x1F, 0x89, 0x1F, 0x8A, 0x1F, 0x8B, 0x1F,
|
||||
0x8C, 0x1F, 0x8D, 0x1F, 0x8E, 0x1F, 0x8F, 0x1F, 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F,
|
||||
0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, 0x98, 0x1F, 0x99, 0x1F, 0x9A, 0x1F, 0x9B, 0x1F,
|
||||
0x9C, 0x1F, 0x9D, 0x1F, 0x9E, 0x1F, 0x9F, 0x1F, 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F,
|
||||
0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, 0xA8, 0x1F, 0xA9, 0x1F, 0xAA, 0x1F, 0xAB, 0x1F,
|
||||
0xAC, 0x1F, 0xAD, 0x1F, 0xAE, 0x1F, 0xAF, 0x1F, 0xB8, 0x1F, 0xB9, 0x1F, 0xB2, 0x1F, 0xBC, 0x1F,
|
||||
0xB4, 0x1F, 0xB5, 0x1F, 0xB6, 0x1F, 0xB7, 0x1F, 0xB8, 0x1F, 0xB9, 0x1F, 0xBA, 0x1F, 0xBB, 0x1F,
|
||||
0xBC, 0x1F, 0xBD, 0x1F, 0xBE, 0x1F, 0xBF, 0x1F, 0xC0, 0x1F, 0xC1, 0x1F, 0xC2, 0x1F, 0xC3, 0x1F,
|
||||
0xC4, 0x1F, 0xC5, 0x1F, 0xC6, 0x1F, 0xC7, 0x1F, 0xC8, 0x1F, 0xC9, 0x1F, 0xCA, 0x1F, 0xCB, 0x1F,
|
||||
0xC3, 0x1F, 0xCD, 0x1F, 0xCE, 0x1F, 0xCF, 0x1F, 0xD8, 0x1F, 0xD9, 0x1F, 0xD2, 0x1F, 0xD3, 0x1F,
|
||||
0xD4, 0x1F, 0xD5, 0x1F, 0xD6, 0x1F, 0xD7, 0x1F, 0xD8, 0x1F, 0xD9, 0x1F, 0xDA, 0x1F, 0xDB, 0x1F,
|
||||
0xDC, 0x1F, 0xDD, 0x1F, 0xDE, 0x1F, 0xDF, 0x1F, 0xE8, 0x1F, 0xE9, 0x1F, 0xE2, 0x1F, 0xE3, 0x1F,
|
||||
0xE4, 0x1F, 0xEC, 0x1F, 0xE6, 0x1F, 0xE7, 0x1F, 0xE8, 0x1F, 0xE9, 0x1F, 0xEA, 0x1F, 0xEB, 0x1F,
|
||||
0xEC, 0x1F, 0xED, 0x1F, 0xEE, 0x1F, 0xEF, 0x1F, 0xF0, 0x1F, 0xF1, 0x1F, 0xF2, 0x1F, 0xF3, 0x1F,
|
||||
0xF4, 0x1F, 0xF5, 0x1F, 0xF6, 0x1F, 0xF7, 0x1F, 0xF8, 0x1F, 0xF9, 0x1F, 0xFA, 0x1F, 0xFB, 0x1F,
|
||||
0xF3, 0x1F, 0xFD, 0x1F, 0xFE, 0x1F, 0xFF, 0x1F, 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20,
|
||||
0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20, 0x08, 0x20, 0x09, 0x20, 0x0A, 0x20, 0x0B, 0x20,
|
||||
0x0C, 0x20, 0x0D, 0x20, 0x0E, 0x20, 0x0F, 0x20, 0x10, 0x20, 0x11, 0x20, 0x12, 0x20, 0x13, 0x20,
|
||||
0x14, 0x20, 0x15, 0x20, 0x16, 0x20, 0x17, 0x20, 0x18, 0x20, 0x19, 0x20, 0x1A, 0x20, 0x1B, 0x20,
|
||||
0x1C, 0x20, 0x1D, 0x20, 0x1E, 0x20, 0x1F, 0x20, 0x20, 0x20, 0x21, 0x20, 0x22, 0x20, 0x23, 0x20,
|
||||
0x24, 0x20, 0x25, 0x20, 0x26, 0x20, 0x27, 0x20, 0x28, 0x20, 0x29, 0x20, 0x2A, 0x20, 0x2B, 0x20,
|
||||
0x2C, 0x20, 0x2D, 0x20, 0x2E, 0x20, 0x2F, 0x20, 0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x33, 0x20,
|
||||
0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20, 0x38, 0x20, 0x39, 0x20, 0x3A, 0x20, 0x3B, 0x20,
|
||||
0x3C, 0x20, 0x3D, 0x20, 0x3E, 0x20, 0x3F, 0x20, 0x40, 0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20,
|
||||
0x44, 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, 0x48, 0x20, 0x49, 0x20, 0x4A, 0x20, 0x4B, 0x20,
|
||||
0x4C, 0x20, 0x4D, 0x20, 0x4E, 0x20, 0x4F, 0x20, 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20,
|
||||
0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, 0x58, 0x20, 0x59, 0x20, 0x5A, 0x20, 0x5B, 0x20,
|
||||
0x5C, 0x20, 0x5D, 0x20, 0x5E, 0x20, 0x5F, 0x20, 0x60, 0x20, 0x61, 0x20, 0x62, 0x20, 0x63, 0x20,
|
||||
0x64, 0x20, 0x65, 0x20, 0x66, 0x20, 0x67, 0x20, 0x68, 0x20, 0x69, 0x20, 0x6A, 0x20, 0x6B, 0x20,
|
||||
0x6C, 0x20, 0x6D, 0x20, 0x6E, 0x20, 0x6F, 0x20, 0x70, 0x20, 0x71, 0x20, 0x72, 0x20, 0x73, 0x20,
|
||||
0x74, 0x20, 0x75, 0x20, 0x76, 0x20, 0x77, 0x20, 0x78, 0x20, 0x79, 0x20, 0x7A, 0x20, 0x7B, 0x20,
|
||||
0x7C, 0x20, 0x7D, 0x20, 0x7E, 0x20, 0x7F, 0x20, 0x80, 0x20, 0x81, 0x20, 0x82, 0x20, 0x83, 0x20,
|
||||
0x84, 0x20, 0x85, 0x20, 0x86, 0x20, 0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x8A, 0x20, 0x8B, 0x20,
|
||||
0x8C, 0x20, 0x8D, 0x20, 0x8E, 0x20, 0x8F, 0x20, 0x90, 0x20, 0x91, 0x20, 0x92, 0x20, 0x93, 0x20,
|
||||
0x94, 0x20, 0x95, 0x20, 0x96, 0x20, 0x97, 0x20, 0x98, 0x20, 0x99, 0x20, 0x9A, 0x20, 0x9B, 0x20,
|
||||
0x9C, 0x20, 0x9D, 0x20, 0x9E, 0x20, 0x9F, 0x20, 0xA0, 0x20, 0xA1, 0x20, 0xA2, 0x20, 0xA3, 0x20,
|
||||
0xA4, 0x20, 0xA5, 0x20, 0xA6, 0x20, 0xA7, 0x20, 0xA8, 0x20, 0xA9, 0x20, 0xAA, 0x20, 0xAB, 0x20,
|
||||
0xAC, 0x20, 0xAD, 0x20, 0xAE, 0x20, 0xAF, 0x20, 0xB0, 0x20, 0xB1, 0x20, 0xB2, 0x20, 0xB3, 0x20,
|
||||
0xB4, 0x20, 0xB5, 0x20, 0xB6, 0x20, 0xB7, 0x20, 0xB8, 0x20, 0xB9, 0x20, 0xBA, 0x20, 0xBB, 0x20,
|
||||
0xBC, 0x20, 0xBD, 0x20, 0xBE, 0x20, 0xBF, 0x20, 0xC0, 0x20, 0xC1, 0x20, 0xC2, 0x20, 0xC3, 0x20,
|
||||
0xC4, 0x20, 0xC5, 0x20, 0xC6, 0x20, 0xC7, 0x20, 0xC8, 0x20, 0xC9, 0x20, 0xCA, 0x20, 0xCB, 0x20,
|
||||
0xCC, 0x20, 0xCD, 0x20, 0xCE, 0x20, 0xCF, 0x20, 0xD0, 0x20, 0xD1, 0x20, 0xD2, 0x20, 0xD3, 0x20,
|
||||
0xD4, 0x20, 0xD5, 0x20, 0xD6, 0x20, 0xD7, 0x20, 0xD8, 0x20, 0xD9, 0x20, 0xDA, 0x20, 0xDB, 0x20,
|
||||
0xDC, 0x20, 0xDD, 0x20, 0xDE, 0x20, 0xDF, 0x20, 0xE0, 0x20, 0xE1, 0x20, 0xE2, 0x20, 0xE3, 0x20,
|
||||
0xE4, 0x20, 0xE5, 0x20, 0xE6, 0x20, 0xE7, 0x20, 0xE8, 0x20, 0xE9, 0x20, 0xEA, 0x20, 0xEB, 0x20,
|
||||
0xEC, 0x20, 0xED, 0x20, 0xEE, 0x20, 0xEF, 0x20, 0xF0, 0x20, 0xF1, 0x20, 0xF2, 0x20, 0xF3, 0x20,
|
||||
0xF4, 0x20, 0xF5, 0x20, 0xF6, 0x20, 0xF7, 0x20, 0xF8, 0x20, 0xF9, 0x20, 0xFA, 0x20, 0xFB, 0x20,
|
||||
0xFC, 0x20, 0xFD, 0x20, 0xFE, 0x20, 0xFF, 0x20, 0x00, 0x21, 0x01, 0x21, 0x02, 0x21, 0x03, 0x21,
|
||||
0x04, 0x21, 0x05, 0x21, 0x06, 0x21, 0x07, 0x21, 0x08, 0x21, 0x09, 0x21, 0x0A, 0x21, 0x0B, 0x21,
|
||||
0x0C, 0x21, 0x0D, 0x21, 0x0E, 0x21, 0x0F, 0x21, 0x10, 0x21, 0x11, 0x21, 0x12, 0x21, 0x13, 0x21,
|
||||
0x14, 0x21, 0x15, 0x21, 0x16, 0x21, 0x17, 0x21, 0x18, 0x21, 0x19, 0x21, 0x1A, 0x21, 0x1B, 0x21,
|
||||
0x1C, 0x21, 0x1D, 0x21, 0x1E, 0x21, 0x1F, 0x21, 0x20, 0x21, 0x21, 0x21, 0x22, 0x21, 0x23, 0x21,
|
||||
0x24, 0x21, 0x25, 0x21, 0x26, 0x21, 0x27, 0x21, 0x28, 0x21, 0x29, 0x21, 0x2A, 0x21, 0x2B, 0x21,
|
||||
0x2C, 0x21, 0x2D, 0x21, 0x2E, 0x21, 0x2F, 0x21, 0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x33, 0x21,
|
||||
0x34, 0x21, 0x35, 0x21, 0x36, 0x21, 0x37, 0x21, 0x38, 0x21, 0x39, 0x21, 0x3A, 0x21, 0x3B, 0x21,
|
||||
0x3C, 0x21, 0x3D, 0x21, 0x3E, 0x21, 0x3F, 0x21, 0x40, 0x21, 0x41, 0x21, 0x42, 0x21, 0x43, 0x21,
|
||||
0x44, 0x21, 0x45, 0x21, 0x46, 0x21, 0x47, 0x21, 0x48, 0x21, 0x49, 0x21, 0x4A, 0x21, 0x4B, 0x21,
|
||||
0x4C, 0x21, 0x4D, 0x21, 0x32, 0x21, 0x4F, 0x21, 0x50, 0x21, 0x51, 0x21, 0x52, 0x21, 0x53, 0x21,
|
||||
0x54, 0x21, 0x55, 0x21, 0x56, 0x21, 0x57, 0x21, 0x58, 0x21, 0x59, 0x21, 0x5A, 0x21, 0x5B, 0x21,
|
||||
0x5C, 0x21, 0x5D, 0x21, 0x5E, 0x21, 0x5F, 0x21, 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21,
|
||||
0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21,
|
||||
0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21,
|
||||
0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, 0x68, 0x21, 0x69, 0x21, 0x6A, 0x21, 0x6B, 0x21,
|
||||
0x6C, 0x21, 0x6D, 0x21, 0x6E, 0x21, 0x6F, 0x21, 0x80, 0x21, 0x81, 0x21, 0x82, 0x21, 0x83, 0x21,
|
||||
0x83, 0x21, 0xFF, 0xFF, 0x4B, 0x03, 0xB6, 0x24, 0xB7, 0x24, 0xB8, 0x24, 0xB9, 0x24, 0xBA, 0x24,
|
||||
0xBB, 0x24, 0xBC, 0x24, 0xBD, 0x24, 0xBE, 0x24, 0xBF, 0x24, 0xC0, 0x24, 0xC1, 0x24, 0xC2, 0x24,
|
||||
0xC3, 0x24, 0xC4, 0x24, 0xC5, 0x24, 0xC6, 0x24, 0xC7, 0x24, 0xC8, 0x24, 0xC9, 0x24, 0xCA, 0x24,
|
||||
0xCB, 0x24, 0xCC, 0x24, 0xCD, 0x24, 0xCE, 0x24, 0xCF, 0x24, 0xFF, 0xFF, 0x46, 0x07, 0x00, 0x2C,
|
||||
0x01, 0x2C, 0x02, 0x2C, 0x03, 0x2C, 0x04, 0x2C, 0x05, 0x2C, 0x06, 0x2C, 0x07, 0x2C, 0x08, 0x2C,
|
||||
0x09, 0x2C, 0x0A, 0x2C, 0x0B, 0x2C, 0x0C, 0x2C, 0x0D, 0x2C, 0x0E, 0x2C, 0x0F, 0x2C, 0x10, 0x2C,
|
||||
0x11, 0x2C, 0x12, 0x2C, 0x13, 0x2C, 0x14, 0x2C, 0x15, 0x2C, 0x16, 0x2C, 0x17, 0x2C, 0x18, 0x2C,
|
||||
0x19, 0x2C, 0x1A, 0x2C, 0x1B, 0x2C, 0x1C, 0x2C, 0x1D, 0x2C, 0x1E, 0x2C, 0x1F, 0x2C, 0x20, 0x2C,
|
||||
0x21, 0x2C, 0x22, 0x2C, 0x23, 0x2C, 0x24, 0x2C, 0x25, 0x2C, 0x26, 0x2C, 0x27, 0x2C, 0x28, 0x2C,
|
||||
0x29, 0x2C, 0x2A, 0x2C, 0x2B, 0x2C, 0x2C, 0x2C, 0x2D, 0x2C, 0x2E, 0x2C, 0x5F, 0x2C, 0x60, 0x2C,
|
||||
0x60, 0x2C, 0x62, 0x2C, 0x63, 0x2C, 0x64, 0x2C, 0x65, 0x2C, 0x66, 0x2C, 0x67, 0x2C, 0x67, 0x2C,
|
||||
0x69, 0x2C, 0x69, 0x2C, 0x6B, 0x2C, 0x6B, 0x2C, 0x6D, 0x2C, 0x6E, 0x2C, 0x6F, 0x2C, 0x70, 0x2C,
|
||||
0x71, 0x2C, 0x72, 0x2C, 0x73, 0x2C, 0x74, 0x2C, 0x75, 0x2C, 0x75, 0x2C, 0x77, 0x2C, 0x78, 0x2C,
|
||||
0x79, 0x2C, 0x7A, 0x2C, 0x7B, 0x2C, 0x7C, 0x2C, 0x7D, 0x2C, 0x7E, 0x2C, 0x7F, 0x2C, 0x80, 0x2C,
|
||||
0x80, 0x2C, 0x82, 0x2C, 0x82, 0x2C, 0x84, 0x2C, 0x84, 0x2C, 0x86, 0x2C, 0x86, 0x2C, 0x88, 0x2C,
|
||||
0x88, 0x2C, 0x8A, 0x2C, 0x8A, 0x2C, 0x8C, 0x2C, 0x8C, 0x2C, 0x8E, 0x2C, 0x8E, 0x2C, 0x90, 0x2C,
|
||||
0x90, 0x2C, 0x92, 0x2C, 0x92, 0x2C, 0x94, 0x2C, 0x94, 0x2C, 0x96, 0x2C, 0x96, 0x2C, 0x98, 0x2C,
|
||||
0x98, 0x2C, 0x9A, 0x2C, 0x9A, 0x2C, 0x9C, 0x2C, 0x9C, 0x2C, 0x9E, 0x2C, 0x9E, 0x2C, 0xA0, 0x2C,
|
||||
0xA0, 0x2C, 0xA2, 0x2C, 0xA2, 0x2C, 0xA4, 0x2C, 0xA4, 0x2C, 0xA6, 0x2C, 0xA6, 0x2C, 0xA8, 0x2C,
|
||||
0xA8, 0x2C, 0xAA, 0x2C, 0xAA, 0x2C, 0xAC, 0x2C, 0xAC, 0x2C, 0xAE, 0x2C, 0xAE, 0x2C, 0xB0, 0x2C,
|
||||
0xB0, 0x2C, 0xB2, 0x2C, 0xB2, 0x2C, 0xB4, 0x2C, 0xB4, 0x2C, 0xB6, 0x2C, 0xB6, 0x2C, 0xB8, 0x2C,
|
||||
0xB8, 0x2C, 0xBA, 0x2C, 0xBA, 0x2C, 0xBC, 0x2C, 0xBC, 0x2C, 0xBE, 0x2C, 0xBE, 0x2C, 0xC0, 0x2C,
|
||||
0xC0, 0x2C, 0xC2, 0x2C, 0xC2, 0x2C, 0xC4, 0x2C, 0xC4, 0x2C, 0xC6, 0x2C, 0xC6, 0x2C, 0xC8, 0x2C,
|
||||
0xC8, 0x2C, 0xCA, 0x2C, 0xCA, 0x2C, 0xCC, 0x2C, 0xCC, 0x2C, 0xCE, 0x2C, 0xCE, 0x2C, 0xD0, 0x2C,
|
||||
0xD0, 0x2C, 0xD2, 0x2C, 0xD2, 0x2C, 0xD4, 0x2C, 0xD4, 0x2C, 0xD6, 0x2C, 0xD6, 0x2C, 0xD8, 0x2C,
|
||||
0xD8, 0x2C, 0xDA, 0x2C, 0xDA, 0x2C, 0xDC, 0x2C, 0xDC, 0x2C, 0xDE, 0x2C, 0xDE, 0x2C, 0xE0, 0x2C,
|
||||
0xE0, 0x2C, 0xE2, 0x2C, 0xE2, 0x2C, 0xE4, 0x2C, 0xE5, 0x2C, 0xE6, 0x2C, 0xE7, 0x2C, 0xE8, 0x2C,
|
||||
0xE9, 0x2C, 0xEA, 0x2C, 0xEB, 0x2C, 0xEC, 0x2C, 0xED, 0x2C, 0xEE, 0x2C, 0xEF, 0x2C, 0xF0, 0x2C,
|
||||
0xF1, 0x2C, 0xF2, 0x2C, 0xF3, 0x2C, 0xF4, 0x2C, 0xF5, 0x2C, 0xF6, 0x2C, 0xF7, 0x2C, 0xF8, 0x2C,
|
||||
0xF9, 0x2C, 0xFA, 0x2C, 0xFB, 0x2C, 0xFC, 0x2C, 0xFD, 0x2C, 0xFE, 0x2C, 0xFF, 0x2C, 0xA0, 0x10,
|
||||
0xA1, 0x10, 0xA2, 0x10, 0xA3, 0x10, 0xA4, 0x10, 0xA5, 0x10, 0xA6, 0x10, 0xA7, 0x10, 0xA8, 0x10,
|
||||
0xA9, 0x10, 0xAA, 0x10, 0xAB, 0x10, 0xAC, 0x10, 0xAD, 0x10, 0xAE, 0x10, 0xAF, 0x10, 0xB0, 0x10,
|
||||
0xB1, 0x10, 0xB2, 0x10, 0xB3, 0x10, 0xB4, 0x10, 0xB5, 0x10, 0xB6, 0x10, 0xB7, 0x10, 0xB8, 0x10,
|
||||
0xB9, 0x10, 0xBA, 0x10, 0xBB, 0x10, 0xBC, 0x10, 0xBD, 0x10, 0xBE, 0x10, 0xBF, 0x10, 0xC0, 0x10,
|
||||
0xC1, 0x10, 0xC2, 0x10, 0xC3, 0x10, 0xC4, 0x10, 0xC5, 0x10, 0xFF, 0xFF, 0x1B, 0xD2, 0x21, 0xFF,
|
||||
0x22, 0xFF, 0x23, 0xFF, 0x24, 0xFF, 0x25, 0xFF, 0x26, 0xFF, 0x27, 0xFF, 0x28, 0xFF, 0x29, 0xFF,
|
||||
0x2A, 0xFF, 0x2B, 0xFF, 0x2C, 0xFF, 0x2D, 0xFF, 0x2E, 0xFF, 0x2F, 0xFF, 0x30, 0xFF, 0x31, 0xFF,
|
||||
0x32, 0xFF, 0x33, 0xFF, 0x34, 0xFF, 0x35, 0xFF, 0x36, 0xFF, 0x37, 0xFF, 0x38, 0xFF, 0x39, 0xFF,
|
||||
0x3A, 0xFF, 0x5B, 0xFF, 0x5C, 0xFF, 0x5D, 0xFF, 0x5E, 0xFF, 0x5F, 0xFF, 0x60, 0xFF, 0x61, 0xFF,
|
||||
0x62, 0xFF, 0x63, 0xFF, 0x64, 0xFF, 0x65, 0xFF, 0x66, 0xFF, 0x67, 0xFF, 0x68, 0xFF, 0x69, 0xFF,
|
||||
0x6A, 0xFF, 0x6B, 0xFF, 0x6C, 0xFF, 0x6D, 0xFF, 0x6E, 0xFF, 0x6F, 0xFF, 0x70, 0xFF, 0x71, 0xFF,
|
||||
0x72, 0xFF, 0x73, 0xFF, 0x74, 0xFF, 0x75, 0xFF, 0x76, 0xFF, 0x77, 0xFF, 0x78, 0xFF, 0x79, 0xFF,
|
||||
0x7A, 0xFF, 0x7B, 0xFF, 0x7C, 0xFF, 0x7D, 0xFF, 0x7E, 0xFF, 0x7F, 0xFF, 0x80, 0xFF, 0x81, 0xFF,
|
||||
0x82, 0xFF, 0x83, 0xFF, 0x84, 0xFF, 0x85, 0xFF, 0x86, 0xFF, 0x87, 0xFF, 0x88, 0xFF, 0x89, 0xFF,
|
||||
0x8A, 0xFF, 0x8B, 0xFF, 0x8C, 0xFF, 0x8D, 0xFF, 0x8E, 0xFF, 0x8F, 0xFF, 0x90, 0xFF, 0x91, 0xFF,
|
||||
0x92, 0xFF, 0x93, 0xFF, 0x94, 0xFF, 0x95, 0xFF, 0x96, 0xFF, 0x97, 0xFF, 0x98, 0xFF, 0x99, 0xFF,
|
||||
0x9A, 0xFF, 0x9B, 0xFF, 0x9C, 0xFF, 0x9D, 0xFF, 0x9E, 0xFF, 0x9F, 0xFF, 0xA0, 0xFF, 0xA1, 0xFF,
|
||||
0xA2, 0xFF, 0xA3, 0xFF, 0xA4, 0xFF, 0xA5, 0xFF, 0xA6, 0xFF, 0xA7, 0xFF, 0xA8, 0xFF, 0xA9, 0xFF,
|
||||
0xAA, 0xFF, 0xAB, 0xFF, 0xAC, 0xFF, 0xAD, 0xFF, 0xAE, 0xFF, 0xAF, 0xFF, 0xB0, 0xFF, 0xB1, 0xFF,
|
||||
0xB2, 0xFF, 0xB3, 0xFF, 0xB4, 0xFF, 0xB5, 0xFF, 0xB6, 0xFF, 0xB7, 0xFF, 0xB8, 0xFF, 0xB9, 0xFF,
|
||||
0xBA, 0xFF, 0xBB, 0xFF, 0xBC, 0xFF, 0xBD, 0xFF, 0xBE, 0xFF, 0xBF, 0xFF, 0xC0, 0xFF, 0xC1, 0xFF,
|
||||
0xC2, 0xFF, 0xC3, 0xFF, 0xC4, 0xFF, 0xC5, 0xFF, 0xC6, 0xFF, 0xC7, 0xFF, 0xC8, 0xFF, 0xC9, 0xFF,
|
||||
0xCA, 0xFF, 0xCB, 0xFF, 0xCC, 0xFF, 0xCD, 0xFF, 0xCE, 0xFF, 0xCF, 0xFF, 0xD0, 0xFF, 0xD1, 0xFF,
|
||||
0xD2, 0xFF, 0xD3, 0xFF, 0xD4, 0xFF, 0xD5, 0xFF, 0xD6, 0xFF, 0xD7, 0xFF, 0xD8, 0xFF, 0xD9, 0xFF,
|
||||
0xDA, 0xFF, 0xDB, 0xFF, 0xDC, 0xFF, 0xDD, 0xFF, 0xDE, 0xFF, 0xDF, 0xFF, 0xE0, 0xFF, 0xE1, 0xFF,
|
||||
0xE2, 0xFF, 0xE3, 0xFF, 0xE4, 0xFF, 0xE5, 0xFF, 0xE6, 0xFF, 0xE7, 0xFF, 0xE8, 0xFF, 0xE9, 0xFF,
|
||||
0xEA, 0xFF, 0xEB, 0xFF, 0xEC, 0xFF, 0xED, 0xFF, 0xEE, 0xFF, 0xEF, 0xFF, 0xF0, 0xFF, 0xF1, 0xFF,
|
||||
0xF2, 0xFF, 0xF3, 0xFF, 0xF4, 0xFF, 0xF5, 0xFF, 0xF6, 0xFF, 0xF7, 0xFF, 0xF8, 0xFF, 0xF9, 0xFF,
|
||||
0xFA, 0xFF, 0xFB, 0xFF, 0xFC, 0xFF, 0xFD, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
/* end of exfat_upcase.c */
|
19
fs/exfat/exfat_version.h
Normal file
19
fs/exfat/exfat_version.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/************************************************************************/
|
||||
/* */
|
||||
/* PROJECT : exFAT & FAT12/16/32 File System */
|
||||
/* FILE : exfat_version.h */
|
||||
/* PURPOSE : exFAT File Manager */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* NOTES */
|
||||
/* */
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* REVISION HISTORY */
|
||||
/* */
|
||||
/* - 2012.02.10 : Release Version 1.1.0 */
|
||||
/* - 2012.04.02 : P1 : Change Module License to Samsung Proprietary */
|
||||
/* - 2012.06.07 : P2 : Fixed incorrect filename problem */
|
||||
/* */
|
||||
/************************************************************************/
|
||||
|
||||
#define EXFAT_VERSION "1.2.5"
|
Loading…
Reference in a new issue