1.exfat支持

This commit is contained in:
payton 2023-11-23 15:45:32 +08:00
parent ee41d9c0bd
commit a685df607b
45 changed files with 13328 additions and 10 deletions

View File

@ -11,6 +11,8 @@ SF_ADC_MUXA=224
SF_ADC_MUXB=225 SF_ADC_MUXB=225
DELAY=0.003 DELAY=0.003
insmod /etc/lib/modules/$KERVER/extra/fs/exfat/exfat.ko
echo ${SF_ADC_MUXA} > /sys/class/gpio/export echo ${SF_ADC_MUXA} > /sys/class/gpio/export
echo ${SF_ADC_MUXB} > /sys/class/gpio/export echo ${SF_ADC_MUXB} > /sys/class/gpio/export

View File

@ -131,6 +131,7 @@ static FST_FS_TYPE m_GxStrgType = FST_FS_TYPE_UITRON;
#if (FWS_FUNC == ENABLE) #if (FWS_FUNC == ENABLE)
static void *mp_fwsrv_work_buf = NULL; static void *mp_fwsrv_work_buf = NULL;
#endif #endif
static BOOL g_bSupportExfat = FALSE;
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// EMBMEM // EMBMEM
@ -359,6 +360,8 @@ void System_OnStrgInit_FS(void)
GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 10); GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 10);
#endif #endif
GxStrg_SetConfigEx(0, FILE_CFG_SUPPORT_EXFAT, TRUE);
g_bSupportExfat = TRUE;
//set the device node of msdc mode for emmc only //set the device node of msdc mode for emmc only
#if (defined(_EMBMEM_EMMC_) && !defined(__FREERTOS)) #if (defined(_EMBMEM_EMMC_) && !defined(__FREERTOS))
emmc_set_dev_node("/dev/mmcblk2p5"); //This devicde node is related to storate-partition, it is last rootfslX logical partition. Using "cat /proc/nvt_info/emmc" to get. emmc_set_dev_node("/dev/mmcblk2p5"); //This devicde node is related to storate-partition, it is last rootfslX logical partition. Using "cat /proc/nvt_info/emmc" to get.
@ -586,14 +589,64 @@ void Card_DetBusy(void)
} }
#if (FSCK_FUNC == ENABLE) #if (FSCK_FUNC == ENABLE)
int search_str_in_file(char *path, char *str)
{
FILE *fp = NULL;
UINT32 u32ize = 0;
int found = 0;
char *pStrSrc = NULL;
fp = fopen(path, "r");
if (fp) {
fseek(fp, 0, SEEK_END);
u32ize = ftell(fp); // take file size
fseek(fp, 0, SEEK_SET); // move to position zero
pStrSrc = (char *)malloc(u32ize * sizeof(char));
if (pStrSrc) {
fread(pStrSrc, 1, u32ize, fp);
if (strstr(pStrSrc, str)) {
found = 1;
}
free(pStrSrc);
}
fclose(fp);
fp = NULL;
pStrSrc = NULL;
u32ize = 0;
}
return found;
}
int System_check_mmcblk0p1(void)
{
SysMain_system("ls /dev/mmcblk0p1 > /tmp/lsdev.txt");
vos_util_delay_ms(100);
if (search_str_in_file("/tmp/lsdev.txt", "/dev/mmcblk0p1")) {
return 1;
} else {
return 0;
}
}
int System_mount_storage(char *pMountPath) int System_mount_storage(char *pMountPath)
{ {
int ret = 0; int ret = 0;
time_t t, t_local, t_gmt; time_t t, t_local, t_gmt;
struct tm tt_local, tt_gmt; struct tm tt_local, tt_gmt;
char opts[20]; char opts[20];
char *pDevSrc = "/dev/mmcblk0p1"; char *pDevSrc;
char *pFileSysType = "vfat"; char *pFileSysType = "vfat";
char *pFileSysExType = "exfat";
BOOL bexfat = FALSE;
if (System_check_mmcblk0p1()) {
pDevSrc = "/dev/mmcblk0p1";
} else {
pDevSrc = "/dev/mmcblk0";
}
time(&t); time(&t);
localtime_r(&t, &tt_local); localtime_r(&t, &tt_local);
@ -604,8 +657,47 @@ int System_mount_storage(char *pMountPath)
snprintf(opts, 19, "time_offset=%d", (t_local-t_gmt)/60); snprintf(opts, 19, "time_offset=%d", (t_local-t_gmt)/60);
DBG_IND("gtime=%d, ltime=%d, diff=%d, m=%d, %s\r\n", t_gmt, t_local, (t_local-t_gmt), (t_local-t_gmt)/60, opts); DBG_IND("gtime=%d, ltime=%d, diff=%d, m=%d, %s\r\n", t_gmt, t_local, (t_local-t_gmt), (t_local-t_gmt)/60, opts);
{
long long DevSize = 0;
int fd = 0;
long long size = 0;
DevSize = 0;//set to zero first
fd = open(pDevSrc, O_RDONLY);
if(fd < 0) {
DBG_ERR("open %s: errno = %d, errmsg = %s\r\n", pDevSrc, errno, strerror(errno));
} else {
if(ioctl(fd, BLKGETSIZE64, &size) < 0) {
DBG_ERR("ioctl BLKGETSIZE64 failed\r\n");
}
if (0 != close(fd)) {
DBG_ERR("close %s: errno = %d, errmsg = %s\r\n", pDevSrc, errno, strerror(errno));
}
}
DBG_DUMP("%s: %s size = %lld\r\n", __func__, pDevSrc, size);
DevSize = size;
//original SD card
if(g_bSupportExfat && DevSize > 32*1024*1024*1024LL)
{
bexfat = TRUE;
}
else
{
bexfat = FALSE;
}
}
// mount sd card // mount sd card
ret = mount(pDevSrc, pMountPath, pFileSysType, MS_DIRSYNC, opts); if (bexfat == FALSE) {
ret = mount(pDevSrc, pMountPath, pFileSysType, MS_DIRSYNC, opts);
} else {
ret = mount(pDevSrc, pMountPath, pFileSysExType, MS_DIRSYNC, opts);
}
if(ret) { if(ret) {
if (errno == EBUSY) { if (errno == EBUSY) {
@ -636,6 +728,7 @@ int System_umount_storage(char *pMountPath)
} }
#endif #endif
INT32 System_OnStrgInsert(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray) INT32 System_OnStrgInsert(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray)
{ {
UINT32 stg_id = paramArray[0]; UINT32 stg_id = paramArray[0];
@ -660,8 +753,15 @@ INT32 System_OnStrgInsert(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray)
System_umount_storage(pMountPath); System_umount_storage(pMountPath);
/*Under normal situation, fsck checking doesn't need to print the message via UART port. /*Under normal situation, fsck checking doesn't need to print the message via UART port.
We sotre the message to /tmp/fsck.txt (on DRAM). */ We sotre the message to /tmp/fsck.txt (on DRAM). */
SysMain_system("fsck.fat -a /dev/mmcblk0p1 > /tmp/fsck.txt"); //Store to /tmp/fsck.txt and use "cat /tmp/fsck.txt". if (System_check_mmcblk0p1()) {
//SysMain_system("fsck.fat -a /dev/mmcblk0p1"); //The fsck ckecking will print the message directly. DBG_IND("fsck /dev/mmcblk0p1\r\n");
SysMain_system("fsck.fat -a /dev/mmcblk0p1 > /tmp/fsck.txt"); //Store to /tmp/fsck.txt and use "cat /tmp/fsck.txt".
//SysMain_system("fsck.fat -a /dev/mmcblk0p1"); //The fsck checking will print the message directly.
} else {
DBG_IND("no /dev/mmcblk0p1, try to fsck /dev/mmcblk0\r\n");
SysMain_system("fsck.fat -a /dev/mmcblk0 > /tmp/fsck.txt"); //Store to /tmp/fsck.txt and use "cat /tmp/fsck.txt".
//SysMain_system("fsck.fat -a /dev/mmcblk0"); //The fsck checking will print the message directly.
}
ret_val = System_mount_storage(pMountPath); ret_val = System_mount_storage(pMountPath);
if (ret_val) { if (ret_val) {
@ -722,7 +822,7 @@ INT32 System_OnStrgInsert(VControl *pCtrl, UINT32 paramNum, UINT32 *paramArray)
dcfParm.WorkbuffSize = POOL_SIZE_DCF_BUFFER; dcfParm.WorkbuffSize = POOL_SIZE_DCF_BUFFER;
DCF_Open(&dcfParm); DCF_Open(&dcfParm);
// DCF_ScanObj(); // DCF_ScanObj();
} }
#endif #endif

View File

@ -46,6 +46,7 @@ obj-m += \
msdcnvt/msdcnvt_custom_si/ \ msdcnvt/msdcnvt_custom_si/ \
touch/touch_gt911/ \ touch/touch_gt911/ \
mcu/ \ mcu/ \
fs/exfat/ \
#obj-m += net/bcmdhd.100.10.545.x/ \ #obj-m += net/bcmdhd.100.10.545.x/ \
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += debug/nvt_data_breakpoint/ obj-$(CONFIG_HAVE_HW_BREAKPOINT) += debug/nvt_data_breakpoint/

7
code/driver/source/fs/exfat/.gitignore vendored Executable file
View File

@ -0,0 +1,7 @@
*.cmd
*.ko
*.mod.c
modules.order
Module.symvers
*.o
.tmp_versions

View File

@ -0,0 +1,39 @@
config EXFAT_FS
tristate "exFAT fs support"
select NLS
help
This adds support for the exFAT file system.
config EXFAT_DISCARD
bool "enable discard support"
depends on EXFAT_FS
default y
config EXFAT_DELAYED_SYNC
bool "enable delayed sync"
depends on EXFAT_FS
default n
config EXFAT_KERNEL_DEBUG
bool "enable kernel debug features via ioctl"
depends on EXFAT_FS
default n
config EXFAT_DEBUG_MSG
bool "print debug messages"
depends on EXFAT_FS
default n
config EXFAT_DEFAULT_CODEPAGE
int "Default codepage for exFAT"
default 437
depends on EXFAT_FS
help
This option should be set to the codepage of your exFAT filesystems.
config EXFAT_DEFAULT_IOCHARSET
string "Default iocharset for exFAT"
default "utf8"
depends on EXFAT_FS
help
Set this to the default input/output character set you'd like exFAT to use.

View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -0,0 +1,37 @@
obj-m += exfat.o
exfat-objs := exfat_core.o exfat_super.o exfat_api.o exfat_blkdev.o exfat_cache.o \
exfat_data.o exfat_bitmap.o exfat_nls.o exfat_oal.o exfat_upcase.o
ccflags-y += -I$(NVT_DRIVER_DIR)/include
ifeq ($(KERNELRELEASE),)
PWD := $(shell pwd)
KERVER ?= $(NVT_LINUX_VER)
KDIR ?= $(KERNELDIR)
MDIR ?= $(KERNELDIR)/_install_modules/lib/modules/$(KERVER)/extra
MODPATH := $(shell echo $(PWD) | awk -F'linux-driver/' '{print $$NF}')
MODNAME := $(shell echo $(obj-m:.o=.ko))
modules:
$(MAKE) -C $(KDIR) M=$(PWD) modules
modules_install:
@if [ -z $(NVT_MOD_INSTALL) ]; then \
rm -f $(MDIR)/$(MODPATH)/$(MODNAME); \
install -m644 -b -D $(MODNAME) ${MDIR}/$(MODPATH)/$(MODNAME); \
cd $(KDIR)/_install_modules/lib/modules/$(KERVER)/; depmod -b $(KDIR)/_install_modules/ -a $(KERVER); \
else \
mkdir -p $(NVT_MOD_INSTALL)/lib/modules/$(KERVER); \
install -m644 -b -D $(MODNAME) $(NVT_MOD_INSTALL)/lib/modules/$(KERVER)/extra/$(MODPATH)/$(MODNAME); \
fi
clean:
@SRC="`find . -name "*.c" ! -name "*.mod.c"`"; \
if [ "$$SRC" ]; then \
rm -rf .tmp_versions Module.symvers modules.order `find . -type f -name "*.mod.c" -o -name ".*.cmd" -o -name "*.o" -o -name "*.ko" -o -name "modules.order" -o -name *~`; \
echo ">>> Clean"; \
else \
echo ">>> Skip"; \
fi \
.PHONY: modules modules_install clean
endif

View File

@ -0,0 +1,98 @@
exfat-nofuse
============
Linux non-fuse read/write kernel driver for the exFAT, FAT12, FAT16 and vfat (FAT32) file systems.<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!<br />
Big thanks to benpicco for fixing 3.11.y compatibility!
Special thanks to github user AndreiLux for spreading the word about the leak!<br />
Installing as a stand-alone module:
====================================
make
sudo make install
To load the driver manually, run this as root:
modprobe exfat
You may also specify custom toolchains by using CROSS_COMPILE flag, in my case:
>CROSS_COMPILE=../dorimanx-SG2-I9100-Kernel/android-toolchain/bin/arm-eabi-
Installing as a part of the kernel:
======================================
Let's take [linux] as the path to your kernel source dir...
cd [linux]
cp -rvf exfat-nofuse [linux]/fs/exfat
edit [linux]/fs/Kconfig
```
menu "DOS/FAT/NT Filesystems"
source "fs/fat/Kconfig"
+source "fs/exfat/Kconfig"
source "fs/ntfs/Kconfig"
endmenu
```
edit [linux]/fs/Makefile
```
obj-$(CONFIG_FAT_FS) += fat/
+obj-$(CONFIG_EXFAT_FS) += exfat/
obj-$(CONFIG_BFS_FS) += bfs/
```
cd [linux]
make menuconfig
Go to:
> File systems > DOS/FAT/NT
> check 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
Have fun.
Installing as a DKMS module:
=================================
You can have even more fun with exfat-nofuse by installing it as a DKMS module has the main advantage of being auto-compiled (and thus, possibly surviving) between kernel upgrades.
First, get dkms. On Ubuntu this should be:
sudo apt install dkms
Then copy the root of this repository to /usr/share:
sudo cp -R . /usr/src/exfat-1.2.8 (or whatever version number declared on dkms.conf is)
sudo dkms add -m exfat -v 1.2.8
Build and load the module:
sudo dkms build -m exfat -v 1.2.8
sudo dkms install -m exfat -v 1.2.8
Now you have a proper dkms module that will work for a long time... hopefully.
Free Software for the Free Minds!
=================================

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,501 @@
---- inode Matches (620 in 6 files) ----
Exfat_api.c:int FsLookupFile(struct inode *inode, char *path, FILE_ID_T *fid)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsLookupFile(inode, path, fid);
Exfat_api.c:int FsCreateFile(struct inode *inode, char *path, u8 mode, FILE_ID_T *fid)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsCreateFile(inode, path, mode, fid);
Exfat_api.c:int FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsReadFile(inode, fid, buffer, count, rcount);
Exfat_api.c:int FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsWriteFile(inode, fid, buffer, count, wcount);
Exfat_api.c:int FsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: DPRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);
Exfat_api.c: err = ffsTruncateFile(inode, old_size, new_size);
Exfat_api.c:int FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
Exfat_api.c:int FsRemoveFile(struct inode *inode, FILE_ID_T *fid)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsRemoveFile(inode, fid);
Exfat_api.c:int FsSetAttr(struct inode *inode, u32 attr)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsSetAttr(inode, attr);
Exfat_api.c:int FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsGetStat(inode, info);
Exfat_api.c:int FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: DPRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);
Exfat_api.c: err = ffsSetStat(inode, info);
Exfat_api.c:int FsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsMapCluster(inode, clu_offset, clu);
Exfat_api.c:int FsCreateDir(struct inode *inode, char *path, FILE_ID_T *fid)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsCreateDir(inode, path, fid);
Exfat_api.c:int FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsReadDir(inode, dir_entry);
Exfat_api.c:int FsRemoveDir(struct inode *inode, FILE_ID_T *fid)
Exfat_api.c: struct super_block *sb = inode->i_sb;
Exfat_api.c: err = ffsRemoveDir(inode, fid);
Exfat_api.h: int FsLookupFile(struct inode *inode, char *path, FILE_ID_T *fid);
Exfat_api.h: int FsCreateFile(struct inode *inode, char *path, u8 mode, FILE_ID_T *fid);
Exfat_api.h: int FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount);
Exfat_api.h: int FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount);
Exfat_api.h: int FsTruncateFile(struct inode *inode, u64 old_size, u64 new_size);
Exfat_api.h: int FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry);
Exfat_api.h: int FsRemoveFile(struct inode *inode, FILE_ID_T *fid);
Exfat_api.h: int FsSetAttr(struct inode *inode, u32 attr);
Exfat_api.h: int FsReadStat(struct inode *inode, DIR_ENTRY_T *info);
Exfat_api.h: int FsWriteStat(struct inode *inode, DIR_ENTRY_T *info);
Exfat_api.h: int FsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu);
Exfat_api.h: int FsCreateDir(struct inode *inode, char *path, FILE_ID_T *fid);
Exfat_api.h: int FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry);
Exfat_api.h: int FsRemoveDir(struct inode *inode, FILE_ID_T *fid);
Exfat_core.c:s32 ffsLookupFile(struct inode *inode, char *path, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: ret = resolve_path(inode, path, &dir, &uni_name);
Exfat_core.c:s32 ffsCreateFile(struct inode *inode, char *path, u8 mode, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: ret = resolve_path(inode, path, &dir, &uni_name);
Exfat_core.c: ret = create_file(inode, &dir, &uni_name, mode, fid);
Exfat_core.c:s32 ffsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c:s32 ffsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c:s32 ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_core.c:static void update_parent_info(FILE_ID_T *fid, struct inode *parent_inode)
Exfat_core.c:s32 ffsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
Exfat_core.c: struct inode *new_inode = new_dentry->d_inode;
Exfat_core.c:s32 ffsRemoveFile(struct inode *inode, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: remove_file(inode, &dir, dentry);
Exfat_core.c:s32 ffsSetAttr(struct inode *inode, u32 attr)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_core.c:s32 ffsGetStat(struct inode *inode, DIR_ENTRY_T *info)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_core.c:s32 ffsSetStat(struct inode *inode, DIR_ENTRY_T *info)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_core.c:s32 ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_core.c: if (EXFAT_I(inode)->mmu_private == 0)
Exfat_core.c: num_clusters = (s32)((EXFAT_I(inode)->mmu_private-1) >> p_fs->cluster_size_bits) + 1;
Exfat_core.c: /* add number of new blocks to inode */
Exfat_core.c: inode->i_blocks += num_alloced << (p_fs->cluster_size_bits - 9);
Exfat_core.c:s32 ffsCreateDir(struct inode *inode, char *path, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: ret = resolve_path(inode, path, &dir, &uni_name);
Exfat_core.c: ret = create_dir(inode, &dir, &uni_name, fid);
Exfat_core.c:s32 ffsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_core.c:s32 ffsRemoveDir(struct inode *inode, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: remove_file(inode, &dir, dentry);
Exfat_core.c:s32 find_empty_entry(struct inode *inode, CHAIN_T *p_dir, s32 num_entries)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_core.c: size = i_size_read(inode);
Exfat_core.c: i_size_write(inode, i_size_read(inode)+p_fs->cluster_size);
Exfat_core.c: EXFAT_I(inode)->mmu_private += p_fs->cluster_size;
Exfat_core.c: EXFAT_I(inode)->fid.size += p_fs->cluster_size;
Exfat_core.c: EXFAT_I(inode)->fid.flags = p_dir->flags;
Exfat_core.c: inode->i_blocks += 1 << (p_fs->cluster_size_bits - 9);
Exfat_core.c:s32 resolve_path(struct inode *inode, char *path, CHAIN_T *p_dir, UNI_NAME_T *p_uniname)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_core.c: fid->size = i_size_read(inode);
Exfat_core.c:s32 create_dir(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: dentry = find_empty_entry(inode, p_dir, num_entries);
Exfat_core.c:s32 create_file(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, u8 mode, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: dentry = find_empty_entry(inode, p_dir, num_entries);
Exfat_core.c:void remove_file(struct inode *inode, CHAIN_T *p_dir, s32 entry)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c:s32 rename_file(struct inode *inode, CHAIN_T *p_dir, s32 oldentry, UNI_NAME_T *p_uniname, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: newentry = find_empty_entry(inode, p_dir, num_new_entries);
Exfat_core.c:s32 move_file(struct inode *inode, CHAIN_T *p_olddir, s32 oldentry, CHAIN_T *p_newdir, UNI_NAME_T *p_uniname, FILE_ID_T *fid)
Exfat_core.c: struct super_block *sb = inode->i_sb;
Exfat_core.c: newentry = find_empty_entry(inode, p_newdir, num_new_entries);
Exfat_core.h:s32 ffsLookupFile(struct inode *inode, char *path, FILE_ID_T *fid);
Exfat_core.h:s32 ffsCreateFile(struct inode *inode, char *path, u8 mode, FILE_ID_T *fid);
Exfat_core.h:s32 ffsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount);
Exfat_core.h:s32 ffsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount);
Exfat_core.h:s32 ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size);
Exfat_core.h:s32 ffsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry);
Exfat_core.h:s32 ffsRemoveFile(struct inode *inode, FILE_ID_T *fid);
Exfat_core.h:s32 ffsSetAttr(struct inode *inode, u32 attr);
Exfat_core.h:s32 ffsGetStat(struct inode *inode, DIR_ENTRY_T *info);
Exfat_core.h:s32 ffsSetStat(struct inode *inode, DIR_ENTRY_T *info);
Exfat_core.h:s32 ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu);
Exfat_core.h:s32 ffsCreateDir(struct inode *inode, char *path, FILE_ID_T *fid);
Exfat_core.h:s32 ffsReadDir(struct inode *inode, DIR_ENTRY_T *dir_ent);
Exfat_core.h:s32 ffsRemoveDir(struct inode *inode, FILE_ID_T *fid);
Exfat_core.h:s32 find_empty_entry(struct inode *inode, CHAIN_T *p_dir, s32 num_entries);
Exfat_core.h:s32 resolve_path(struct inode *inode, char *path, CHAIN_T *p_dir, UNI_NAME_T *p_uniname);
Exfat_core.h:s32 create_dir(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
Exfat_core.h:s32 create_file(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, u8 mode, FILE_ID_T *fid);
Exfat_core.h:void remove_file(struct inode *inode, CHAIN_T *p_dir, s32 entry);
Exfat_core.h:s32 rename_file(struct inode *inode, CHAIN_T *p_dir, s32 old_entry, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
Exfat_core.h:s32 move_file(struct inode *inode, CHAIN_T *p_olddir, s32 oldentry, CHAIN_T *p_newdir, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
Exfat_super.c:/* Some of the source code in this file came from "linux/fs/fat/file.c","linux/fs/fat/inode.c" and "linux/fs/fat/misc.c". */
Exfat_super.c: * linux/fs/fat/inode.c
Exfat_super.c:static void _exfat_truncate(struct inode *inode, loff_t old_size);
Exfat_super.c:static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos);
Exfat_super.c:static int exfat_generic_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);
Exfat_super.c:static int exfat_sync_inode(struct inode *inode);
Exfat_super.c:static struct inode *exfat_build_inode(struct super_block *sb, FILE_ID_T *fid, loff_t i_pos);
Exfat_super.c:static void exfat_detach(struct inode *inode);
Exfat_super.c:static void exfat_attach(struct inode *inode, loff_t i_pos);
Exfat_super.c:static int exfat_write_inode(struct inode *inode, int wait);
Exfat_super.c:static int exfat_write_inode(struct inode *inode, struct writeback_control *wbc);
Exfat_super.c:static int exfat_d_hash(const struct dentry *dentry, const struct inode *inode,
Exfat_super.c:static int exfat_d_hashi(const struct dentry *dentry, const struct inode *inode,
Exfat_super.c:static int exfat_cmpi(const struct dentry *parent, const struct inode *pinode,
Exfat_super.c: const struct dentry *dentry, const struct inode *inode,
Exfat_super.c:static int exfat_cmp(const struct dentry *parent, const struct inode *pinode,
Exfat_super.c: const struct dentry *dentry, const struct inode *inode,
Exfat_super.c: struct inode *inode = file_inode(filp);
Exfat_super.c: struct inode *inode = filp->f_path.dentry->d_inode;
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: if ((p_fs->vol_type == EXFAT) || (inode->i_ino == EXFAT_ROOT_INO)) {
Exfat_super.c: if (inode->i_ino == EXFAT_ROOT_INO)
Exfat_super.c: inum = inode->i_ino;
Exfat_super.c: EXFAT_I(inode)->fid.size = i_size_read(inode);
Exfat_super.c: EXFAT_I(inode)->fid.rwoffset = cpos >> DENTRY_SIZE_BITS;
Exfat_super.c: err = FsReadDir(inode, &de);
Exfat_super.c: cpos = EXFAT_I(inode)->fid.rwoffset << DENTRY_SIZE_BITS;
Exfat_super.c: inum = inode->i_ino;
Exfat_super.c: loff_t i_pos = ((loff_t) EXFAT_I(inode)->fid.start_clu << 32) |
Exfat_super.c: ((EXFAT_I(inode)->fid.rwoffset-1) & 0xffffffff);
Exfat_super.c: struct inode *tmp = exfat_iget(sb, i_pos);
Exfat_super.c:static int exfat_ioctl_volume_id(struct inode *dir)
Exfat_super.c:static int exfat_generic_ioctl(struct inode *inode, struct file *filp,
Exfat_super.c: struct inode *inode = filp->f_path.dentry->d_inode;
Exfat_super.c: struct inode *inode = filp->f_dentry->d_inode;
Exfat_super.c: return exfat_ioctl_volume_id(inode);
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: struct inode *inode = filp->f_mapping->host;
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c:static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
Exfat_super.c:static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
Exfat_super.c:static int exfat_create(struct inode *dir, struct dentry *dentry, int mode,
Exfat_super.c: struct inode *inode;
Exfat_super.c: inode = exfat_build_inode(sb, &fid, i_pos);
Exfat_super.c: if (IS_ERR(inode)) {
Exfat_super.c: err = PTR_ERR(inode);
Exfat_super.c: INC_IVERSION(inode);
Exfat_super.c: inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
Exfat_super.c: d_instantiate(dentry, inode);
Exfat_super.c:static int exfat_find(struct inode *dir, struct qstr *qname,
Exfat_super.c:static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry,
Exfat_super.c:static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry,
Exfat_super.c: struct inode *inode;
Exfat_super.c: inode = NULL;
Exfat_super.c: inode = exfat_build_inode(sb, &fid, i_pos);
Exfat_super.c: if (IS_ERR(inode)) {
Exfat_super.c: err = PTR_ERR(inode);
Exfat_super.c: i_mode = inode->i_mode;
Exfat_super.c: if (S_ISLNK(i_mode) && !EXFAT_I(inode)->target) {
Exfat_super.c: EXFAT_I(inode)->target = kmalloc(i_size_read(inode)+1, GFP_KERNEL);
Exfat_super.c: if (!EXFAT_I(inode)->target) {
Exfat_super.c: FsReadFile(dir, &fid, EXFAT_I(inode)->target, i_size_read(inode), &ret);
Exfat_super.c: *(EXFAT_I(inode)->target + i_size_read(inode)) = '\0';
Exfat_super.c: alias = d_find_alias(inode);
Exfat_super.c: iput(inode);
Exfat_super.c: dentry = d_splice_alias(inode, dentry);
Exfat_super.c: dentry = d_splice_alias(inode, dentry);
Exfat_super.c:static int exfat_unlink(struct inode *dir, struct dentry *dentry)
Exfat_super.c: struct inode *inode = dentry->d_inode;
Exfat_super.c: EXFAT_I(inode)->fid.size = i_size_read(inode);
Exfat_super.c: err = FsRemoveFile(dir, &(EXFAT_I(inode)->fid));
Exfat_super.c: clear_nlink(inode);
Exfat_super.c: inode->i_mtime = inode->i_atime = current_time(inode);
Exfat_super.c: exfat_detach(inode);
Exfat_super.c: remove_inode_hash(inode);
Exfat_super.c:static int exfat_symlink(struct inode *dir, struct dentry *dentry, const char *target)
Exfat_super.c: struct inode *inode;
Exfat_super.c: inode = exfat_build_inode(sb, &fid, i_pos);
Exfat_super.c: if (IS_ERR(inode)) {
Exfat_super.c: err = PTR_ERR(inode);
Exfat_super.c: INC_IVERSION(inode);
Exfat_super.c: inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
Exfat_super.c: EXFAT_I(inode)->target = kmalloc(len+1, GFP_KERNEL);
Exfat_super.c: if (!EXFAT_I(inode)->target) {
Exfat_super.c: memcpy(EXFAT_I(inode)->target, target, len+1);
Exfat_super.c: d_instantiate(dentry, inode);
Exfat_super.c:static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
Exfat_super.c:static int exfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)
Exfat_super.c: struct inode *inode;
Exfat_super.c: inode = exfat_build_inode(sb, &fid, i_pos);
Exfat_super.c: if (IS_ERR(inode)) {
Exfat_super.c: err = PTR_ERR(inode);
Exfat_super.c: INC_IVERSION(inode);
Exfat_super.c: inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
Exfat_super.c: d_instantiate(dentry, inode);
Exfat_super.c:static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
Exfat_super.c: struct inode *inode = dentry->d_inode;
Exfat_super.c: EXFAT_I(inode)->fid.size = i_size_read(inode);
Exfat_super.c: err = FsRemoveDir(dir, &(EXFAT_I(inode)->fid));
Exfat_super.c: clear_nlink(inode);
Exfat_super.c: inode->i_mtime = inode->i_atime = current_time(inode);
Exfat_super.c: exfat_detach(inode);
Exfat_super.c: remove_inode_hash(inode);
Exfat_super.c:static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
Exfat_super.c: struct inode *new_dir, struct dentry *new_dentry,
Exfat_super.c:static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
Exfat_super.c: struct inode *new_dir, struct dentry *new_dentry)
Exfat_super.c: struct inode *old_inode, *new_inode;
Exfat_super.c:static int exfat_cont_expand(struct inode *inode, loff_t size)
Exfat_super.c: struct address_space *mapping = inode->i_mapping;
Exfat_super.c: loff_t start = i_size_read(inode), count = size - i_size_read(inode);
Exfat_super.c: err = generic_cont_expand_simple(inode, size);
Exfat_super.c: inode->i_ctime = inode->i_mtime = current_time(inode);
Exfat_super.c: mark_inode_dirty(inode);
Exfat_super.c: if (IS_SYNC(inode)) {
Exfat_super.c: err2 = write_inode_now(inode, 1);
Exfat_super.c:static int exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode)
Exfat_super.c: if (!uid_eq(current_fsuid(), inode->i_uid))
Exfat_super.c: if (current_fsuid() != inode->i_uid)
Exfat_super.c: if (in_group_p(inode->i_gid))
Exfat_super.c: struct inode *inode, umode_t *mode_ptr)
Exfat_super.c: i_mode = inode->i_mode;
Exfat_super.c: if (exfat_mode_can_hold_ro(inode)) {
Exfat_super.c: /* If exfat_mode_can_hold_ro(inode) is false, can't change w bits. */
Exfat_super.c: struct inode *inode = dentry->d_inode;
Exfat_super.c: && (attr->ia_size > i_size_read(inode))) {
Exfat_super.c: error = exfat_cont_expand(inode, attr->ia_size);
Exfat_super.c: && exfat_allow_set_time(sbi, inode)) {
Exfat_super.c: error = inode_change_ok(inode, attr);
Exfat_super.c: if (exfat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0)
Exfat_super.c: EXFAT_I(inode)->fid.size = i_size_read(inode);
Exfat_super.c: error = inode_setattr(inode, attr);
Exfat_super.c: old_size = i_size_read(inode);
Exfat_super.c: down_write(&EXFAT_I(inode)->truncate_lock);
Exfat_super.c: truncate_setsize(inode, attr->ia_size);
Exfat_super.c: _exfat_truncate(inode, old_size);
Exfat_super.c: up_write(&EXFAT_I(inode)->truncate_lock);
Exfat_super.c: truncate_setsize(inode, attr->ia_size);
Exfat_super.c: _exfat_truncate(inode, old_size);
Exfat_super.c: setattr_copy(inode, attr);
Exfat_super.c: mark_inode_dirty(inode);
Exfat_super.c: struct inode *inode = path->dentry->d_inode;
Exfat_super.c: struct inode *inode = dentry->d_inode;
Exfat_super.c: generic_fillattr(inode, stat);
Exfat_super.c: stat->blksize = EXFAT_SB(inode->i_sb)->fs_info.cluster_size;
Exfat_super.c:static const char *exfat_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done)
Exfat_super.c: struct exfat_inode_info *ei = EXFAT_I(inode);
Exfat_super.c:static int exfat_file_release(struct inode *inode, struct file *filp)
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: EXFAT_I(inode)->fid.size = i_size_read(inode);
Exfat_super.c:static void _exfat_truncate(struct inode *inode, loff_t old_size)
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: if (EXFAT_I(inode)->mmu_private > i_size_read(inode))
Exfat_super.c: EXFAT_I(inode)->mmu_private = i_size_read(inode);
Exfat_super.c: if (EXFAT_I(inode)->fid.start_clu == 0)
Exfat_super.c: err = FsTruncateFile(inode, old_size, i_size_read(inode));
Exfat_super.c: inode->i_ctime = inode->i_mtime = current_time(inode);
Exfat_super.c: if (IS_DIRSYNC(inode))
Exfat_super.c: (void) exfat_sync_inode(inode);
Exfat_super.c: mark_inode_dirty(inode);
Exfat_super.c: inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1))
Exfat_super.c:static void exfat_truncate(struct inode *inode)
Exfat_super.c: _exfat_truncate(inode, i_size_read(inode));
Exfat_super.c:static int exfat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: if (inode->i_ino == EXFAT_ROOT_INO) {
Exfat_super.c: last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits;
Exfat_super.c: EXFAT_I(inode)->fid.size = i_size_read(inode);
Exfat_super.c: err = FsMapCluster(inode, clu_offset, &cluster);
Exfat_super.c:static int exfat_get_block(struct inode *inode, sector_t iblock,
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
Exfat_super.c: err = exfat_bmap(inode, iblock, &phys, &mapped_blocks, &create);
Exfat_super.c: EXFAT_I(inode)->mmu_private += max_blocks << sb->s_blocksize_bits;
Exfat_super.c: struct inode *inode = mapping->host;
Exfat_super.c: if (to > i_size_read(inode)) {
Exfat_super.c: truncate_pagecache(inode, i_size_read(inode));
Exfat_super.c: truncate_pagecache(inode, to, i_size_read(inode));
Exfat_super.c: EXFAT_I(inode)->fid.size = i_size_read(inode);
Exfat_super.c: _exfat_truncate(inode, i_size_read(inode));
Exfat_super.c: struct inode *inode = mapping->host;
Exfat_super.c: FILE_ID_T *fid = &(EXFAT_I(inode)->fid);
Exfat_super.c: inode->i_mtime = inode->i_ctime = current_time(inode);
Exfat_super.c: mark_inode_dirty(inode);
Exfat_super.c: struct inode *inode = iocb->ki_filp->f_mapping->host;
Exfat_super.c: if (EXFAT_I(inode)->mmu_private <
Exfat_super.c: if (EXFAT_I(inode)->mmu_private < (offset + iov_length(iov, nr_segs)))
Exfat_super.c: if (EXFAT_I(inode)->mmu_private < (offset + iov_iter_count(iter)))
Exfat_super.c: if (EXFAT_I(inode)->mmu_private < iov_iter_count(iter))
Exfat_super.c: ret = blockdev_direct_IO(iocb, inode, iter, exfat_get_block);
Exfat_super.c: ret = blockdev_direct_IO(iocb, inode, iter,
Exfat_super.c: ret = blockdev_direct_IO(rw, iocb, inode, iter,
Exfat_super.c: ret = blockdev_direct_IO(rw, iocb, inode, iter,
Exfat_super.c: ret = blockdev_direct_IO(rw, iocb, inode, iov,
Exfat_super.c: ret = blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev, iov,
Exfat_super.c:static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos)
Exfat_super.c: struct inode *inode = NULL;
Exfat_super.c: inode = igrab(&info->vfs_inode);
Exfat_super.c: if (inode)
Exfat_super.c: return inode;
Exfat_super.c:static void exfat_attach(struct inode *inode, loff_t i_pos)
Exfat_super.c: struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
Exfat_super.c: EXFAT_I(inode)->i_pos = i_pos;
Exfat_super.c: hlist_add_head(&EXFAT_I(inode)->i_hash_fat, head);
Exfat_super.c:static void exfat_detach(struct inode *inode)
Exfat_super.c: struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
Exfat_super.c: hlist_del_init(&EXFAT_I(inode)->i_hash_fat);
Exfat_super.c: EXFAT_I(inode)->i_pos = 0;
Exfat_super.c:/* doesn't deal with root inode */
Exfat_super.c:static int exfat_fill_inode(struct inode *inode, FILE_ID_T *fid)
Exfat_super.c: struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
Exfat_super.c: memcpy(&(EXFAT_I(inode)->fid), fid, sizeof(FILE_ID_T));
Exfat_super.c: FsReadStat(inode, &info);
Exfat_super.c: EXFAT_I(inode)->i_pos = 0;
Exfat_super.c: EXFAT_I(inode)->target = NULL;
Exfat_super.c: inode->i_uid = sbi->options.fs_uid;
Exfat_super.c: inode->i_gid = sbi->options.fs_gid;
Exfat_super.c: INC_IVERSION(inode);
Exfat_super.c: inode->i_generation = get_seconds();
Exfat_super.c: inode->i_generation &= ~1;
Exfat_super.c: inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO);
Exfat_super.c: inode->i_op = &exfat_dir_inode_operations;
Exfat_super.c: inode->i_fop = &exfat_dir_operations;
Exfat_super.c: i_size_write(inode, info.Size);
Exfat_super.c: EXFAT_I(inode)->mmu_private = i_size_read(inode);
Exfat_super.c: set_nlink(inode, info.NumSubdirs);
Exfat_super.c: inode->i_nlink = info.NumSubdirs;
Exfat_super.c: inode->i_generation |= 1;
Exfat_super.c: inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO);
Exfat_super.c: inode->i_op = &exfat_symlink_inode_operations;
Exfat_super.c: i_size_write(inode, info.Size);
Exfat_super.c: EXFAT_I(inode)->mmu_private = i_size_read(inode);
Exfat_super.c: inode->i_generation |= 1;
Exfat_super.c: inode->i_mode = exfat_make_mode(sbi, info.Attr, S_IRWXUGO);
Exfat_super.c: inode->i_op = &exfat_file_inode_operations;
Exfat_super.c: inode->i_fop = &exfat_file_operations;
Exfat_super.c: inode->i_mapping->a_ops = &exfat_aops;
Exfat_super.c: inode->i_mapping->nrpages = 0;
Exfat_super.c: i_size_write(inode, info.Size);
Exfat_super.c: EXFAT_I(inode)->mmu_private = i_size_read(inode);
Exfat_super.c: exfat_save_attr(inode, info.Attr);
Exfat_super.c: inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1))
Exfat_super.c: exfat_time_fat2unix(sbi, &inode->i_mtime, &info.ModifyTimestamp);
Exfat_super.c: exfat_time_fat2unix(sbi, &inode->i_ctime, &info.CreateTimestamp);
Exfat_super.c: exfat_time_fat2unix(sbi, &inode->i_atime, &info.AccessTimestamp);
Exfat_super.c:static struct inode *exfat_build_inode(struct super_block *sb,
Exfat_super.c: struct inode *inode;
Exfat_super.c: inode = exfat_iget(sb, i_pos);
Exfat_super.c: if (inode)
Exfat_super.c: inode = new_inode(sb);
Exfat_super.c: if (!inode) {
Exfat_super.c: inode = ERR_PTR(-ENOMEM);
Exfat_super.c: inode->i_ino = iunique(sb, EXFAT_ROOT_INO);
Exfat_super.c: SET_IVERSION(inode, 1);
Exfat_super.c: err = exfat_fill_inode(inode, fid);
Exfat_super.c: iput(inode);
Exfat_super.c: inode = ERR_PTR(err);
Exfat_super.c: exfat_attach(inode, i_pos);
Exfat_super.c: insert_inode_hash(inode);
Exfat_super.c: return inode;
Exfat_super.c:static int exfat_sync_inode(struct inode *inode)
Exfat_super.c: return exfat_write_inode(inode, 0);
Exfat_super.c: return exfat_write_inode(inode, NULL);
Exfat_super.c:static struct inode *exfat_alloc_inode(struct super_block *sb)
Exfat_super.c:static void exfat_destroy_inode(struct inode *inode)
Exfat_super.c: if (EXFAT_I(inode)->target)
Exfat_super.c: kfree(EXFAT_I(inode)->target);
Exfat_super.c: EXFAT_I(inode)->target = NULL;
Exfat_super.c: kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode));
Exfat_super.c:static int exfat_write_inode(struct inode *inode, int wait)
Exfat_super.c:static int exfat_write_inode(struct inode *inode, struct writeback_control *wbc)
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: if (inode->i_ino == EXFAT_ROOT_INO)
Exfat_super.c: info.Attr = exfat_make_attr(inode);
Exfat_super.c: info.Size = i_size_read(inode);
Exfat_super.c: exfat_time_unix2fat(sbi, &inode->i_mtime, &info.ModifyTimestamp);
Exfat_super.c: exfat_time_unix2fat(sbi, &inode->i_ctime, &info.CreateTimestamp);
Exfat_super.c: exfat_time_unix2fat(sbi, &inode->i_atime, &info.AccessTimestamp);
Exfat_super.c: FsWriteStat(inode, &info);
Exfat_super.c:static void exfat_delete_inode(struct inode *inode)
Exfat_super.c: truncate_inode_pages(&inode->i_data, 0);
Exfat_super.c: clear_inode(inode);
Exfat_super.c:static void exfat_clear_inode(struct inode *inode)
Exfat_super.c: exfat_detach(inode);
Exfat_super.c: remove_inode_hash(inode);
Exfat_super.c:static void exfat_evict_inode(struct inode *inode)
Exfat_super.c: truncate_inode_pages(&inode->i_data, 0);
Exfat_super.c: if (!inode->i_nlink)
Exfat_super.c: i_size_write(inode, 0);
Exfat_super.c: invalidate_inode_buffers(inode);
Exfat_super.c: end_writeback(inode);
Exfat_super.c: clear_inode(inode);
Exfat_super.c: exfat_detach(inode);
Exfat_super.c: remove_inode_hash(inode);
Exfat_super.c:static struct inode *exfat_nfs_get_inode(struct super_block *sb,
Exfat_super.c: struct inode *inode = NULL;
Exfat_super.c: return inode;
Exfat_super.c: inode = ilookup(sb, ino);
Exfat_super.c: if (inode && generation && (inode->i_generation != generation)) {
Exfat_super.c: iput(inode);
Exfat_super.c: inode = NULL;
Exfat_super.c: return inode;
Exfat_super.c:static int exfat_read_root(struct inode *inode)
Exfat_super.c: struct super_block *sb = inode->i_sb;
Exfat_super.c: EXFAT_I(inode)->fid.dir.dir = p_fs->root_dir;
Exfat_super.c: EXFAT_I(inode)->fid.dir.flags = 0x01;
Exfat_super.c: EXFAT_I(inode)->fid.entry = -1;
Exfat_super.c: EXFAT_I(inode)->fid.start_clu = p_fs->root_dir;
Exfat_super.c: EXFAT_I(inode)->fid.flags = 0x01;
Exfat_super.c: EXFAT_I(inode)->fid.type = TYPE_DIR;
Exfat_super.c: EXFAT_I(inode)->fid.rwoffset = 0;
Exfat_super.c: EXFAT_I(inode)->fid.hint_last_off = -1;
Exfat_super.c: EXFAT_I(inode)->target = NULL;
Exfat_super.c: FsReadStat(inode, &info);
Exfat_super.c: inode->i_uid = sbi->options.fs_uid;
Exfat_super.c: inode->i_gid = sbi->options.fs_gid;
Exfat_super.c: INC_IVERSION(inode);
Exfat_super.c: inode->i_generation = 0;
Exfat_super.c: inode->i_mode = exfat_make_mode(sbi, ATTR_SUBDIR, S_IRWXUGO);
Exfat_super.c: inode->i_op = &exfat_dir_inode_operations;
Exfat_super.c: inode->i_fop = &exfat_dir_operations;
Exfat_super.c: i_size_write(inode, info.Size);
Exfat_super.c: inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1))
Exfat_super.c: EXFAT_I(inode)->i_pos = ((loff_t) p_fs->root_dir << 32) | 0xffffffff;
Exfat_super.c: EXFAT_I(inode)->mmu_private = i_size_read(inode);
Exfat_super.c: exfat_save_attr(inode, ATTR_SUBDIR);
Exfat_super.c: inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
Exfat_super.c: set_nlink(inode, info.NumSubdirs + 2);
Exfat_super.c: inode->i_nlink = info.NumSubdirs + 2;
Exfat_super.c: struct inode *root_inode = NULL;
Exfat_super.c: /* set up enough so that it can read an inode */
Exfat_super.c: printk(KERN_ERR "[EXFAT] Getting the root inode failed\n");
Exfat_super.h: struct inode *fat_inode;
Exfat_super.h: * EXFAT file system inode data in memory
Exfat_super.h: struct inode vfs_inode;
Exfat_super.h:static inline struct exfat_inode_info *EXFAT_I(struct inode *inode)
Exfat_super.h: return container_of(inode, struct exfat_inode_info, vfs_inode);
Exfat_super.h:static inline int exfat_mode_can_hold_ro(struct inode *inode)
Exfat_super.h: struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
Exfat_super.h: if (S_ISDIR(inode->i_mode))
Exfat_super.h:/* Return the FAT attribute byte for this inode */
Exfat_super.h:static inline u32 exfat_make_attr(struct inode *inode)
Exfat_super.h: if (exfat_mode_can_hold_ro(inode) && !(inode->i_mode & S_IWUGO))
Exfat_super.h: return (EXFAT_I(inode)->fid.attr) | ATTR_READONLY;
Exfat_super.h: return EXFAT_I(inode)->fid.attr;
Exfat_super.h:static inline void exfat_save_attr(struct inode *inode, u32 attr)
Exfat_super.h: if (exfat_mode_can_hold_ro(inode))
Exfat_super.h: EXFAT_I(inode)->fid.attr = attr & ATTR_RWMASK;
Exfat_super.h: EXFAT_I(inode)->fid.attr = attr & (ATTR_RWMASK | ATTR_READONLY);

Binary file not shown.

View File

@ -0,0 +1,7 @@
PACKAGE_NAME="exfat"
PACKAGE_VERSION="1.2.8"
MAKE="KDIR=/lib/modules/$kernelver/build MDIR=/lib/modules/$kernelver make"
CLEAN="make clean"
BUILT_MODULE_NAME[0]="exfat"
AUTOINSTALL="yes"
DEST_MODULE_LOCATION="/extra"

View File

@ -0,0 +1,11 @@
EXFAT_FOLDER ?= external/exfat-nofuse
EXFAT_MODULE:
make clean -C $(EXFAT_FOLDER) KDIR=$(KERNEL_OUT)
make -j8 -C $(EXFAT_FOLDER) ARCH=arm KDIR=$(KERNEL_OUT) \
$(if $(ARM_CROSS_COMPILE),$(ARM_CROSS_COMPILE),$(KERNEL_CROSS_COMPILE))
mv $(EXFAT_FOLDER)/exfat.ko $(KERNEL_MODULES_OUT)
$(if $(ARM_EABI_TOOLCHAIN),$(ARM_EABI_TOOLCHAIN)/arm-eabi-strip, \
$(KERNEL_TOOLCHAIN_PATH)strip) --strip-unneeded $(KERNEL_MODULES_OUT)/exfat.ko
TARGET_KERNEL_MODULES += EXFAT_MODULE

View File

@ -0,0 +1,528 @@
/*
* 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_data.h"
#include "exfat_oal.h"
#include "exfat_nls.h"
#include "exfat_api.h"
#include "exfat_super.h"
#include "exfat_core.h"
/*----------------------------------------------------------------------*/
/* Constant & Macro Definitions */
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* Global Variable Definitions */
/*----------------------------------------------------------------------*/
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 */
/*----------------------------------------------------------------------*/
int FsInit(void)
{
return ffsInit();
}
int FsShutdown(void)
{
return ffsShutdown();
}
/*----------------------------------------------------------------------*/
/* Volume Management Functions */
/*----------------------------------------------------------------------*/
/* FsMountVol : mount the file system volume */
int FsMountVol(struct super_block *sb)
{
int err;
sm_P(&z_sem);
err = buf_init(sb);
if (!err)
err = ffsMountVol(sb);
else
buf_shutdown(sb);
sm_V(&z_sem);
return err;
} /* end of FsMountVol */
/* FsUmountVol : unmount the file system volume */
int FsUmountVol(struct super_block *sb)
{
int 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(&p_fs->v_sem);
err = ffsUmountVol(sb);
buf_shutdown(sb);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
sm_V(&z_sem);
return err;
} /* end of FsUmountVol */
/* FsGetVolInfo : get the information of a file system volume */
int FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info)
{
int 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(&p_fs->v_sem);
err = ffsGetVolInfo(sb, info);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsGetVolInfo */
/* FsSyncVol : synchronize a file system volume */
int FsSyncVol(struct super_block *sb, int do_sync)
{
int err;
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
/* acquire the lock for file system critical section */
sm_P(&p_fs->v_sem);
err = ffsSyncVol(sb, do_sync);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsSyncVol */
/*----------------------------------------------------------------------*/
/* File Operation Functions */
/*----------------------------------------------------------------------*/
/* FsCreateFile : create a file */
int FsLookupFile(struct inode *inode, char *path, FILE_ID_T *fid)
{
int 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(&p_fs->v_sem);
err = ffsLookupFile(inode, path, fid);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsLookupFile */
/* FsCreateFile : create a file */
int FsCreateFile(struct inode *inode, char *path, u8 mode, FILE_ID_T *fid)
{
int 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(&p_fs->v_sem);
err = ffsCreateFile(inode, path, mode, fid);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsCreateFile */
int FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount)
{
int 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(&p_fs->v_sem);
err = ffsReadFile(inode, fid, buffer, count, rcount);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsReadFile */
int FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount)
{
int 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(&p_fs->v_sem);
err = ffsWriteFile(inode, fid, buffer, count, wcount);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsWriteFile */
/* FsTruncateFile : resize the file length */
int FsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
{
int 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(&p_fs->v_sem);
DPRINTK("FsTruncateFile entered (inode %p size %llu)\n", inode, new_size);
err = ffsTruncateFile(inode, old_size, new_size);
DPRINTK("FsTruncateFile exitted (%d)\n", err);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsTruncateFile */
/* FsMoveFile : move(rename) a old file into a new file */
int FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry)
{
int 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(&p_fs->v_sem);
err = ffsMoveFile(old_parent_inode, fid, new_parent_inode, new_dentry);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsMoveFile */
/* FsRemoveFile : remove a file */
int FsRemoveFile(struct inode *inode, FILE_ID_T *fid)
{
int 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(&p_fs->v_sem);
err = ffsRemoveFile(inode, fid);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsRemoveFile */
/* FsSetAttr : set the attribute of a given file */
int FsSetAttr(struct inode *inode, u32 attr)
{
int 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(&p_fs->v_sem);
err = ffsSetAttr(inode, attr);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsSetAttr */
/* FsReadStat : get the information of a given file */
int FsReadStat(struct inode *inode, DIR_ENTRY_T *info)
{
int 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(&p_fs->v_sem);
err = ffsGetStat(inode, info);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsReadStat */
/* FsWriteStat : set the information of a given file */
int FsWriteStat(struct inode *inode, DIR_ENTRY_T *info)
{
int 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(&p_fs->v_sem);
DPRINTK("FsWriteStat entered (inode %p info %p\n", inode, info);
err = ffsSetStat(inode, info);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
DPRINTK("FsWriteStat exited (%d)\n", err);
return err;
} /* end of FsWriteStat */
/* FsMapCluster : return the cluster number in the given cluster offset */
int FsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
{
int 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(&p_fs->v_sem);
err = ffsMapCluster(inode, clu_offset, clu);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsMapCluster */
/*----------------------------------------------------------------------*/
/* Directory Operation Functions */
/*----------------------------------------------------------------------*/
/* FsCreateDir : create(make) a directory */
int FsCreateDir(struct inode *inode, char *path, FILE_ID_T *fid)
{
int 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(&p_fs->v_sem);
err = ffsCreateDir(inode, path, fid);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsCreateDir */
/* FsReadDir : read a directory entry from the opened directory */
int FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry)
{
int 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(&p_fs->v_sem);
err = ffsReadDir(inode, dir_entry);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return err;
} /* end of FsReadDir */
/* FsRemoveDir : remove a directory */
int FsRemoveDir(struct inode *inode, FILE_ID_T *fid)
{
int 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(&p_fs->v_sem);
err = ffsRemoveDir(inode, fid);
/* release the lock for file system critical section */
sm_V(&p_fs->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);
#ifdef CONFIG_EXFAT_KERNEL_DEBUG
/* FsReleaseCache: Release FAT & buf cache */
int 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(&p_fs->v_sem);
FAT_release_all(sb);
buf_release_all(sb);
/* release the lock for file system critical section */
sm_V(&p_fs->v_sem);
return 0;
}
/* FsReleaseCache */
EXPORT_SYMBOL(FsReleaseCache);
#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
/*======================================================================*/
/* Local Function Definitions */
/*======================================================================*/

View File

@ -0,0 +1,206 @@
/*
* 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 <linux/fs.h>
#include "exfat_config.h"
/*----------------------------------------------------------------------*/
/* 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
/*----------------------------------------------------------------------*/
/* Type Definitions */
/*----------------------------------------------------------------------*/
typedef struct {
u16 Year;
u16 Month;
u16 Day;
u16 Hour;
u16 Minute;
u16 Second;
u16 MilliSecond;
} DATE_TIME_T;
typedef struct {
u32 Offset; /* start sector number of the partition */
u32 Size; /* in sectors */
} PART_INFO_T;
typedef struct {
u32 SecSize; /* sector size in bytes */
u32 DevSize; /* block device size in sectors */
} DEV_INFO_T;
typedef struct {
u32 FatType;
u32 ClusterSize;
u32 NumClusters;
u32 FreeClusters;
u32 UsedClusters;
} VOL_INFO_T;
/* directory structure */
typedef struct {
u32 dir;
s32 size;
u8 flags;
} CHAIN_T;
/* file id structure */
typedef struct {
CHAIN_T dir;
s32 entry;
u32 type;
u32 attr;
u32 start_clu;
u64 size;
u8 flags;
s64 rwoffset;
s32 hint_last_off;
u32 hint_last_clu;
} FILE_ID_T;
typedef struct {
char Name[MAX_NAME_LENGTH * MAX_CHARSET_SIZE];
char ShortName[DOS_NAME_LENGTH + 2]; /* used only for FAT12/16/32, not used for exFAT */
u32 Attr;
u64 Size;
u32 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 */
int FsInit(void);
int FsShutdown(void);
/* volume management functions */
int FsMountVol(struct super_block *sb);
int FsUmountVol(struct super_block *sb);
int FsGetVolInfo(struct super_block *sb, VOL_INFO_T *info);
int FsSyncVol(struct super_block *sb, int do_sync);
/* file management functions */
int FsLookupFile(struct inode *inode, char *path, FILE_ID_T *fid);
int FsCreateFile(struct inode *inode, char *path, u8 mode, FILE_ID_T *fid);
int FsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount);
int FsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount);
int FsTruncateFile(struct inode *inode, u64 old_size, u64 new_size);
int FsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry);
int FsRemoveFile(struct inode *inode, FILE_ID_T *fid);
int FsSetAttr(struct inode *inode, u32 attr);
int FsReadStat(struct inode *inode, DIR_ENTRY_T *info);
int FsWriteStat(struct inode *inode, DIR_ENTRY_T *info);
int FsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu);
/* directory management functions */
int FsCreateDir(struct inode *inode, char *path, FILE_ID_T *fid);
int FsReadDir(struct inode *inode, DIR_ENTRY_T *dir_entry);
int FsRemoveDir(struct inode *inode, FILE_ID_T *fid);
/* debug functions */
s32 FsReleaseCache(struct super_block *sb);
#endif /* _EXFAT_API_H */

View File

@ -0,0 +1,63 @@
/*
* 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_bitmap.h"
/*----------------------------------------------------------------------*/
/* Bitmap Manipulation Functions */
/*----------------------------------------------------------------------*/
#define BITMAP_LOC(v) ((v) >> 3)
#define BITMAP_SHIFT(v) ((v) & 0x07)
s32 exfat_bitmap_test(u8 *bitmap, int i)
{
u8 data;
data = bitmap[BITMAP_LOC(i)];
if ((data >> BITMAP_SHIFT(i)) & 0x01)
return 1;
return 0;
} /* end of Bitmap_test */
void exfat_bitmap_set(u8 *bitmap, int i)
{
bitmap[BITMAP_LOC(i)] |= (0x01 << BITMAP_SHIFT(i));
} /* end of Bitmap_set */
void exfat_bitmap_clear(u8 *bitmap, int i)
{
bitmap[BITMAP_LOC(i)] &= ~(0x01 << BITMAP_SHIFT(i));
} /* end of Bitmap_clear */

View File

@ -0,0 +1,55 @@
/*
* 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_BITMAP_H
#define _EXFAT_BITMAP_H
#include <linux/types.h>
/*======================================================================*/
/* */
/* LIBRARY FUNCTION DECLARATIONS -- OTHER UTILITY FUNCTIONS */
/* (DO NOT CHANGE THIS PART !!) */
/* */
/*======================================================================*/
/*----------------------------------------------------------------------*/
/* Bitmap Manipulation Functions */
/*----------------------------------------------------------------------*/
s32 exfat_bitmap_test(u8 *bitmap, int i);
void exfat_bitmap_set(u8 *bitmap, int i);
void exfat_bitmap_clear(u8 *bitmpa, int i);
#endif /* _EXFAT_BITMAP_H */

View File

@ -0,0 +1,197 @@
/*
* 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 <linux/log2.h>
#include "exfat_config.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 */
/*======================================================================*/
s32 bdev_init(void)
{
return FFS_SUCCESS;
}
s32 bdev_shutdown(void)
{
return FFS_SUCCESS;
}
s32 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 = ilog2(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;
}
s32 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;
}
s32 bdev_read(struct super_block *sb, sector_t secno, struct buffer_head **bh, u32 num_secs, s32 read)
{
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
#ifdef CONFIG_EXFAT_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 /* CONFIG_EXFAT_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;
}
s32 bdev_write(struct super_block *sb, sector_t secno, struct buffer_head *bh, u32 num_secs, s32 sync)
{
s32 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);
#ifdef CONFIG_EXFAT_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 /* CONFIG_EXFAT_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;
}
s32 bdev_sync(struct super_block *sb)
{
BD_INFO_T *p_bd = &(EXFAT_SB(sb)->bd_info);
#ifdef CONFIG_EXFAT_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 /* CONFIG_EXFAT_KERNEL_DEBUG */
if (!p_bd->opened)
return FFS_MEDIAERR;
return sync_blockdev(sb->s_bdev);
}

View File

@ -0,0 +1,73 @@
/*
* 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 <linux/fs.h>
#include "exfat_config.h"
/*----------------------------------------------------------------------*/
/* Constant & Macro Definitions (Non-Configurable) */
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* Type Definitions */
/*----------------------------------------------------------------------*/
typedef struct __BD_INFO_T {
s32 sector_size; /* in bytes */
s32 sector_size_bits;
s32 sector_size_mask;
s32 num_sectors; /* total number of sectors in this block device */
bool opened; /* opened or not */
} BD_INFO_T;
/*----------------------------------------------------------------------*/
/* External Variable Declarations */
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* External Function Declarations */
/*----------------------------------------------------------------------*/
s32 bdev_init(void);
s32 bdev_shutdown(void);
s32 bdev_open(struct super_block *sb);
s32 bdev_close(struct super_block *sb);
s32 bdev_read(struct super_block *sb, sector_t secno, struct buffer_head **bh, u32 num_secs, s32 read);
s32 bdev_write(struct super_block *sb, sector_t secno, struct buffer_head *bh, u32 num_secs, s32 sync);
s32 bdev_sync(struct super_block *sb);
#endif /* _EXFAT_BLKDEV_H */

View File

@ -0,0 +1,784 @@
/*
* 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_data.h"
#include "exfat_cache.h"
#include "exfat_super.h"
#include "exfat_core.h"
/*----------------------------------------------------------------------*/
/* Global Variable Definitions */
/*----------------------------------------------------------------------*/
#define sm_P(s)
#define sm_V(s)
static s32 __FAT_read(struct super_block *sb, u32 loc, u32 *content);
static s32 __FAT_write(struct super_block *sb, u32 loc, u32 content);
static BUF_CACHE_T *FAT_cache_find(struct super_block *sb, sector_t sec);
static BUF_CACHE_T *FAT_cache_get(struct super_block *sb, sector_t 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 u8 *__buf_getblk(struct super_block *sb, sector_t sec);
static BUF_CACHE_T *buf_cache_find(struct super_block *sb, sector_t sec);
static BUF_CACHE_T *buf_cache_get(struct super_block *sb, sector_t 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 */
/*======================================================================*/
s32 buf_init(struct super_block *sb)
{
FS_INFO_T *p_fs = &(EXFAT_SB(sb)->fs_info);
int 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 */
s32 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
*/
s32 FAT_read(struct super_block *sb, u32 loc, u32 *content)
{
s32 ret;
sm_P(&f_sem);
ret = __FAT_read(sb, loc, content);
sm_V(&f_sem);
return ret;
} /* end of FAT_read */
s32 FAT_write(struct super_block *sb, u32 loc, u32 content)
{
s32 ret;
sm_P(&f_sem);
ret = __FAT_write(sb, loc, content);
sm_V(&f_sem);
return ret;
} /* end of FAT_write */
static s32 __FAT_read(struct super_block *sb, u32 loc, u32 *content)
{
s32 off;
u32 _content;
sector_t sec;
u8 *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 = (u32) fat_sector[off];
fat_sector = FAT_getblk(sb, ++sec);
if (!fat_sector)
return -1;
_content |= (u32) 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 s32 __FAT_write(struct super_block *sb, u32 loc, u32 content)
{
s32 off;
sector_t sec;
u8 *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] = (u8)(content | (fat_sector[off] & 0x0F));
FAT_modify(sb, sec);
fat_sector = FAT_getblk(sb, ++sec);
if (!fat_sector)
return -1;
fat_sector[0] = (u8)(content >> 8);
} else {
fat_entry = &(fat_sector[off]);
content |= GET16(fat_entry) & 0x000F;
SET16(fat_entry, content);
}
} else { /* even */
fat_sector[off] = (u8)(content);
if (off == (p_bd->sector_size-1)) {
fat_sector[off] = (u8)(content);
FAT_modify(sb, sec);
fat_sector = FAT_getblk(sb, ++sec);
fat_sector[0] = (u8)((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 */
u8 *FAT_getblk(struct super_block *sb, sector_t 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, sector_t 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, sector_t sec)
{
s32 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, sector_t 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)
{
s32 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 */
/*======================================================================*/
u8 *buf_getblk(struct super_block *sb, sector_t sec)
{
u8 *buf;
sm_P(&b_sem);
buf = __buf_getblk(sb, sec);
sm_V(&b_sem);
return buf;
} /* end of buf_getblk */
static u8 *__buf_getblk(struct super_block *sb, sector_t 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, sector_t 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:%llu).\n",
(unsigned long long)sec);
sm_V(&b_sem);
} /* end of buf_modify */
void buf_lock(struct super_block *sb, sector_t 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:%llu).\n",
(unsigned long long)sec);
sm_V(&b_sem);
} /* end of buf_lock */
void buf_unlock(struct super_block *sb, sector_t 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:%llu).\n",
(unsigned long long)sec);
sm_V(&b_sem);
} /* end of buf_unlock */
void buf_release(struct super_block *sb, sector_t 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, sector_t sec)
{
s32 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, sector_t 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)
{
s32 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 */

View File

@ -0,0 +1,85 @@
/*
* 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 <linux/fs.h>
#include <linux/types.h>
#include "exfat_config.h"
/*----------------------------------------------------------------------*/
/* 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;
s32 drv;
sector_t sec;
u32 flag;
struct buffer_head *buf_bh;
} BUF_CACHE_T;
/*----------------------------------------------------------------------*/
/* External Function Declarations */
/*----------------------------------------------------------------------*/
s32 buf_init(struct super_block *sb);
s32 buf_shutdown(struct super_block *sb);
s32 FAT_read(struct super_block *sb, u32 loc, u32 *content);
s32 FAT_write(struct super_block *sb, u32 loc, u32 content);
u8 *FAT_getblk(struct super_block *sb, sector_t sec);
void FAT_modify(struct super_block *sb, sector_t sec);
void FAT_release_all(struct super_block *sb);
void FAT_sync(struct super_block *sb);
u8 *buf_getblk(struct super_block *sb, sector_t sec);
void buf_modify(struct super_block *sb, sector_t sec);
void buf_lock(struct super_block *sb, sector_t sec);
void buf_unlock(struct super_block *sb, sector_t sec);
void buf_release(struct super_block *sb, sector_t sec);
void buf_release_all(struct super_block *sb);
void buf_sync(struct super_block *sb);
#endif /* _EXFAT_CACHE_H */

View File

@ -0,0 +1,69 @@
/*
* 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
/*======================================================================*/
/* */
/* FFS CONFIGURATIONS */
/* (CHANGE THIS PART IF REQUIRED) */
/* */
/*======================================================================*/
/*----------------------------------------------------------------------*/
/* Feature Config */
/*----------------------------------------------------------------------*/
#ifndef CONFIG_EXFAT_DISCARD
#define CONFIG_EXFAT_DISCARD 1 /* mount option -o discard support */
#endif
#ifndef CONFIG_EXFAT_DELAYED_SYNC
#define CONFIG_EXFAT_DELAYED_SYNC 0
#endif
#ifndef CONFIG_EXFAT_KERNEL_DEBUG
#define CONFIG_EXFAT_KERNEL_DEBUG 1 /* kernel debug features via ioctl */
#endif
#ifndef CONFIG_EXFAT_DEBUG_MSG
#define CONFIG_EXFAT_DEBUG_MSG 0 /* debugging message on/off */
#endif
#ifndef CONFIG_EXFAT_DEFAULT_CODEPAGE
#define CONFIG_EXFAT_DEFAULT_CODEPAGE 437
#define CONFIG_EXFAT_DEFAULT_IOCHARSET "utf8"
#endif
#endif /* _EXFAT_CONFIG_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,671 @@
/*
* 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_core.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_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 CONFIG_EXFAT_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 /* CONFIG_EXFAT_KERNEL_DEBUG */
/*----------------------------------------------------------------------*/
/* Constant & Macro Definitions */
/*----------------------------------------------------------------------*/
#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) ((u16)(x))
#define CLUSTER_32(x) ((u32)(x))
#define FALSE 0
#define TRUE 1
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define START_SECTOR(x) \
((((sector_t)((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) \
((u32)((((sec) - p_fs->data_start_sector) >> p_fs->sectors_per_clu_bits) + 2))
#define GET16(p_src) \
(((u16)(p_src)[0]) | (((u16)(p_src)[1]) << 8))
#define GET32(p_src) \
(((u32)(p_src)[0]) | (((u32)(p_src)[1]) << 8) | \
(((u32)(p_src)[2]) << 16) | (((u32)(p_src)[3]) << 24))
#define GET64(p_src) \
(((u64)(p_src)[0]) | (((u64)(p_src)[1]) << 8) | \
(((u64)(p_src)[2]) << 16) | (((u64)(p_src)[3]) << 24) | \
(((u64)(p_src)[4]) << 32) | (((u64)(p_src)[5]) << 40) | \
(((u64)(p_src)[6]) << 48) | (((u64)(p_src)[7]) << 56))
#define SET16(p_dst, src) \
do { \
(p_dst)[0] = (u8)(src); \
(p_dst)[1] = (u8)(((u16)(src)) >> 8); \
} while (0)
#define SET32(p_dst, src) \
do { \
(p_dst)[0] = (u8)(src); \
(p_dst)[1] = (u8)(((u32)(src)) >> 8); \
(p_dst)[2] = (u8)(((u32)(src)) >> 16); \
(p_dst)[3] = (u8)(((u32)(src)) >> 24); \
} while (0)
#define SET64(p_dst, src) \
do { \
(p_dst)[0] = (u8)(src); \
(p_dst)[1] = (u8)(((u64)(src)) >> 8); \
(p_dst)[2] = (u8)(((u64)(src)) >> 16); \
(p_dst)[3] = (u8)(((u64)(src)) >> 24); \
(p_dst)[4] = (u8)(((u64)(src)) >> 32); \
(p_dst)[5] = (u8)(((u64)(src)) >> 40); \
(p_dst)[6] = (u8)(((u64)(src)) >> 48); \
(p_dst)[7] = (u8)(((u64)(src)) >> 56); \
} while (0)
#ifdef __LITTLE_ENDIAN
#define GET16_A(p_src) (*((u16 *)(p_src)))
#define GET32_A(p_src) (*((u32 *)(p_src)))
#define GET64_A(p_src) (*((u64 *)(p_src)))
#define SET16_A(p_dst, src) (*((u16 *)(p_dst)) = (u16)(src))
#define SET32_A(p_dst, src) (*((u32 *)(p_dst)) = (u32)(src))
#define SET64_A(p_dst, src) (*((u64 *)(p_dst)) = (u64)(src))
#else /* BIG_ENDIAN */
#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)
#if CONFIG_EXFAT_DEBUG_MSG
#define DPRINTK(...) \
do { \
printk("[EXFAT] " __VA_ARGS__); \
} while (0)
#else
#define DPRINTK(...)
#endif
static inline u16 get_col_index(u16 i)
{
return i >> LOW_INDEX_BIT;
}
static inline u16 get_row_index(u16 i)
{
return i & ~HIGH_INDEX_MASK;
}
/*----------------------------------------------------------------------*/
/* Type Definitions */
/*----------------------------------------------------------------------*/
/* MS_DOS FAT partition boot record (512 bytes) */
typedef struct {
u8 jmp_boot[3];
u8 oem_name[8];
u8 bpb[109];
u8 boot_code[390];
u8 signature[2];
} PBR_SECTOR_T;
/* MS-DOS FAT12/16 BIOS parameter block (51 bytes) */
typedef struct {
u8 sector_size[2];
u8 sectors_per_clu;
u8 num_reserved[2];
u8 num_fats;
u8 num_root_entries[2];
u8 num_sectors[2];
u8 media_type;
u8 num_fat_sectors[2];
u8 sectors_in_track[2];
u8 num_heads[2];
u8 num_hid_sectors[4];
u8 num_huge_sectors[4];
u8 phy_drv_no;
u8 reserved;
u8 ext_signature;
u8 vol_serial[4];
u8 vol_label[11];
u8 vol_type[8];
} BPB16_T;
/* MS-DOS FAT32 BIOS parameter block (79 bytes) */
typedef struct {
u8 sector_size[2];
u8 sectors_per_clu;
u8 num_reserved[2];
u8 num_fats;
u8 num_root_entries[2];
u8 num_sectors[2];
u8 media_type;
u8 num_fat_sectors[2];
u8 sectors_in_track[2];
u8 num_heads[2];
u8 num_hid_sectors[4];
u8 num_huge_sectors[4];
u8 num_fat32_sectors[4];
u8 ext_flags[2];
u8 fs_version[2];
u8 root_cluster[4];
u8 fsinfo_sector[2];
u8 backup_sector[2];
u8 reserved[12];
u8 phy_drv_no;
u8 ext_reserved;
u8 ext_signature;
u8 vol_serial[4];
u8 vol_label[11];
u8 vol_type[8];
} BPB32_T;
/* MS-DOS EXFAT BIOS parameter block (109 bytes) */
typedef struct {
u8 reserved1[53];
u8 vol_offset[8];
u8 vol_length[8];
u8 fat_offset[4];
u8 fat_length[4];
u8 clu_offset[4];
u8 clu_count[4];
u8 root_cluster[4];
u8 vol_serial[4];
u8 fs_version[2];
u8 vol_flags[2];
u8 sector_size_bits;
u8 sectors_per_clu_bits;
u8 num_fats;
u8 phy_drv_no;
u8 perc_in_use;
u8 reserved2[7];
} BPBEX_T;
/* MS-DOS FAT file system information sector (512 bytes) */
typedef struct {
u8 signature1[4];
u8 reserved1[480];
u8 signature2[4];
u8 free_cluster[4];
u8 next_cluster[4];
u8 reserved2[14];
u8 signature3[2];
} FSI_SECTOR_T;
/* MS-DOS FAT directory entry (32 bytes) */
typedef struct {
u8 dummy[32];
} DENTRY_T;
typedef struct {
u8 name[DOS_NAME_LENGTH];
u8 attr;
u8 lcase;
u8 create_time_ms;
u8 create_time[2];
u8 create_date[2];
u8 access_date[2];
u8 start_clu_hi[2];
u8 modify_time[2];
u8 modify_date[2];
u8 start_clu_lo[2];
u8 size[4];
} DOS_DENTRY_T;
/* MS-DOS FAT extended directory entry (32 bytes) */
typedef struct {
u8 order;
u8 unicode_0_4[10];
u8 attr;
u8 sysid;
u8 checksum;
u8 unicode_5_10[12];
u8 start_clu[2];
u8 unicode_11_12[4];
} EXT_DENTRY_T;
/* MS-DOS EXFAT file directory entry (32 bytes) */
typedef struct {
u8 type;
u8 num_ext;
u8 checksum[2];
u8 attr[2];
u8 reserved1[2];
u8 create_time[2];
u8 create_date[2];
u8 modify_time[2];
u8 modify_date[2];
u8 access_time[2];
u8 access_date[2];
u8 create_time_ms;
u8 modify_time_ms;
u8 access_time_ms;
u8 reserved2[9];
} FILE_DENTRY_T;
/* MS-DOS EXFAT stream extension directory entry (32 bytes) */
typedef struct {
u8 type;
u8 flags;
u8 reserved1;
u8 name_len;
u8 name_hash[2];
u8 reserved2[2];
u8 valid_size[8];
u8 reserved3[4];
u8 start_clu[4];
u8 size[8];
} STRM_DENTRY_T;
/* MS-DOS EXFAT file name directory entry (32 bytes) */
typedef struct {
u8 type;
u8 flags;
u8 unicode_0_14[30];
} NAME_DENTRY_T;
/* MS-DOS EXFAT allocation bitmap directory entry (32 bytes) */
typedef struct {
u8 type;
u8 flags;
u8 reserved[18];
u8 start_clu[4];
u8 size[8];
} BMAP_DENTRY_T;
/* MS-DOS EXFAT up-case table directory entry (32 bytes) */
typedef struct {
u8 type;
u8 reserved1[3];
u8 checksum[4];
u8 reserved2[12];
u8 start_clu[4];
u8 size[8];
} CASE_DENTRY_T;
/* MS-DOS EXFAT volume label directory entry (32 bytes) */
typedef struct {
u8 type;
u8 label_len;
u8 unicode_0_10[22];
u8 reserved[8];
} VOLM_DENTRY_T;
/* unused entry hint information */
typedef struct {
u32 dir;
s32 entry;
CHAIN_T clu;
} UENTRY_T;
typedef struct {
s32 (*alloc_cluster)(struct super_block *sb, s32 num_alloc, CHAIN_T *p_chain);
void (*free_cluster)(struct super_block *sb, CHAIN_T *p_chain, s32 do_relse);
s32 (*count_used_clusters)(struct super_block *sb);
s32 (*init_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u32 type,
u32 start_clu, u64 size);
s32 (*init_ext_entry)(struct super_block *sb, CHAIN_T *p_dir, s32 entry, s32 num_entries,
UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname);
s32 (*find_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, s32 num_entries, DOS_NAME_T *p_dosname, u32 type);
void (*delete_dir_entry)(struct super_block *sb, CHAIN_T *p_dir, s32 entry, s32 offset, s32 num_entries);
void (*get_uni_name_from_ext_entry)(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u16 *uniname);
s32 (*count_ext_entries)(struct super_block *sb, CHAIN_T *p_dir, s32 entry, DENTRY_T *p_entry);
s32 (*calc_num_entries)(UNI_NAME_T *p_uniname);
u32 (*get_entry_type)(DENTRY_T *p_entry);
void (*set_entry_type)(DENTRY_T *p_entry, u32 type);
u32 (*get_entry_attr)(DENTRY_T *p_entry);
void (*set_entry_attr)(DENTRY_T *p_entry, u32 attr);
u8 (*get_entry_flag)(DENTRY_T *p_entry);
void (*set_entry_flag)(DENTRY_T *p_entry, u8 flag);
u32 (*get_entry_clu0)(DENTRY_T *p_entry);
void (*set_entry_clu0)(DENTRY_T *p_entry, u32 clu0);
u64 (*get_entry_size)(DENTRY_T *p_entry);
void (*set_entry_size)(DENTRY_T *p_entry, u64 size);
void (*get_entry_time)(DENTRY_T *p_entry, TIMESTAMP_T *tp, u8 mode);
void (*set_entry_time)(DENTRY_T *p_entry, TIMESTAMP_T *tp, u8 mode);
} FS_FUNC_T;
typedef struct __FS_INFO_T {
u32 drv; /* drive ID */
u32 vol_type; /* volume FAT type */
u32 vol_id; /* volume serial number */
u64 num_sectors; /* num of sectors in volume */
u32 num_clusters; /* num of clusters in volume */
u32 cluster_size; /* cluster size in bytes */
u32 cluster_size_bits;
u32 sectors_per_clu; /* cluster size in sectors */
u32 sectors_per_clu_bits;
u32 PBR_sector; /* PBR sector */
u32 FAT1_start_sector; /* FAT1 start sector */
u32 FAT2_start_sector; /* FAT2 start sector */
u32 root_start_sector; /* root dir start sector */
u32 data_start_sector; /* data area start sector */
u32 num_FAT_sectors; /* num of FAT sectors */
u32 root_dir; /* root dir cluster */
u32 dentries_in_root; /* num of dentries in root dir */
u32 dentries_per_clu; /* num of dentries per cluster */
u32 vol_flag; /* volume dirty flag */
struct buffer_head *pbr_bh; /* PBR sector */
u32 map_clu; /* allocation bitmap start cluster */
u32 map_sectors; /* num of allocation bitmap sectors */
struct buffer_head **vol_amap; /* allocation bitmap */
u16 **vol_utbl; /* upcase table */
u32 clu_srch_ptr; /* cluster search pointer */
u32 used_clusters; /* number of used clusters */
UENTRY_T hint_uentry; /* unused entry hint information */
u32 dev_ejected; /* block device operation error flag */
FS_FUNC_T *fs_func;
struct semaphore v_sem;
/* 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 {
sector_t sector; /* sector number that contains file_entry */
s32 offset; /* byte offset in the sector */
s32 alloc_flag; /* flag in stream entry. 01 for cluster chain, 03 for contig. clusteres. */
u32 num_entries;
/* __buf should be the last member */
void *__buf;
} ENTRY_SET_CACHE_T;
/*----------------------------------------------------------------------*/
/* External Function Declarations */
/*----------------------------------------------------------------------*/
/* file system initialization & shutdown functions */
s32 ffsInit(void);
s32 ffsShutdown(void);
/* volume management functions */
s32 ffsMountVol(struct super_block *sb);
s32 ffsUmountVol(struct super_block *sb);
s32 ffsCheckVol(struct super_block *sb);
s32 ffsGetVolInfo(struct super_block *sb, VOL_INFO_T *info);
s32 ffsSyncVol(struct super_block *sb, s32 do_sync);
/* file management functions */
s32 ffsLookupFile(struct inode *inode, char *path, FILE_ID_T *fid);
s32 ffsCreateFile(struct inode *inode, char *path, u8 mode, FILE_ID_T *fid);
s32 ffsReadFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *rcount);
s32 ffsWriteFile(struct inode *inode, FILE_ID_T *fid, void *buffer, u64 count, u64 *wcount);
s32 ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size);
s32 ffsMoveFile(struct inode *old_parent_inode, FILE_ID_T *fid, struct inode *new_parent_inode, struct dentry *new_dentry);
s32 ffsRemoveFile(struct inode *inode, FILE_ID_T *fid);
s32 ffsSetAttr(struct inode *inode, u32 attr);
s32 ffsGetStat(struct inode *inode, DIR_ENTRY_T *info);
s32 ffsSetStat(struct inode *inode, DIR_ENTRY_T *info);
s32 ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu);
/* directory management functions */
s32 ffsCreateDir(struct inode *inode, char *path, FILE_ID_T *fid);
s32 ffsReadDir(struct inode *inode, DIR_ENTRY_T *dir_ent);
s32 ffsRemoveDir(struct inode *inode, FILE_ID_T *fid);
/*----------------------------------------------------------------------*/
/* External Function Declarations (NOT TO UPPER LAYER) */
/*----------------------------------------------------------------------*/
/* fs management functions */
s32 fs_init(void);
s32 fs_shutdown(void);
void fs_set_vol_flags(struct super_block *sb, u32 new_flag);
void fs_sync(struct super_block *sb, s32 do_sync);
void fs_error(struct super_block *sb);
/* cluster management functions */
s32 clear_cluster(struct super_block *sb, u32 clu);
s32 fat_alloc_cluster(struct super_block *sb, s32 num_alloc, CHAIN_T *p_chain);
s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc, CHAIN_T *p_chain);
void fat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, s32 do_relse);
void exfat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, s32 do_relse);
u32 find_last_cluster(struct super_block *sb, CHAIN_T *p_chain);
s32 count_num_clusters(struct super_block *sb, CHAIN_T *dir);
s32 fat_count_used_clusters(struct super_block *sb);
s32 exfat_count_used_clusters(struct super_block *sb);
void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len);
/* allocation bitmap management functions */
s32 load_alloc_bitmap(struct super_block *sb);
void free_alloc_bitmap(struct super_block *sb);
s32 set_alloc_bitmap(struct super_block *sb, u32 clu);
s32 clr_alloc_bitmap(struct super_block *sb, u32 clu);
u32 test_alloc_bitmap(struct super_block *sb, u32 clu);
void sync_alloc_bitmap(struct super_block *sb);
/* upcase table management functions */
s32 load_upcase_table(struct super_block *sb);
void free_upcase_table(struct super_block *sb);
/* dir entry management functions */
u32 fat_get_entry_type(DENTRY_T *p_entry);
u32 exfat_get_entry_type(DENTRY_T *p_entry);
void fat_set_entry_type(DENTRY_T *p_entry, u32 type);
void exfat_set_entry_type(DENTRY_T *p_entry, u32 type);
u32 fat_get_entry_attr(DENTRY_T *p_entry);
u32 exfat_get_entry_attr(DENTRY_T *p_entry);
void fat_set_entry_attr(DENTRY_T *p_entry, u32 attr);
void exfat_set_entry_attr(DENTRY_T *p_entry, u32 attr);
u8 fat_get_entry_flag(DENTRY_T *p_entry);
u8 exfat_get_entry_flag(DENTRY_T *p_entry);
void fat_set_entry_flag(DENTRY_T *p_entry, u8 flag);
void exfat_set_entry_flag(DENTRY_T *p_entry, u8 flag);
u32 fat_get_entry_clu0(DENTRY_T *p_entry);
u32 exfat_get_entry_clu0(DENTRY_T *p_entry);
void fat_set_entry_clu0(DENTRY_T *p_entry, u32 start_clu);
void exfat_set_entry_clu0(DENTRY_T *p_entry, u32 start_clu);
u64 fat_get_entry_size(DENTRY_T *p_entry);
u64 exfat_get_entry_size(DENTRY_T *p_entry);
void fat_set_entry_size(DENTRY_T *p_entry, u64 size);
void exfat_set_entry_size(DENTRY_T *p_entry, u64 size);
void fat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, u8 mode);
void exfat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, u8 mode);
void fat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, u8 mode);
void exfat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, u8 mode);
s32 fat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u32 type, u32 start_clu, u64 size);
s32 exfat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u32 type, u32 start_clu, u64 size);
s32 fat_init_ext_dir_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, s32 num_entries, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname);
s32 exfat_init_ext_dir_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, s32 num_entries, UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname);
void init_dos_entry(DOS_DENTRY_T *ep, u32 type, u32 start_clu);
void init_ext_entry(EXT_DENTRY_T *ep, s32 order, u8 chksum, u16 *uniname);
void init_file_entry(FILE_DENTRY_T *ep, u32 type);
void init_strm_entry(STRM_DENTRY_T *ep, u8 flags, u32 start_clu, u64 size);
void init_name_entry(NAME_DENTRY_T *ep, u16 *uniname);
void fat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, s32 order, s32 num_entries);
void exfat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, s32 order, s32 num_entries);
s32 find_location(struct super_block *sb, CHAIN_T *p_dir, s32 entry, sector_t *sector, s32 *offset);
DENTRY_T *get_entry_with_sector(struct super_block *sb, sector_t sector, s32 offset);
DENTRY_T *get_entry_in_dir(struct super_block *sb, CHAIN_T *p_dir, s32 entry, sector_t *sector);
ENTRY_SET_CACHE_T *get_entry_set_in_dir(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u32 type, DENTRY_T **file_ep);
void release_entry_set(ENTRY_SET_CACHE_T *es);
s32 write_whole_entry_set(struct super_block *sb, ENTRY_SET_CACHE_T *es);
s32 write_partial_entries_in_entry_set(struct super_block *sb, ENTRY_SET_CACHE_T *es, DENTRY_T *ep, u32 count);
s32 search_deleted_or_unused_entry(struct super_block *sb, CHAIN_T *p_dir, s32 num_entries);
s32 find_empty_entry(struct inode *inode, CHAIN_T *p_dir, s32 num_entries);
s32 fat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, s32 num_entries, DOS_NAME_T *p_dosname, u32 type);
s32 exfat_find_dir_entry(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, s32 num_entries, DOS_NAME_T *p_dosname, u32 type);
s32 fat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, s32 entry, DENTRY_T *p_entry);
s32 exfat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, s32 entry, DENTRY_T *p_entry);
s32 count_dos_name_entries(struct super_block *sb, CHAIN_T *p_dir, u32 type);
void update_dir_checksum(struct super_block *sb, CHAIN_T *p_dir, s32 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 */
s32 get_num_entries_and_dos_name(struct super_block *sb, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, s32 *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, u8 mode);
void fat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u16 *uniname);
void exfat_get_uni_name_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u16 *uniname);
s32 extract_uni_name_from_ext_entry(EXT_DENTRY_T *ep, u16 *uniname, s32 order);
s32 extract_uni_name_from_name_entry(NAME_DENTRY_T *ep, u16 *uniname, s32 order);
s32 fat_generate_dos_name(struct super_block *sb, CHAIN_T *p_dir, DOS_NAME_T *p_dosname);
void fat_attach_count_to_dos_name(u8 *dosname, s32 count);
s32 fat_calc_num_entries(UNI_NAME_T *p_uniname);
s32 exfat_calc_num_entries(UNI_NAME_T *p_uniname);
u8 calc_checksum_1byte(void *data, s32 len, u8 chksum);
u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type);
u32 calc_checksum_4byte(void *data, s32 len, u32 chksum, s32 type);
/* name resolution functions */
s32 resolve_path(struct inode *inode, char *path, CHAIN_T *p_dir, UNI_NAME_T *p_uniname);
s32 resolve_name(u8 *name, u8 **arg);
/* file operation functions */
s32 fat16_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr);
s32 fat32_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr);
s32 exfat_mount(struct super_block *sb, PBR_SECTOR_T *p_pbr);
s32 create_dir(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
s32 create_file(struct inode *inode, CHAIN_T *p_dir, UNI_NAME_T *p_uniname, u8 mode, FILE_ID_T *fid);
void remove_file(struct inode *inode, CHAIN_T *p_dir, s32 entry);
s32 rename_file(struct inode *inode, CHAIN_T *p_dir, s32 old_entry, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
s32 move_file(struct inode *inode, CHAIN_T *p_olddir, s32 oldentry, CHAIN_T *p_newdir, UNI_NAME_T *p_uniname, FILE_ID_T *fid);
/* sector read/write functions */
s32 sector_read(struct super_block *sb, sector_t sec, struct buffer_head **bh, s32 read);
s32 sector_write(struct super_block *sb, sector_t sec, struct buffer_head *bh, s32 sync);
s32 multi_sector_read(struct super_block *sb, sector_t sec, struct buffer_head **bh, s32 num_secs, s32 read);
s32 multi_sector_write(struct super_block *sb, sector_t sec, struct buffer_head *bh, s32 num_secs, s32 sync);
#endif /* _EXFAT_H */

View 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_data.h"
#include "exfat_oal.h"
#include "exfat_blkdev.h"
#include "exfat_cache.h"
#include "exfat_nls.h"
#include "exfat_super.h"
#include "exfat_core.h"
/*======================================================================*/
/* */
/* GLOBAL VARIABLE DEFINITIONS */
/* */
/*======================================================================*/
/*----------------------------------------------------------------------*/
/* File Manager */
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* Buffer Manager */
/*----------------------------------------------------------------------*/
/* FAT cache */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
DECLARE_MUTEX(f_sem);
#else
DEFINE_SEMAPHORE(f_sem);
#endif
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 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
DECLARE_MUTEX(b_sem);
#else
DEFINE_SEMAPHORE(b_sem);
#endif
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];

View File

@ -0,0 +1,58 @@
/*
* 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"
/*======================================================================*/
/* */
/* FFS CONFIGURATIONS */
/* (CHANGE THIS PART IF REQUIRED) */
/* */
/*======================================================================*/
/* 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
#endif /* _EXFAT_DATA_H */

View File

@ -0,0 +1,448 @@
/*
* 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_data.h"
#include "exfat_nls.h"
#include "exfat_api.h"
#include "exfat_super.h"
#include "exfat_core.h"
#include <linux/nls.h>
/*----------------------------------------------------------------------*/
/* Global Variable Definitions */
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* Local Variable Definitions */
/*----------------------------------------------------------------------*/
static u16 bad_dos_chars[] = {
/* + , ; = [ ] */
0x002B, 0x002C, 0x003B, 0x003D, 0x005B, 0x005D,
0xFF0B, 0xFF0C, 0xFF1B, 0xFF1D, 0xFF3B, 0xFF3D,
0
};
static u16 bad_uni_chars[] = {
/* " * / : < > ? \ | */
0x0022, 0x002A, 0x002F, 0x003A,
0x003C, 0x003E, 0x003F, 0x005C, 0x007C,
0
};
/*----------------------------------------------------------------------*/
/* Local Function Declarations */
/*----------------------------------------------------------------------*/
static s32 convert_uni_to_ch(struct nls_table *nls, u8 *ch, u16 uni, s32 *lossy);
static s32 convert_ch_to_uni(struct nls_table *nls, u16 *uni, u8 *ch, s32 *lossy);
/*======================================================================*/
/* Global Function Definitions */
/*======================================================================*/
u16 nls_upper(struct super_block *sb, u16 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;
}
u16 *nls_wstrchr(u16 *str, u16 wchar)
{
while (*str) {
if (*(str++) == wchar)
return str;
}
return 0;
}
s32 nls_dosname_cmp(struct super_block *sb, u8 *a, u8 *b)
{
return strncmp((void *) a, (void *) b, DOS_NAME_LENGTH);
} /* end of nls_dosname_cmp */
s32 nls_uniname_cmp(struct super_block *sb, u16 *a, u16 *b)
{
int 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, s32 *p_lossy)
{
int i, j, len, lossy = FALSE;
u8 buf[MAX_CHARSET_SIZE];
u8 lower = 0, upper = 0;
u8 *dosname = p_dosname->name;
u16 *uniname = p_uniname->name;
u16 *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, (u16 *) UNI_CUR_DIR_NAME)) {
*(dosname) = '.';
p_dosname->name_case = 0x0;
if (p_lossy != NULL)
*p_lossy = FALSE;
return;
}
if (!nls_uniname_cmp(sb, uniname, (u16 *) 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 == (u16) '.')
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 == (u16) '\0') {
break;
} else if (*uniname == (u16) ' ') {
lossy = TRUE;
} else if (*uniname == (u16) '.') {
if (uniname < last_period)
lossy = TRUE;
else
i = 8;
} else if (nls_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)
{
int i = 0, j, n = 0;
u8 buf[DOS_NAME_LENGTH+2];
u8 *dosname = p_dosname->name;
u16 *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 = (u16) '\0';
} /* end of nls_dosname_to_uniname */
void nls_uniname_to_cstring(struct super_block *sb, u8 *p_cstring, UNI_NAME_T *p_uniname)
{
int i, j, len;
u8 buf[MAX_CHARSET_SIZE];
u16 *uniname = p_uniname->name;
struct nls_table *nls = EXFAT_SB(sb)->nls_io;
if (nls == NULL) {
len = utf16s_to_utf8s(uniname, MAX_NAME_LENGTH, UTF16_HOST_ENDIAN, p_cstring, MAX_NAME_LENGTH);
p_cstring[len] = 0;
return;
}
i = 0;
while (i < (MAX_NAME_LENGTH-1)) {
if (*uniname == (u16) '\0')
break;
len = convert_uni_to_ch(nls, buf, *uniname, NULL);
if (len > 1) {
for (j = 0; j < len; j++)
*p_cstring++ = (char) *(buf+j);
} else { /* len == 1 */
*p_cstring++ = (char) *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, u8 *p_cstring, s32 *p_lossy)
{
int i, j, lossy = FALSE;
u8 *end_of_name;
u8 upname[MAX_NAME_LENGTH * 2];
u16 *uniname = p_uniname->name;
struct nls_table *nls = EXFAT_SB(sb)->nls_io;
/* strip all trailing spaces */
end_of_name = p_cstring + strlen((char *) p_cstring);
while (*(--end_of_name) == ' ') {
if (end_of_name < p_cstring)
break;
}
*(++end_of_name) = '\0';
if (strcmp((char *) p_cstring, ".") && strcmp((char *) 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;
if (nls == NULL) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,101)
i = utf8s_to_utf16s(p_cstring, MAX_NAME_LENGTH, uniname);
#else
i = utf8s_to_utf16s(p_cstring, MAX_NAME_LENGTH, UTF16_HOST_ENDIAN, uniname, MAX_NAME_LENGTH);
#endif
for (j = 0; j < i; j++)
SET16_A(upname + j * 2, nls_upper(sb, uniname[j]));
uniname[i] = '\0';
}
else {
i = j = 0;
while (j < (MAX_NAME_LENGTH-1)) {
if (*(p_cstring+i) == '\0')
break;
i += convert_ch_to_uni(nls, uniname, (u8 *)(p_cstring+i), &lossy);
if ((*uniname < 0x0020) || nls_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 = (u16) '\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 s32 convert_ch_to_uni(struct nls_table *nls, u16 *uni, u8 *ch, s32 *lossy)
{
int len;
*uni = 0x0;
if (ch[0] < 0x80) {
*uni = (u16) ch[0];
return 1;
}
len = nls->char2uni(ch, NLS_MAX_CHARSET_SIZE, uni);
if (len < 0) {
/* conversion failed */
printk("%s: fail to use nls\n", __func__);
if (lossy != NULL)
*lossy = TRUE;
*uni = (u16) '_';
if (!strcmp(nls->charset, "utf8"))
return 1;
else
return 2;
}
return len;
} /* end of convert_ch_to_uni */
static s32 convert_uni_to_ch(struct nls_table *nls, u8 *ch, u16 uni, s32 *lossy)
{
int len;
ch[0] = 0x0;
if (uni < 0x0080) {
ch[0] = (u8) uni;
return 1;
}
len = nls->uni2char(uni, ch, NLS_MAX_CHARSET_SIZE);
if (len < 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 */

View File

@ -0,0 +1,91 @@
/*
* 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/types.h>
#include <linux/nls.h>
#include "exfat_config.h"
#include "exfat_api.h"
/*----------------------------------------------------------------------*/
/* 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 {
u8 name[DOS_NAME_LENGTH];
u8 name_case;
} DOS_NAME_T;
/* unicode name stucture */
typedef struct {
u16 name[MAX_NAME_LENGTH];
u16 name_hash;
u8 name_len;
} UNI_NAME_T;
/*----------------------------------------------------------------------*/
/* External Function Declarations */
/*----------------------------------------------------------------------*/
/* NLS management function */
u16 nls_upper(struct super_block *sb, u16 a);
s32 nls_dosname_cmp(struct super_block *sb, u8 *a, u8 *b);
s32 nls_uniname_cmp(struct super_block *sb, u16 *a, u16 *b);
void nls_uniname_to_dosname(struct super_block *sb, DOS_NAME_T *p_dosname, UNI_NAME_T *p_uniname, s32 *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, u8 *p_cstring, UNI_NAME_T *p_uniname);
void nls_cstring_to_uniname(struct super_block *sb, UNI_NAME_T *p_uniname, u8 *p_cstring, s32 *p_lossy);
#endif /* _EXFAT_NLS_H */

View File

@ -0,0 +1,196 @@
/* 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_api.h"
#include "exfat_oal.h"
/*======================================================================*/
/* */
/* SEMAPHORE FUNCTIONS */
/* */
/*======================================================================*/
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
DECLARE_MUTEX(z_sem);
#else
DEFINE_SEMAPHORE(z_sem);
#endif
s32 sm_init(struct semaphore *sm)
{
sema_init(sm, 1);
return 0;
} /* end of sm_init */
s32 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;
time_t second, day, leap_day, month, year;
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0)
ts = CURRENT_TIME_SEC;
#else
ktime_get_real_ts(&ts);
#endif
second = ts.tv_sec;
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 */

View File

@ -0,0 +1,74 @@
/*
* 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 <linux/semaphore.h>
#include "exfat_config.h"
#include <linux/version.h>
/*----------------------------------------------------------------------*/
/* Constant & Macro Definitions (Configurable) */
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* Constant & Macro Definitions (Non-Configurable) */
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
/* Type Definitions */
/*----------------------------------------------------------------------*/
typedef struct {
u16 sec; /* 0 ~ 59 */
u16 min; /* 0 ~ 59 */
u16 hour; /* 0 ~ 23 */
u16 day; /* 1 ~ 31 */
u16 mon; /* 1 ~ 12 */
u16 year; /* 0 ~ 127 (since 1980) */
} TIMESTAMP_T;
/*----------------------------------------------------------------------*/
/* External Function Declarations */
/*----------------------------------------------------------------------*/
s32 sm_init(struct semaphore *sm);
s32 sm_P(struct semaphore *sm);
void sm_V(struct semaphore *sm);
TIMESTAMP_T *tm_current(TIMESTAMP_T *tm);
#endif /* _EXFAT_OAL_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,173 @@
/* 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_data.h"
#include "exfat_oal.h"
#include "exfat_blkdev.h"
#include "exfat_cache.h"
#include "exfat_nls.h"
#include "exfat_api.h"
#include "exfat_core.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 */
int time_offset; /* Offset of timestamps from UTC (in minutes) */
char *iocharset; /* charset for filename input/display */
unsigned char casesensitive;
unsigned char errors; /* on error: continue, panic, remount-ro */
#ifdef CONFIG_EXFAT_DISCARD
unsigned char discard; /* flag on if -o dicard specified and device support discard() */
#endif /* CONFIG_EXFAT_DISCARD */
unsigned tz_set:1; /* Filesystem timestamps' offset set */
};
#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];
#ifdef CONFIG_EXFAT_KERNEL_DEBUG
long debug_flags;
#endif /* CONFIG_EXFAT_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 */

View File

@ -0,0 +1,405 @@
/*
* 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_nls.h"
const u8 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
};

View 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.9"

View File

@ -6,7 +6,7 @@ INSTALL_DIR =${EXTLIB}/__install
#MAKEFILE_LIST = freetype libnl openssl #MAKEFILE_LIST = freetype libnl openssl
# openssl for tee # openssl for tee
MULTI_CORES ?= $(shell grep -c ^processor /proc/cpuinfo) MULTI_CORES ?= $(shell grep -c ^processor /proc/cpuinfo)
MAKEFILE_LIST = openssl libnl MAKEFILE_LIST = openssl libnl exfat-utils
XML2 := libxml2-2.9.3 XML2 := libxml2-2.9.3
@ -19,6 +19,7 @@ FFMPEG := ffmpeg-3.0
LIBNL := libnl-3.2.27 LIBNL := libnl-3.2.27
OPENSSL := openssl-1.0.2d OPENSSL := openssl-1.0.2d
CURL := curl-7.45.0 CURL := curl-7.45.0
EXFAT_UTILS := exfat-utils-1.2.7
unexport CC unexport CC
unexport CPP unexport CPP
@ -164,6 +165,17 @@ endif
@rm -rf ${INSTALL_DIR}/lib/pkgconfig @rm -rf ${INSTALL_DIR}/lib/pkgconfig
@echo $(NVT_CURL_SSL) > ${CURL}/.nvt_finish @echo $(NVT_CURL_SSL) > ${CURL}/.nvt_finish
exfat-utils: init
@echo ">>>>>>>>>>>>>>>>>>> $@ compiling >>>>>>>>>>>>>>>>>>>"
@if [ ! -f ${EXFAT_UTILS}/.nvt_finish ]; then \
$(call check_exist, ${EXFAT_UTILS}); \
cd ${EXFAT_UTILS}; ./configure --host=${NVT_HOST} --prefix=${EXTERNAL}/${INSTALL_DIR}; make; \
fi
@mkdir -p ${EXTERNAL}/${INSTALL_DIR}/sbin/;
@cd ${EXFAT_UTILS}; cp -f ./mkfs/mkexfatfs ${ROOTFS_DIR}/rootfs/sbin/;
@${CROSS_COMPILE}strip ${ROOTFS_DIR}/rootfs/sbin/mkexfatfs;
@touch ${EXFAT_UTILS}/.nvt_finish
install: install:
@echo ">>>>>>>>>>>>>>>>>>> $@ >>>>>>>>>>>>>>>>>>>" @echo ">>>>>>>>>>>>>>>>>>> $@ >>>>>>>>>>>>>>>>>>>"
@if [ -x ${INSTALL_DIR}/include ]; then \ @if [ -x ${INSTALL_DIR}/include ]; then \
@ -181,4 +193,4 @@ install:
clean: clean:
@echo ">>>>>>>>>>>>>>>>>>> Remove >>>>>>>>>>>>>>>>>>>" @echo ">>>>>>>>>>>>>>>>>>> Remove >>>>>>>>>>>>>>>>>>>"
@rm -rf ${INSTALL_DIR} @rm -rf ${INSTALL_DIR}
@rm -rf ${XML2} ${AXTLS} ${FUSE} ${FREETYPE} ${FFMPEG} ${LIBNL} ${SQLITE3} ${OPENSSL} ${CURL} ${UNWIND} ${LIBP11} @rm -rf ${XML2} ${AXTLS} ${FUSE} ${FREETYPE} ${FFMPEG} ${LIBNL} ${SQLITE3} ${OPENSSL} ${CURL} ${UNWIND} ${LIBP11} ${EXFAT_UTILS}

View File

@ -102,6 +102,7 @@ MV_KO_LIST=(\
/lib/modules/$KERVER/kernel/drivers/usb/serial/option.ko \ /lib/modules/$KERVER/kernel/drivers/usb/serial/option.ko \
/lib/modules/$KERVER/kernel/drivers/usb/class/cdc-wdm.ko \ /lib/modules/$KERVER/kernel/drivers/usb/class/cdc-wdm.ko \
/lib/modules/$KERVER/kernel/drivers/net/usb/qmi_wwan.ko \ /lib/modules/$KERVER/kernel/drivers/net/usb/qmi_wwan.ko \
/lib/modules/$KERVER/extra/fs/exfat/exfat.ko \
) )

View File

@ -343,8 +343,8 @@ void System_OnStrgInit_FS(void)
GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 10); GxStrg_SetConfigEx(0, FILE_CFG_MAX_OPEN_FILE, 10);
#endif #endif
// support exFAT // support exFAT
// GxStrg_SetConfigEx(0, FILE_CFG_SUPPORT_EXFAT, TRUE); GxStrg_SetConfigEx(0, FILE_CFG_SUPPORT_EXFAT, TRUE);
GxStrg_SetConfigEx(0, FILE_CFG_SUPPORT_EXFAT, FALSE); // GxStrg_SetConfigEx(0, FILE_CFG_SUPPORT_EXFAT, FALSE);
// mount path // mount path
strncpy(mount_path, "/mnt/sd", sizeof(mount_path) - 1); strncpy(mount_path, "/mnt/sd", sizeof(mount_path) - 1);
mount_path[sizeof(mount_path) - 1] = '\0'; mount_path[sizeof(mount_path) - 1] = '\0';