diff --git a/patch.sh b/patch.sh
index d60e8edc3d7cd19fc009a26992b04335991e324d..07a7575cc52c9c6542adf7b68904a34cb303e424 100644
--- a/patch.sh
+++ b/patch.sh
@@ -330,7 +330,7 @@ dtb_makefile_append () {
 }
 
 beagleboard_dtbs () {
-	bbdtbs="v5.3.x"
+	bbdtbs="v5.4.x"
 	#regenerate="enable"
 	if [ "x${regenerate}" = "xenable" ] ; then
 		cd ../
@@ -382,7 +382,7 @@ local_patch () {
 }
 
 #external_git
-aufs
+#aufs
 can_isotp
 #rt
 wireguard
@@ -424,10 +424,7 @@ patch_backports (){
 }
 
 backports () {
-	dir 'drivers/exfat'
-
 #	backport_tag="v4.x-y"
-	backport_tag="619e17cf75dd58905aa67ccd494a6ba5f19d6cc6"
 
 	subsystem="exfat"
 	#regenerate="enable"
@@ -489,10 +486,11 @@ soc () {
 }
 
 ###
-backports
+#backports
 #reverts
 drivers
 soc
+dir 'fixes'
 
 packaging () {
 	echo "dir: packaging"
diff --git a/patches/WireGuard/0001-merge-WireGuard.patch b/patches/WireGuard/0001-merge-WireGuard.patch
index e2df120ab19151dbdbbea397c101a2638d2e819f..8dd7ee4a750a9dc7547f6020de10eb816c617d41 100644
--- a/patches/WireGuard/0001-merge-WireGuard.patch
+++ b/patches/WireGuard/0001-merge-WireGuard.patch
@@ -1,6 +1,6 @@
-From 18b9299bc240d57dcc401fed6defadf8360f9e82 Mon Sep 17 00:00:00 2001
+From 800183001259bfdfcbe8d69de90cae904cf95b20 Mon Sep 17 00:00:00 2001
 From: Robert Nelson <robertcnelson@gmail.com>
-Date: Tue, 1 Oct 2019 10:29:04 -0500
+Date: Tue, 1 Oct 2019 11:24:09 -0500
 Subject: [PATCH] merge: WireGuard
 
 Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
@@ -202,7 +202,7 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
  create mode 100644 net/wireguard/version.h
 
 diff --git a/net/Kconfig b/net/Kconfig
-index 57f51a279ad6..6006564bc33b 100644
+index 3101bfcbdd7a..5ecae010f9ec 100644
 --- a/net/Kconfig
 +++ b/net/Kconfig
 @@ -88,6 +88,7 @@ config INET
diff --git a/patches/can_isotp/0001-merge-can-isotp-https-github.com-hartkopp-can-isotp.patch b/patches/can_isotp/0001-merge-can-isotp-https-github.com-hartkopp-can-isotp.patch
index 2a37fd9173091089bdf5bf5acb91444ca8faee30..5970dff042481fd5952caf86dcafea546165358b 100644
--- a/patches/can_isotp/0001-merge-can-isotp-https-github.com-hartkopp-can-isotp.patch
+++ b/patches/can_isotp/0001-merge-can-isotp-https-github.com-hartkopp-can-isotp.patch
@@ -1,6 +1,6 @@
-From a776f7edb2a0d58a10e46cb252e73652f83774c2 Mon Sep 17 00:00:00 2001
+From 25d2c346881a073f8018721bcc77abf88863a311 Mon Sep 17 00:00:00 2001
 From: Robert Nelson <robertcnelson@gmail.com>
-Date: Tue, 1 Oct 2019 10:28:29 -0500
+Date: Tue, 1 Oct 2019 11:24:51 -0500
 Subject: [PATCH] merge: can-isotp: https://github.com/hartkopp/can-isotp
 
 Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
diff --git a/patches/can_isotp/0002-CAN_ISOTP-wire-up-to-kconfig-makefile.patch b/patches/can_isotp/0002-CAN_ISOTP-wire-up-to-kconfig-makefile.patch
index 9582a9cb3a53ed5496f84353be2a82dc2da9d41f..1948be8dd7ee701ff2700d270073090f13df6562 100644
--- a/patches/can_isotp/0002-CAN_ISOTP-wire-up-to-kconfig-makefile.patch
+++ b/patches/can_isotp/0002-CAN_ISOTP-wire-up-to-kconfig-makefile.patch
@@ -10,12 +10,12 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
  2 files changed, 13 insertions(+)
 
 diff --git a/net/can/Kconfig b/net/can/Kconfig
-index a15c0e0d1fc7..8774a591398b 100644
+index d77042752457..9e2f196f0423 100644
 --- a/net/can/Kconfig
 +++ b/net/can/Kconfig
-@@ -51,6 +51,16 @@ config CAN_GW
- 	  They can be modified with AND/OR/XOR/SET operations as configured
- 	  by the netlink configuration interface known e.g. from iptables.
+@@ -55,6 +55,16 @@ config CAN_GW
+ 
+ source "net/can/j1939/Kconfig"
  
 +config CAN_ISOTP
 +	tristate "ISO 15765-2:2016 CAN transport protocol"
@@ -31,16 +31,17 @@ index a15c0e0d1fc7..8774a591398b 100644
  
  endif
 diff --git a/net/can/Makefile b/net/can/Makefile
-index 1242bbbfe57f..fde676965946 100644
+index 08bd217fc051..cfa1024369cf 100644
 --- a/net/can/Makefile
 +++ b/net/can/Makefile
-@@ -15,3 +15,6 @@ can-bcm-y		:= bcm.o
- 
+@@ -16,4 +16,7 @@ can-bcm-y		:= bcm.o
  obj-$(CONFIG_CAN_GW)	+= can-gw.o
  can-gw-y		:= gw.o
-+
+ 
 +obj-$(CONFIG_CAN_ISOTP)	+= can-isotp.o
 +can-isotp-y		:= isotp.o
++
+ obj-$(CONFIG_CAN_J1939)	+= j1939/
 -- 
-2.20.1
+2.23.0
 
diff --git a/patches/defconfig b/patches/defconfig
index 0d960d24a07b1a6b0d0c986096d02bc4dfde83e1..fd58152a6f1203ae2413c91d3847ffcac99f4f1b 100644
--- a/patches/defconfig
+++ b/patches/defconfig
@@ -1,6 +1,6 @@
 #
 # Automatically generated file; DO NOT EDIT.
-# Linux/arm 5.3.2 Kernel Configuration
+# Linux/arm 5.4.0-rc1 Kernel Configuration
 #
 
 #
@@ -11,6 +11,7 @@ CONFIG_GCC_VERSION=80300
 CONFIG_CLANG_VERSION=0
 CONFIG_CC_CAN_LINK=y
 CONFIG_CC_HAS_ASM_GOTO=y
+CONFIG_CC_HAS_ASM_INLINE=y
 CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y
 CONFIG_IRQ_WORK=y
 CONFIG_BUILDTIME_EXTABLE_SORT=y
@@ -24,7 +25,7 @@ CONFIG_INIT_ENV_ARG_LIMIT=32
 # CONFIG_HEADER_TEST is not set
 CONFIG_LOCALVERSION=""
 # CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_BUILD_SALT="5.3.2-bone9.2"
+CONFIG_BUILD_SALT="5.4-rc1-bone0"
 CONFIG_HAVE_KERNEL_GZIP=y
 CONFIG_HAVE_KERNEL_LZMA=y
 CONFIG_HAVE_KERNEL_XZ=y
@@ -256,19 +257,13 @@ CONFIG_ARCH_MULTIPLATFORM=y
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_DOVE is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_LPC32XX is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C24XX is not set
-# CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP1 is not set
 
 #
@@ -287,6 +282,7 @@ CONFIG_ARCH_MULTI_V6_V7=y
 # CONFIG_ARCH_ACTIONS is not set
 # CONFIG_ARCH_ALPINE is not set
 # CONFIG_ARCH_ARTPEC is not set
+# CONFIG_ARCH_ASPEED is not set
 # CONFIG_ARCH_AT91 is not set
 # CONFIG_ARCH_BCM is not set
 # CONFIG_ARCH_BERLIN is not set
@@ -538,6 +534,7 @@ CONFIG_DT_IDLE_STATES=y
 # ARM CPU Idle Drivers
 #
 CONFIG_ARM_CPUIDLE=y
+CONFIG_ARM_PSCI_CPUIDLE=y
 # CONFIG_ARM_HIGHBANK_CPUIDLE is not set
 # end of ARM CPU Idle Drivers
 # end of CPU Idle
@@ -611,6 +608,7 @@ CONFIG_EFI_BOOTLOADER_CONTROL=m
 CONFIG_EFI_CAPSULE_LOADER=m
 # CONFIG_EFI_TEST is not set
 # CONFIG_RESET_ATTACK_MITIGATION is not set
+# CONFIG_EFI_RCI2_TABLE is not set
 # end of EFI (Extensible Firmware Interface) Support
 
 #
@@ -685,6 +683,7 @@ CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
 CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
 CONFIG_HAVE_EXIT_THREAD=y
 CONFIG_ARCH_MMAP_RND_BITS=8
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
 CONFIG_CLONE_BACKWARDS=y
 CONFIG_OLD_SIGSUSPEND3=y
 CONFIG_OLD_SIGACTION=y
@@ -732,6 +731,8 @@ CONFIG_MODVERSIONS=y
 CONFIG_MODULE_COMPRESS=y
 # CONFIG_MODULE_COMPRESS_GZIP is not set
 CONFIG_MODULE_COMPRESS_XZ=y
+# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_TRIM_UNUSED_KSYMS is not set
 CONFIG_MODULES_TREE_LOOKUP=y
 CONFIG_BLOCK=y
@@ -745,6 +746,7 @@ CONFIG_BLK_DEV_THROTTLING=y
 # CONFIG_BLK_CMDLINE_PARSER is not set
 CONFIG_BLK_WBT=y
 # CONFIG_BLK_CGROUP_IOLATENCY is not set
+# CONFIG_BLK_CGROUP_IOCOST is not set
 CONFIG_BLK_WBT_MQ=y
 CONFIG_BLK_DEBUG_FS=y
 CONFIG_BLK_DEBUG_FS_ZONED=y
@@ -1379,7 +1381,6 @@ CONFIG_NET_DSA=m
 # CONFIG_NET_DSA_TAG_EDSA is not set
 # CONFIG_NET_DSA_TAG_MTK is not set
 # CONFIG_NET_DSA_TAG_KSZ is not set
-# CONFIG_NET_DSA_TAG_KSZ9477 is not set
 # CONFIG_NET_DSA_TAG_QCA is not set
 # CONFIG_NET_DSA_TAG_LAN9303 is not set
 # CONFIG_NET_DSA_TAG_SJA1105 is not set
@@ -1507,6 +1508,7 @@ CONFIG_NET_ACT_TUNNEL_KEY=m
 CONFIG_NET_IFE_SKBMARK=m
 CONFIG_NET_IFE_SKBPRIO=m
 CONFIG_NET_IFE_SKBTCINDEX=m
+# CONFIG_NET_TC_SKB_EXT is not set
 CONFIG_NET_SCH_FIFO=y
 CONFIG_DCB=y
 CONFIG_DNS_RESOLVER=y
@@ -1549,7 +1551,7 @@ CONFIG_BPF_STREAM_PARSER=y
 # Network testing
 #
 CONFIG_NET_PKTGEN=m
-CONFIG_NET_DROP_MONITOR=m
+CONFIG_NET_DROP_MONITOR=y
 # end of Network testing
 # end of Networking options
 
@@ -1578,6 +1580,7 @@ CONFIG_CAN=y
 CONFIG_CAN_RAW=m
 CONFIG_CAN_BCM=m
 CONFIG_CAN_GW=m
+CONFIG_CAN_J1939=m
 CONFIG_CAN_ISOTP=m
 
 #
@@ -1818,6 +1821,7 @@ CONFIG_DMA_SHARED_BUFFER=y
 # Bus devices
 #
 # CONFIG_BRCMSTB_GISB_ARB is not set
+# CONFIG_MOXTET is not set
 CONFIG_OMAP_INTERCONNECT=y
 # CONFIG_OMAP_OCP2SCP is not set
 CONFIG_SIMPLE_PM_BUS=y
@@ -1834,13 +1838,13 @@ CONFIG_GNSS_SIRF_SERIAL=m
 CONFIG_GNSS_UBX_SERIAL=m
 CONFIG_MTD=y
 # CONFIG_MTD_TESTS is not set
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_OF_PARTS=m
-CONFIG_MTD_AR7_PARTS=m
 
 #
 # Partition parsers
 #
+CONFIG_MTD_AR7_PARTS=m
+# CONFIG_MTD_CMDLINE_PARTS is not set
+CONFIG_MTD_OF_PARTS=m
 # CONFIG_MTD_AFS_PARTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # end of Partition parsers
@@ -1892,7 +1896,6 @@ CONFIG_MTD_PLATRAM=m
 CONFIG_MTD_DATAFLASH=m
 # CONFIG_MTD_DATAFLASH_WRITE_VERIFY is not set
 # CONFIG_MTD_DATAFLASH_OTP is not set
-CONFIG_MTD_M25P80=m
 # CONFIG_MTD_MCHP23K256 is not set
 CONFIG_MTD_SST25L=m
 # CONFIG_MTD_SLRAM is not set
@@ -1924,6 +1927,7 @@ CONFIG_MTD_NAND_ECC_SW_BCH=y
 CONFIG_MTD_NAND_OMAP2=m
 # CONFIG_MTD_NAND_OMAP_BCH is not set
 # CONFIG_MTD_NAND_BRCMNAND is not set
+# CONFIG_MTD_NAND_MXIC is not set
 # CONFIG_MTD_NAND_GPIO is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 
@@ -2180,6 +2184,7 @@ CONFIG_DM_CACHE=m
 CONFIG_DM_CACHE_SMQ=m
 CONFIG_DM_WRITECACHE=m
 CONFIG_DM_ERA=m
+# CONFIG_DM_CLONE is not set
 CONFIG_DM_MIRROR=m
 CONFIG_DM_LOG_USERSPACE=m
 # CONFIG_DM_RAID is not set
@@ -2192,6 +2197,7 @@ CONFIG_DM_DELAY=m
 CONFIG_DM_UEVENT=y
 CONFIG_DM_FLAKEY=m
 CONFIG_DM_VERITY=m
+# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set
 # CONFIG_DM_VERITY_FEC is not set
 CONFIG_DM_SWITCH=m
 CONFIG_DM_LOG_WRITES=m
@@ -2255,6 +2261,7 @@ CONFIG_ATM_DUMMY=m
 # CONFIG_NET_DSA_MT7530 is not set
 # CONFIG_NET_DSA_MV88E6060 is not set
 # CONFIG_NET_DSA_MICROCHIP_KSZ9477 is not set
+# CONFIG_NET_DSA_MICROCHIP_KSZ8795 is not set
 # CONFIG_NET_DSA_MV88E6XXX is not set
 # CONFIG_NET_DSA_SJA1105 is not set
 # CONFIG_NET_DSA_QCA8K is not set
@@ -2301,6 +2308,7 @@ CONFIG_NET_VENDOR_MICROSEMI=y
 # CONFIG_NET_VENDOR_NETRONOME is not set
 # CONFIG_NET_VENDOR_NI is not set
 # CONFIG_ETHOC is not set
+# CONFIG_NET_VENDOR_PENSANDO is not set
 # CONFIG_NET_VENDOR_QUALCOMM is not set
 # CONFIG_NET_VENDOR_RENESAS is not set
 # CONFIG_NET_VENDOR_ROCKER is not set
@@ -2347,6 +2355,7 @@ CONFIG_LED_TRIGGER_PHY=y
 # MII PHY device drivers
 #
 # CONFIG_SFP is not set
+# CONFIG_ADIN_PHY is not set
 # CONFIG_AMD_PHY is not set
 # CONFIG_AQUANTIA_PHY is not set
 # CONFIG_AX88796B_PHY is not set
@@ -2706,6 +2715,7 @@ CONFIG_JOYSTICK_XPAD_LEDS=y
 CONFIG_JOYSTICK_PSXPAD_SPI=y
 CONFIG_JOYSTICK_PSXPAD_SPI_FF=y
 CONFIG_JOYSTICK_PXRC=m
+CONFIG_JOYSTICK_FSIA6B=m
 CONFIG_INPUT_TABLET=y
 CONFIG_TABLET_USB_ACECAD=m
 CONFIG_TABLET_USB_AIPTEK=m
@@ -2830,7 +2840,6 @@ CONFIG_INPUT_UINPUT=m
 # CONFIG_INPUT_ADXL34X is not set
 # CONFIG_INPUT_IMS_PCU is not set
 # CONFIG_INPUT_CMA3000 is not set
-# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set
 # CONFIG_INPUT_DRV260X_HAPTICS is not set
 # CONFIG_INPUT_DRV2665_HAPTICS is not set
 # CONFIG_INPUT_DRV2667_HAPTICS is not set
@@ -2926,6 +2935,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
 # CONFIG_SERIAL_XILINX_PS_UART is not set
 # CONFIG_SERIAL_ARC is not set
 # CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_FSL_LINFLEXUART is not set
 # CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
 # CONFIG_SERIAL_ST_ASC is not set
 # end of Serial drivers
@@ -2958,6 +2968,8 @@ CONFIG_TCG_TIS_I2C_ATMEL=y
 # CONFIG_XILLYBUS is not set
 # end of Character devices
 
+CONFIG_RANDOM_TRUST_BOOTLOADER=y
+
 #
 # I2C support
 #
@@ -3181,6 +3193,7 @@ CONFIG_W1_MASTER_DS2482=m
 # CONFIG_W1_MASTER_DS1WM is not set
 CONFIG_W1_MASTER_GPIO=m
 CONFIG_HDQ_MASTER_OMAP=m
+# CONFIG_W1_MASTER_SGI is not set
 # end of 1-wire Bus Masters
 
 #
@@ -3199,6 +3212,7 @@ CONFIG_W1_SLAVE_DS2431=m
 CONFIG_W1_SLAVE_DS2433=m
 # CONFIG_W1_SLAVE_DS2433_CRC is not set
 CONFIG_W1_SLAVE_DS2438=m
+CONFIG_W1_SLAVE_DS250X=m
 CONFIG_W1_SLAVE_DS2780=m
 CONFIG_W1_SLAVE_DS2781=m
 CONFIG_W1_SLAVE_DS28E04=m
@@ -3278,6 +3292,7 @@ CONFIG_SENSORS_ADT7411=m
 CONFIG_SENSORS_ADT7462=m
 CONFIG_SENSORS_ADT7470=m
 CONFIG_SENSORS_ADT7475=m
+CONFIG_SENSORS_AS370=m
 CONFIG_SENSORS_ASC7621=m
 CONFIG_SENSORS_ASPEED=m
 CONFIG_SENSORS_ATXP1=m
@@ -3351,6 +3366,7 @@ CONFIG_PMBUS=m
 CONFIG_SENSORS_PMBUS=m
 CONFIG_SENSORS_ADM1275=m
 CONFIG_SENSORS_IBM_CFFPS=m
+CONFIG_SENSORS_INSPUR_IPSPS=m
 CONFIG_SENSORS_IR35221=m
 CONFIG_SENSORS_IR38064=m
 CONFIG_SENSORS_IRPS5401=m
@@ -3388,7 +3404,6 @@ CONFIG_SENSORS_SCH5636=m
 CONFIG_SENSORS_STTS751=m
 CONFIG_SENSORS_SMM665=m
 CONFIG_SENSORS_ADC128D818=m
-CONFIG_SENSORS_ADS1015=m
 CONFIG_SENSORS_ADS7828=m
 CONFIG_SENSORS_ADS7871=m
 CONFIG_SENSORS_AMC6821=m
@@ -3499,7 +3514,6 @@ CONFIG_MFD_CORE=y
 # CONFIG_MFD_BCM590XX is not set
 # CONFIG_MFD_BD9571MWV is not set
 # CONFIG_MFD_AXP20X_I2C is not set
-# CONFIG_MFD_CROS_EC is not set
 # CONFIG_MFD_MADERA is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_PMIC_DA903X is not set
@@ -3629,6 +3643,7 @@ CONFIG_REGULATOR_PWM=y
 # CONFIG_REGULATOR_SLG51000 is not set
 CONFIG_REGULATOR_TI_ABB=y
 # CONFIG_REGULATOR_SY8106A is not set
+# CONFIG_REGULATOR_SY8824X is not set
 # CONFIG_REGULATOR_TPS51632 is not set
 # CONFIG_REGULATOR_TPS62360 is not set
 # CONFIG_REGULATOR_TPS65023 is not set
@@ -3689,6 +3704,7 @@ CONFIG_MEDIA_CONTROLLER_DVB=y
 CONFIG_VIDEO_DEV=m
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L2_I2C=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
 # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_VIDEO_TUNER=m
@@ -4030,6 +4046,7 @@ CONFIG_VIDEO_OV2640=m
 # CONFIG_VIDEO_OV5647 is not set
 # CONFIG_VIDEO_OV6650 is not set
 # CONFIG_VIDEO_OV5670 is not set
+# CONFIG_VIDEO_OV5675 is not set
 # CONFIG_VIDEO_OV5695 is not set
 # CONFIG_VIDEO_OV7251 is not set
 # CONFIG_VIDEO_OV772X is not set
@@ -4333,6 +4350,7 @@ CONFIG_DVB_DUMMY_FE=m
 #
 # CONFIG_IMX_IPUV3_CORE is not set
 CONFIG_DRM=y
+CONFIG_DRM_MIPI_DBI=m
 CONFIG_DRM_MIPI_DSI=y
 CONFIG_DRM_DP_AUX_CHARDEV=y
 # CONFIG_DRM_DEBUG_MM is not set
@@ -4346,6 +4364,7 @@ CONFIG_DRM_LOAD_EDID_FIRMWARE=y
 # CONFIG_DRM_DP_CEC is not set
 CONFIG_DRM_GEM_CMA_HELPER=y
 CONFIG_DRM_KMS_CMA_HELPER=y
+CONFIG_DRM_GEM_SHMEM_HELPER=y
 
 #
 # I2C encoder or helper chips
@@ -4396,12 +4415,16 @@ CONFIG_DRM_PANEL_SIMPLE=y
 # CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set
 # CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04 is not set
 # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
+# CONFIG_DRM_PANEL_LG_LB035Q02 is not set
 # CONFIG_DRM_PANEL_LG_LG4573 is not set
+# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
+# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set
 # CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set
 # CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set
 # CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS is not set
 # CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set
 # CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set
+# CONFIG_DRM_PANEL_RAYDIUM_RM67191 is not set
 # CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set
 # CONFIG_DRM_PANEL_ROCKTECH_JH057N00900 is not set
 # CONFIG_DRM_PANEL_RONBO_RB070D30 is not set
@@ -4412,9 +4435,13 @@ CONFIG_DRM_PANEL_SIMPLE=y
 # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
 # CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set
 # CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set
+# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set
 # CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set
 # CONFIG_DRM_PANEL_SITRONIX_ST7701 is not set
 # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
+# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set
+# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
+# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set
 # CONFIG_DRM_PANEL_TPO_TPG110 is not set
 # CONFIG_DRM_PANEL_TRULY_NT35597_WQXGA is not set
 # end of Display Panels
@@ -4450,8 +4477,7 @@ CONFIG_DRM_I2C_ADV7511_CEC=y
 # CONFIG_DRM_ETNAVIV is not set
 # CONFIG_DRM_ARCPGU is not set
 # CONFIG_DRM_MXSFB is not set
-CONFIG_DRM_TINYDRM=m
-CONFIG_TINYDRM_MIPI_DBI=m
+CONFIG_DRM_GM12U320=m
 CONFIG_TINYDRM_HX8357D=m
 CONFIG_TINYDRM_ILI9225=m
 CONFIG_TINYDRM_ILI9341=m
@@ -4771,6 +4797,7 @@ CONFIG_SND_SOC_TLV320AIC3X=m
 CONFIG_SND_SOC_TS3A227E=m
 # CONFIG_SND_SOC_TSCS42XX is not set
 # CONFIG_SND_SOC_TSCS454 is not set
+# CONFIG_SND_SOC_UDA1334 is not set
 # CONFIG_SND_SOC_WM8510 is not set
 # CONFIG_SND_SOC_WM8523 is not set
 # CONFIG_SND_SOC_WM8524 is not set
@@ -4841,6 +4868,7 @@ CONFIG_HID_COUGAR=m
 CONFIG_HID_PRODIKEYS=m
 CONFIG_HID_CMEDIA=m
 CONFIG_HID_CP2112=m
+CONFIG_HID_CREATIVE_SB0540=m
 CONFIG_HID_CYPRESS=m
 CONFIG_HID_DRAGONRISE=m
 CONFIG_DRAGONRISE_FF=y
@@ -4947,6 +4975,9 @@ CONFIG_I2C_HID=m
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_COMMON=y
+CONFIG_USB_LED_TRIG=y
+# CONFIG_USB_ULPI_BUS is not set
+# CONFIG_USB_CONN_GPIO is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
@@ -4963,8 +4994,6 @@ CONFIG_USB_OTG=y
 CONFIG_USB_LEDS_TRIGGER_USBPORT=m
 CONFIG_USB_AUTOSUSPEND_DELAY=2
 CONFIG_USB_MON=m
-CONFIG_USB_WUSB_CBAF=m
-# CONFIG_USB_WUSB_CBAF_DEBUG is not set
 
 #
 # USB Host Controller Drivers
@@ -4999,21 +5028,21 @@ CONFIG_USB_TMC=m
 #
 CONFIG_USB_STORAGE=y
 # CONFIG_USB_STORAGE_DEBUG is not set
-CONFIG_USB_STORAGE_REALTEK=m
+CONFIG_USB_STORAGE_REALTEK=y
 CONFIG_REALTEK_AUTOPM=y
-CONFIG_USB_STORAGE_DATAFAB=m
-CONFIG_USB_STORAGE_FREECOM=m
-CONFIG_USB_STORAGE_ISD200=m
-CONFIG_USB_STORAGE_USBAT=m
-CONFIG_USB_STORAGE_SDDR09=m
-CONFIG_USB_STORAGE_SDDR55=m
-CONFIG_USB_STORAGE_JUMPSHOT=m
-CONFIG_USB_STORAGE_ALAUDA=m
-CONFIG_USB_STORAGE_ONETOUCH=m
-CONFIG_USB_STORAGE_KARMA=m
-CONFIG_USB_STORAGE_CYPRESS_ATACB=m
-CONFIG_USB_STORAGE_ENE_UB6250=m
-CONFIG_USB_UAS=m
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_STORAGE_ENE_UB6250=y
+CONFIG_USB_UAS=y
 
 #
 # USB Imaging devices
@@ -5027,6 +5056,7 @@ CONFIG_USBIP_VHCI_NR_HCS=8
 CONFIG_USBIP_HOST=m
 CONFIG_USBIP_VUDC=m
 # CONFIG_USBIP_DEBUG is not set
+# CONFIG_USB_CDNS3 is not set
 CONFIG_USB_MUSB_HDRC=y
 # CONFIG_USB_MUSB_HOST is not set
 # CONFIG_USB_MUSB_GADGET is not set
@@ -5254,9 +5284,6 @@ CONFIG_USB_G_DBGP_SERIAL=y
 # CONFIG_USB_G_WEBCAM is not set
 # CONFIG_TYPEC is not set
 # CONFIG_USB_ROLE_SWITCH is not set
-CONFIG_USB_LED_TRIG=y
-# CONFIG_USB_ULPI_BUS is not set
-# CONFIG_UWB is not set
 CONFIG_MMC=y
 CONFIG_PWRSEQ_EMMC=y
 # CONFIG_PWRSEQ_SD8787 is not set
@@ -5404,7 +5431,6 @@ CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RTC_DRV_PCF8583=y
 CONFIG_RTC_DRV_M41T80=y
 CONFIG_RTC_DRV_M41T80_WDT=y
-# CONFIG_RTC_DRV_BD70528 is not set
 CONFIG_RTC_DRV_BQ32K=y
 CONFIG_RTC_DRV_S35390A=y
 CONFIG_RTC_DRV_FM3130=m
@@ -5519,6 +5545,7 @@ CONFIG_ASYNC_TX_DMA=y
 CONFIG_SYNC_FILE=y
 # CONFIG_SW_SYNC is not set
 # CONFIG_UDMABUF is not set
+# CONFIG_DMABUF_SELFTESTS is not set
 # end of DMABUF options
 
 CONFIG_AUXDISPLAY=y
@@ -5545,6 +5572,8 @@ CONFIG_VIRTIO_MMIO=m
 #
 # end of Microsoft Hyper-V guest support
 
+CONFIG_GREYBUS=m
+CONFIG_GREYBUS_ES2=m
 CONFIG_STAGING=y
 # CONFIG_PRISM2_USB is not set
 # CONFIG_COMEDI is not set
@@ -5676,8 +5705,6 @@ CONFIG_FB_FLEX=m
 # CONFIG_WILC1000_SPI is not set
 # CONFIG_MOST is not set
 # CONFIG_KS7010 is not set
-CONFIG_GREYBUS=m
-CONFIG_GREYBUS_ES2=m
 CONFIG_GREYBUS_AUDIO=m
 CONFIG_GREYBUS_BOOTROM=m
 CONFIG_GREYBUS_FIRMWARE=m
@@ -5704,8 +5731,10 @@ CONFIG_GREYBUS_USB=m
 # end of Gasket devices
 
 # CONFIG_XIL_AXIS_FIFO is not set
-# CONFIG_EROFS_FS is not set
 # CONFIG_FIELDBUS_DEV is not set
+CONFIG_USB_WUSB_CBAF=m
+# CONFIG_USB_WUSB_CBAF_DEBUG is not set
+# CONFIG_UWB is not set
 CONFIG_EXFAT_FS=m
 CONFIG_EXFAT_DONT_MOUNT_VFAT=y
 CONFIG_EXFAT_DISCARD=y
@@ -5715,6 +5744,7 @@ CONFIG_EXFAT_DISCARD=y
 CONFIG_EXFAT_DEFAULT_CODEPAGE=437
 CONFIG_EXFAT_DEFAULT_IOCHARSET="utf8"
 # CONFIG_GOLDFISH is not set
+# CONFIG_MFD_CROS_EC is not set
 # CONFIG_CHROME_PLATFORMS is not set
 # CONFIG_MELLANOX_PLATFORM is not set
 CONFIG_CLKDEV_LOOKUP=y
@@ -5912,7 +5942,6 @@ CONFIG_DMARD06=m
 CONFIG_DMARD09=m
 CONFIG_DMARD10=m
 CONFIG_HID_SENSOR_ACCEL_3D=m
-# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set
 CONFIG_IIO_ST_ACCEL_3AXIS=m
 CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m
 CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m
@@ -6159,6 +6188,7 @@ CONFIG_SI7020=m
 # Inertial measurement units
 #
 CONFIG_ADIS16400=m
+CONFIG_ADIS16460=m
 CONFIG_ADIS16480=m
 CONFIG_BMI160=m
 CONFIG_BMI160_I2C=m
@@ -6201,6 +6231,7 @@ CONFIG_LTR501=m
 CONFIG_LV0104CS=m
 CONFIG_MAX44000=m
 CONFIG_MAX44009=m
+CONFIG_NOA1305=m
 CONFIG_OPT3001=m
 CONFIG_PA12203001=m
 CONFIG_SI1133=m
@@ -6273,6 +6304,7 @@ CONFIG_IIO_SYSFS_TRIGGER=m
 #
 CONFIG_AD5272=m
 CONFIG_DS1803=m
+CONFIG_MAX5432=m
 CONFIG_MAX5481=m
 CONFIG_MAX5487=m
 CONFIG_MCP4018=m
@@ -6500,6 +6532,9 @@ CONFIG_EXPORTFS_BLOCK_OPS=y
 CONFIG_FILE_LOCKING=y
 CONFIG_MANDATORY_FILE_LOCKING=y
 CONFIG_FS_ENCRYPTION=y
+CONFIG_FS_VERITY=y
+# CONFIG_FS_VERITY_DEBUG is not set
+# CONFIG_FS_VERITY_BUILTIN_SIGNATURES is not set
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -6517,6 +6552,7 @@ CONFIG_AUTOFS4_FS=y
 CONFIG_AUTOFS_FS=y
 CONFIG_FUSE_FS=y
 CONFIG_CUSE=m
+# CONFIG_VIRTIO_FS is not set
 CONFIG_OVERLAY_FS=y
 # CONFIG_OVERLAY_FS_REDIRECT_DIR is not set
 CONFIG_OVERLAY_FS_REDIRECT_ALWAYS_FOLLOW=y
@@ -6647,23 +6683,7 @@ CONFIG_ROMFS_ON_MTD=y
 # CONFIG_PSTORE is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-CONFIG_AUFS_FS=m
-CONFIG_AUFS_BRANCH_MAX_127=y
-# CONFIG_AUFS_BRANCH_MAX_511 is not set
-# CONFIG_AUFS_BRANCH_MAX_1023 is not set
-# CONFIG_AUFS_BRANCH_MAX_32767 is not set
-CONFIG_AUFS_SBILIST=y
-# CONFIG_AUFS_HNOTIFY is not set
-CONFIG_AUFS_EXPORT=y
-CONFIG_AUFS_XATTR=y
-# CONFIG_AUFS_FHSM is not set
-# CONFIG_AUFS_RDU is not set
-# CONFIG_AUFS_DIRREN is not set
-# CONFIG_AUFS_SHWH is not set
-# CONFIG_AUFS_BR_RAMFS is not set
-# CONFIG_AUFS_BR_FUSE is not set
-CONFIG_AUFS_BDEV_LOOP=y
-# CONFIG_AUFS_DEBUG is not set
+# CONFIG_EROFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V2=y
@@ -6693,7 +6713,6 @@ CONFIG_NFSD_BLOCKLAYOUT=y
 # CONFIG_NFSD_SCSILAYOUT is not set
 # CONFIG_NFSD_FLEXFILELAYOUT is not set
 CONFIG_NFSD_V4_SECURITY_LABEL=y
-# CONFIG_NFSD_FAULT_INJECTION is not set
 CONFIG_GRACE_PERIOD=y
 CONFIG_LOCKD=y
 CONFIG_LOCKD_V4=y
@@ -6831,6 +6850,7 @@ CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y
 # CONFIG_SECURITY_LOADPIN is not set
 CONFIG_SECURITY_YAMA=y
 # CONFIG_SECURITY_SAFESETID is not set
+# CONFIG_SECURITY_LOCKDOWN_LSM is not set
 CONFIG_INTEGRITY=y
 CONFIG_INTEGRITY_SIGNATURE=y
 CONFIG_INTEGRITY_ASYMMETRIC_KEYS=y
@@ -6914,10 +6934,7 @@ CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_GCM=m
 CONFIG_CRYPTO_CHACHA20POLY1305=m
 CONFIG_CRYPTO_AEGIS128=m
-CONFIG_CRYPTO_AEGIS128L=m
-CONFIG_CRYPTO_AEGIS256=m
-CONFIG_CRYPTO_MORUS640=m
-CONFIG_CRYPTO_MORUS1280=m
+CONFIG_CRYPTO_AEGIS128_SIMD=y
 CONFIG_CRYPTO_SEQIV=y
 CONFIG_CRYPTO_ECHAINIV=m
 
@@ -6936,6 +6953,7 @@ CONFIG_CRYPTO_XTS=y
 # CONFIG_CRYPTO_KEYWRAP is not set
 CONFIG_CRYPTO_NHPOLY1305=m
 CONFIG_CRYPTO_ADIANTUM=m
+CONFIG_CRYPTO_ESSIV=m
 
 #
 # Hash modes
@@ -6962,6 +6980,7 @@ CONFIG_CRYPTO_RMD160=m
 CONFIG_CRYPTO_RMD256=m
 CONFIG_CRYPTO_RMD320=m
 CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_LIB_SHA256=y
 CONFIG_CRYPTO_SHA256=y
 CONFIG_CRYPTO_SHA512=y
 CONFIG_CRYPTO_SHA3=m
@@ -6973,6 +6992,7 @@ CONFIG_CRYPTO_WP512=m
 #
 # Ciphers
 #
+CONFIG_CRYPTO_LIB_AES=y
 CONFIG_CRYPTO_AES=y
 # CONFIG_CRYPTO_AES_TI is not set
 CONFIG_CRYPTO_ANUBIS=m
@@ -6984,6 +7004,7 @@ CONFIG_CRYPTO_CAMELLIA=m
 CONFIG_CRYPTO_CAST_COMMON=m
 CONFIG_CRYPTO_CAST5=m
 CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_LIB_DES=y
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_FCRYPT=m
 CONFIG_CRYPTO_KHAZAD=m
@@ -7032,6 +7053,7 @@ CONFIG_CRYPTO_DEV_ATMEL_I2C=y
 CONFIG_CRYPTO_DEV_ATMEL_ECC=y
 CONFIG_CRYPTO_DEV_ATMEL_SHA204A=y
 CONFIG_CRYPTO_DEV_VIRTIO=m
+# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
 # CONFIG_CRYPTO_DEV_CCREE is not set
 CONFIG_ASYMMETRIC_KEY_TYPE=y
 CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
@@ -7147,7 +7169,6 @@ CONFIG_CLZ_TAB=y
 CONFIG_IRQ_POLL=y
 CONFIG_MPILIB=y
 CONFIG_SIGNATURE=y
-CONFIG_DIMLIB=y
 CONFIG_LIBFDT=y
 CONFIG_OID_REGISTRY=y
 CONFIG_UCS2_STRING=y
@@ -7185,10 +7206,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 CONFIG_STRIP_ASM_SYMS=y
 # CONFIG_READABLE_ASM is not set
-# CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_INSTALL is not set
-# CONFIG_OPTIMIZE_INLINING is not set
+CONFIG_OPTIMIZE_INLINING=y
 # CONFIG_DEBUG_SECTION_MISMATCH is not set
 CONFIG_SECTION_MISMATCH_WARN_ONLY=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
diff --git a/patches/drivers/exfat/0001-staging-exfat-add-exfat-filesystem-code-to-staging.patch b/patches/drivers/exfat/0001-staging-exfat-add-exfat-filesystem-code-to-staging.patch
deleted file mode 100644
index 7d01cc501424b8e2aca21994922ed9e3d89d218a..0000000000000000000000000000000000000000
--- a/patches/drivers/exfat/0001-staging-exfat-add-exfat-filesystem-code-to-staging.patch
+++ /dev/null
@@ -1,11019 +0,0 @@
-From c48c9f7ff32b8b3965a08e40eb6763682d905b5d Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Valdis=20Kl=C4=93tnieks?= <valdis.kletnieks@vt.edu>
-Date: Wed, 28 Aug 2019 18:08:17 +0200
-Subject: staging: exfat: add exfat filesystem code to staging
-
-The exfat code needs a lot of work to get it into "real" shape for
-the fs/ part of the kernel, so put it into drivers/staging/ for now so
-that it can be worked on by everyone in the community.
-
-The full specification of the filesystem can be found at:
-  https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification
-
-Signed-off-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
-Signed-off-by: Sasha Levin <alexander.levin@microsoft.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Link: https://lore.kernel.org/r/20190828160817.6250-1-gregkh@linuxfoundation.org
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
----
- MAINTAINERS                          |    5 +
- drivers/staging/Kconfig              |    2 +
- drivers/staging/Makefile             |    1 +
- drivers/staging/exfat/Kconfig        |   39 +
- drivers/staging/exfat/Makefile       |   10 +
- drivers/staging/exfat/TODO           |   12 +
- drivers/staging/exfat/exfat.h        |  973 ++++++++
- drivers/staging/exfat/exfat_blkdev.c |  136 ++
- drivers/staging/exfat/exfat_cache.c  |  722 ++++++
- drivers/staging/exfat/exfat_core.c   | 3704 ++++++++++++++++++++++++++++++
- drivers/staging/exfat/exfat_nls.c    |  404 ++++
- drivers/staging/exfat/exfat_super.c  | 4137 ++++++++++++++++++++++++++++++++++
- drivers/staging/exfat/exfat_upcase.c |  740 ++++++
- 13 files changed, 10885 insertions(+)
- create mode 100644 drivers/staging/exfat/Kconfig
- create mode 100644 drivers/staging/exfat/Makefile
- create mode 100644 drivers/staging/exfat/TODO
- create mode 100644 drivers/staging/exfat/exfat.h
- create mode 100644 drivers/staging/exfat/exfat_blkdev.c
- create mode 100644 drivers/staging/exfat/exfat_cache.c
- create mode 100644 drivers/staging/exfat/exfat_core.c
- create mode 100644 drivers/staging/exfat/exfat_nls.c
- create mode 100644 drivers/staging/exfat/exfat_super.c
- create mode 100644 drivers/staging/exfat/exfat_upcase.c
-
-diff --git a/MAINTAINERS b/MAINTAINERS
-index e3242687cd19..a484b36e5117 100644
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -6097,6 +6097,11 @@ F:	include/trace/events/mdio.h
- F:	include/uapi/linux/mdio.h
- F:	include/uapi/linux/mii.h
- 
-+EXFAT FILE SYSTEM
-+M:	Valdis Kletnieks <valdis.kletnieks@vt.edu>
-+S:	Maintained
-+F:	fs/exfat/
-+
- EXT2 FILE SYSTEM
- M:	Jan Kara <jack@suse.com>
- L:	linux-ext4@vger.kernel.org
-diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
-index d972ec8e71fb..fbdc33874780 100644
---- a/drivers/staging/Kconfig
-+++ b/drivers/staging/Kconfig
-@@ -118,4 +118,6 @@ source "drivers/staging/kpc2000/Kconfig"
- 
- source "drivers/staging/isdn/Kconfig"
- 
-+source "drivers/staging/exfat/Kconfig"
-+
- endif # STAGING
-diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
-index 6018b9a4a077..ca13f87b1e1b 100644
---- a/drivers/staging/Makefile
-+++ b/drivers/staging/Makefile
-@@ -49,3 +49,4 @@ obj-$(CONFIG_XIL_AXIS_FIFO)	+= axis-fifo/
- obj-$(CONFIG_FIELDBUS_DEV)     += fieldbus/
- obj-$(CONFIG_KPC2000)		+= kpc2000/
- obj-$(CONFIG_ISDN_CAPI)		+= isdn/
-+obj-$(CONFIG_EXFAT_FS)		+= exfat/
-diff --git a/drivers/staging/exfat/Kconfig b/drivers/staging/exfat/Kconfig
-new file mode 100644
-index 000000000000..78b32aa2ca19
---- /dev/null
-+++ b/drivers/staging/exfat/Kconfig
-@@ -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.
-diff --git a/drivers/staging/exfat/Makefile b/drivers/staging/exfat/Makefile
-new file mode 100644
-index 000000000000..84944dfbae28
---- /dev/null
-+++ b/drivers/staging/exfat/Makefile
-@@ -0,0 +1,10 @@
-+# SPDX-License-Identifier: GPL-2.0
-+
-+obj-$(CONFIG_EXFAT_FS) += exfat.o
-+
-+exfat-y :=	exfat_core.o	\
-+		exfat_super.o	\
-+		exfat_blkdev.o	\
-+		exfat_cache.o	\
-+		exfat_nls.o	\
-+		exfat_upcase.o
-diff --git a/drivers/staging/exfat/TODO b/drivers/staging/exfat/TODO
-new file mode 100644
-index 000000000000..a3eb282f9efc
---- /dev/null
-+++ b/drivers/staging/exfat/TODO
-@@ -0,0 +1,12 @@
-+exfat_core.c - ffsReadFile - the goto err_out seem to leak a brelse().
-+same for ffsWriteFile.
-+
-+exfat_core.c - fs_sync(sb,0) all over the place looks fishy as hell.
-+There's only one place that calls it with a non-zero argument.
-+
-+ffsTruncateFile -  if (old_size <= new_size) {
-+That doesn't look right. How did it ever work? Are they relying on lazy
-+block allocation when actual writes happen? If nothing else, it never
-+does the 'fid->size = new_size' and do the inode update....
-+
-+ffsSetAttr() is just dangling in the breeze, not wired up at all...
-diff --git a/drivers/staging/exfat/exfat.h b/drivers/staging/exfat/exfat.h
-new file mode 100644
-index 000000000000..bae180e10609
---- /dev/null
-+++ b/drivers/staging/exfat/exfat.h
-@@ -0,0 +1,973 @@
-+/* SPDX-License-Identifier: GPL-2.0 */
-+/*
-+ *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
-+ */
-+
-+#ifndef _EXFAT_H
-+#define _EXFAT_H
-+
-+#include <linux/types.h>
-+#include <linux/buffer_head.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 available 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 */
-+
-+#ifdef CONFIG_EXFAT_DEBUG_MSG
-+#define DEBUG	1
-+#else
-+#undef DEBUG
-+#endif
-+
-+#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 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
-+
-+/* 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
-+
-+/* Upcase table macro */
-+#define HIGH_INDEX_BIT	(8)
-+#define HIGH_INDEX_MASK	(0xFF00)
-+#define LOW_INDEX_BIT	(16-HIGH_INDEX_BIT)
-+#define UTBL_ROW_COUNT	(1<<LOW_INDEX_BIT)
-+#define UTBL_COL_COUNT	(1<<HIGH_INDEX_BIT)
-+
-+static inline u16 get_col_index(u16 i)
-+{
-+	return i >> LOW_INDEX_BIT;
-+}
-+static inline u16 get_row_index(u16 i)
-+{
-+	return i & ~HIGH_INDEX_MASK;
-+}
-+
-+#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 filename including NULL */
-+#define MAX_PATH_LENGTH		260	/* max len of pathname including NULL */
-+#define DOS_NAME_LENGTH		11	/* DOS filename length excluding NULL */
-+#define DOS_PATH_LENGTH		80	/* DOS pathname 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
-+
-+#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
-+
-+struct date_time_t {
-+	u16      Year;
-+	u16      Month;
-+	u16      Day;
-+	u16      Hour;
-+	u16      Minute;
-+	u16      Second;
-+	u16      MilliSecond;
-+};
-+
-+struct part_info_t {
-+	u32      Offset;    /* start sector number of the partition */
-+	u32      Size;      /* in sectors */
-+};
-+
-+struct dev_info_t {
-+	u32      SecSize;    /* sector size in bytes */
-+	u32      DevSize;    /* block device size in sectors */
-+};
-+
-+struct vol_info_t {
-+	u32      FatType;
-+	u32      ClusterSize;
-+	u32      NumClusters;
-+	u32      FreeClusters;
-+	u32      UsedClusters;
-+};
-+
-+/* directory structure */
-+struct chain_t {
-+	u32      dir;
-+	s32       size;
-+	u8       flags;
-+};
-+
-+struct file_id_t {
-+	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;
-+};
-+
-+struct dir_entry_t {
-+	char Name[MAX_NAME_LENGTH * MAX_CHARSET_SIZE];
-+
-+	/* used only for FAT12/16/32, not used for exFAT */
-+	char ShortName[DOS_NAME_LENGTH + 2];
-+
-+	u32 Attr;
-+	u64 Size;
-+	u32 NumSubdirs;
-+	struct date_time_t CreateTimestamp;
-+	struct date_time_t ModifyTimestamp;
-+	struct date_time_t AccessTimestamp;
-+};
-+
-+struct timestamp_t {
-+	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) */
-+};
-+
-+/* MS_DOS FAT partition boot record (512 bytes) */
-+struct pbr_sector_t {
-+	u8       jmp_boot[3];
-+	u8       oem_name[8];
-+	u8       bpb[109];
-+	u8       boot_code[390];
-+	u8       signature[2];
-+};
-+
-+/* MS-DOS FAT12/16 BIOS parameter block (51 bytes) */
-+struct bpb16_t {
-+	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];
-+};
-+
-+/* MS-DOS FAT32 BIOS parameter block (79 bytes) */
-+struct bpb32_t {
-+	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];
-+};
-+
-+/* MS-DOS EXFAT BIOS parameter block (109 bytes) */
-+struct bpbex_t {
-+	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];
-+};
-+
-+/* MS-DOS FAT file system information sector (512 bytes) */
-+struct fsi_sector_t {
-+	u8       signature1[4];
-+	u8       reserved1[480];
-+	u8       signature2[4];
-+	u8       free_cluster[4];
-+	u8       next_cluster[4];
-+	u8       reserved2[14];
-+	u8       signature3[2];
-+};
-+
-+/* MS-DOS FAT directory entry (32 bytes) */
-+struct dentry_t {
-+	u8       dummy[32];
-+};
-+
-+struct dos_dentry_t {
-+	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];
-+};
-+
-+/* MS-DOS FAT extended directory entry (32 bytes) */
-+struct ext_dentry_t {
-+	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];
-+};
-+
-+/* MS-DOS EXFAT file directory entry (32 bytes) */
-+struct file_dentry_t {
-+	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];
-+};
-+
-+/* MS-DOS EXFAT stream extension directory entry (32 bytes) */
-+struct strm_dentry_t {
-+	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];
-+};
-+
-+/* MS-DOS EXFAT file name directory entry (32 bytes) */
-+struct name_dentry_t {
-+	u8       type;
-+	u8       flags;
-+	u8       unicode_0_14[30];
-+};
-+
-+/* MS-DOS EXFAT allocation bitmap directory entry (32 bytes) */
-+struct bmap_dentry_t {
-+	u8       type;
-+	u8       flags;
-+	u8       reserved[18];
-+	u8       start_clu[4];
-+	u8       size[8];
-+};
-+
-+/* MS-DOS EXFAT up-case table directory entry (32 bytes) */
-+struct case_dentry_t {
-+	u8       type;
-+	u8       reserved1[3];
-+	u8       checksum[4];
-+	u8       reserved2[12];
-+	u8       start_clu[4];
-+	u8       size[8];
-+};
-+
-+/* MS-DOS EXFAT volume label directory entry (32 bytes) */
-+struct volm_dentry_t {
-+	u8       type;
-+	u8       label_len;
-+	u8       unicode_0_10[22];
-+	u8       reserved[8];
-+};
-+
-+/* unused entry hint information */
-+struct uentry_t {
-+	u32      dir;
-+	s32       entry;
-+	struct chain_t     clu;
-+};
-+
-+/* DOS name structure */
-+struct dos_name_t {
-+	u8       name[DOS_NAME_LENGTH];
-+	u8       name_case;
-+};
-+
-+/* unicode name structure */
-+struct uni_name_t {
-+	u16      name[MAX_NAME_LENGTH];
-+	u16      name_hash;
-+	u8       name_len;
-+};
-+
-+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;
-+};
-+
-+struct fs_func {
-+	s32	(*alloc_cluster)(struct super_block *sb, s32 num_alloc,
-+				 struct chain_t *p_chain);
-+	void	(*free_cluster)(struct super_block *sb, struct chain_t *p_chain,
-+				s32 do_relse);
-+	s32	(*count_used_clusters)(struct super_block *sb);
-+
-+	s32	(*init_dir_entry)(struct super_block *sb, struct chain_t *p_dir,
-+				  s32 entry, u32 type, u32 start_clu, u64 size);
-+	s32	(*init_ext_entry)(struct super_block *sb, struct chain_t *p_dir,
-+				  s32 entry, s32 num_entries,
-+				  struct uni_name_t *p_uniname,
-+				  struct dos_name_t *p_dosname);
-+	s32	(*find_dir_entry)(struct super_block *sb, struct chain_t *p_dir,
-+				  struct uni_name_t *p_uniname, s32 num_entries,
-+				  struct dos_name_t *p_dosname, u32 type);
-+	void	(*delete_dir_entry)(struct super_block *sb,
-+				    struct chain_t *p_dir, s32 entry,
-+				    s32 offset, s32 num_entries);
-+	void	(*get_uni_name_from_ext_entry)(struct super_block *sb,
-+					       struct chain_t *p_dir, s32 entry,
-+					       u16 *uniname);
-+	s32	(*count_ext_entries)(struct super_block *sb,
-+				     struct chain_t *p_dir, s32 entry,
-+				     struct dentry_t *p_entry);
-+	s32	(*calc_num_entries)(struct uni_name_t *p_uniname);
-+
-+	u32	(*get_entry_type)(struct dentry_t *p_entry);
-+	void	(*set_entry_type)(struct dentry_t *p_entry, u32 type);
-+	u32	(*get_entry_attr)(struct dentry_t *p_entry);
-+	void	(*set_entry_attr)(struct dentry_t *p_entry, u32 attr);
-+	u8	(*get_entry_flag)(struct dentry_t *p_entry);
-+	void	(*set_entry_flag)(struct dentry_t *p_entry, u8 flag);
-+	u32	(*get_entry_clu0)(struct dentry_t *p_entry);
-+	void	(*set_entry_clu0)(struct dentry_t *p_entry, u32 clu0);
-+	u64	(*get_entry_size)(struct dentry_t *p_entry);
-+	void	(*set_entry_size)(struct dentry_t *p_entry, u64 size);
-+	void	(*get_entry_time)(struct dentry_t *p_entry,
-+				  struct timestamp_t *tp, u8 mode);
-+	void	(*set_entry_time)(struct dentry_t *p_entry,
-+				  struct timestamp_t *tp, u8 mode);
-+};
-+
-+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 */
-+	struct uentry_t hint_uentry;	/* unused entry hint information */
-+
-+	u32 dev_ejected;	/* block device operation error flag */
-+
-+	struct fs_func *fs_func;
-+	struct semaphore v_sem;
-+
-+	/* FAT cache */
-+	struct buf_cache_t FAT_cache_array[FAT_CACHE_SIZE];
-+	struct buf_cache_t FAT_cache_lru_list;
-+	struct buf_cache_t FAT_cache_hash_list[FAT_CACHE_HASH_SIZE];
-+
-+	/* buf cache */
-+	struct buf_cache_t buf_cache_array[BUF_CACHE_SIZE];
-+	struct buf_cache_t buf_cache_lru_list;
-+	struct buf_cache_t buf_cache_hash_list[BUF_CACHE_HASH_SIZE];
-+};
-+
-+#define ES_2_ENTRIES		2
-+#define ES_3_ENTRIES		3
-+#define ES_ALL_ENTRIES		0
-+
-+struct entry_set_cache_t {
-+	/* sector number that contains file_entry */
-+	sector_t sector;
-+
-+	/* byte offset in the sector */
-+	s32 offset;
-+
-+	/*
-+	 * flag in stream entry.
-+	 * 01 for cluster chain,
-+	 * 03 for contig. clusteres.
-+	 */
-+	s32 alloc_flag;
-+
-+	u32 num_entries;
-+
-+	/* __buf should be the last member */
-+	void *__buf;
-+};
-+
-+#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 {
-+	kuid_t fs_uid;
-+	kgid_t fs_gid;
-+	unsigned short fs_fmask;
-+	unsigned short fs_dmask;
-+
-+	/* permission for setting the [am]time */
-+	unsigned short allow_utime;
-+
-+	/* codepage for shortname conversions */
-+	unsigned short codepage;
-+
-+	/* charset for filename input/display */
-+	char *iocharset;
-+
-+	unsigned char casesensitive;
-+
-+	/* on error: continue, panic, remount-ro */
-+	unsigned char errors;
-+#ifdef CONFIG_EXFAT_DISCARD
-+	/* flag on if -o dicard specified and device support discard() */
-+	unsigned char discard;
-+#endif /* CONFIG_EXFAT_DISCARD */
-+};
-+
-+#define EXFAT_HASH_BITS		8
-+#define EXFAT_HASH_SIZE		(1UL << EXFAT_HASH_BITS)
-+
-+/*
-+ * EXFAT file system in-core superblock data
-+ */
-+struct bd_info_t {
-+	s32 sector_size;	/* in bytes */
-+	s32 sector_size_bits;
-+	s32 sector_size_mask;
-+
-+	/* total number of sectors in this block device */
-+	s32 num_sectors;
-+
-+	/* opened or not */
-+	bool opened;
-+};
-+
-+struct exfat_sb_info {
-+	struct fs_info_t fs_info;
-+	struct bd_info_t bd_info;
-+
-+	struct exfat_mount_options options;
-+
-+	int s_dirt;
-+	struct mutex s_lock;
-+	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 {
-+	struct 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 */
-+	struct rw_semaphore truncate_lock;
-+	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);
-+}
-+
-+/* NLS management function */
-+u16 nls_upper(struct super_block *sb, u16 a);
-+int nls_dosname_cmp(struct super_block *sb, u8 *a, u8 *b);
-+int nls_uniname_cmp(struct super_block *sb, u16 *a, u16 *b);
-+void nls_uniname_to_dosname(struct super_block *sb,
-+			    struct dos_name_t *p_dosname,
-+			    struct uni_name_t *p_uniname, bool *p_lossy);
-+void nls_dosname_to_uniname(struct super_block *sb,
-+			    struct uni_name_t *p_uniname,
-+			    struct dos_name_t *p_dosname);
-+void nls_uniname_to_cstring(struct super_block *sb, u8 *p_cstring,
-+			    struct uni_name_t *p_uniname);
-+void nls_cstring_to_uniname(struct super_block *sb,
-+			    struct uni_name_t *p_uniname, u8 *p_cstring,
-+			    bool *p_lossy);
-+
-+/* buffer cache management */
-+void buf_init(struct super_block *sb);
-+void buf_shutdown(struct super_block *sb);
-+int 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);
-+
-+/* fs management functions */
-+void fs_set_vol_flags(struct super_block *sb, u32 new_flag);
-+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,
-+		      struct chain_t *p_chain);
-+s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc,
-+			struct chain_t *p_chain);
-+void fat_free_cluster(struct super_block *sb, struct chain_t *p_chain,
-+		      s32 do_relse);
-+void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain,
-+			s32 do_relse);
-+u32 find_last_cluster(struct super_block *sb, struct chain_t *p_chain);
-+s32 count_num_clusters(struct super_block *sb, struct 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(struct dentry_t *p_entry);
-+u32 exfat_get_entry_type(struct dentry_t *p_entry);
-+void fat_set_entry_type(struct dentry_t *p_entry, u32 type);
-+void exfat_set_entry_type(struct dentry_t *p_entry, u32 type);
-+u32 fat_get_entry_attr(struct dentry_t *p_entry);
-+u32 exfat_get_entry_attr(struct dentry_t *p_entry);
-+void fat_set_entry_attr(struct dentry_t *p_entry, u32 attr);
-+void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr);
-+u8 fat_get_entry_flag(struct dentry_t *p_entry);
-+u8 exfat_get_entry_flag(struct dentry_t *p_entry);
-+void fat_set_entry_flag(struct dentry_t *p_entry, u8 flag);
-+void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flag);
-+u32 fat_get_entry_clu0(struct dentry_t *p_entry);
-+u32 exfat_get_entry_clu0(struct dentry_t *p_entry);
-+void fat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu);
-+void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu);
-+u64 fat_get_entry_size(struct dentry_t *p_entry);
-+u64 exfat_get_entry_size(struct dentry_t *p_entry);
-+void fat_set_entry_size(struct dentry_t *p_entry, u64 size);
-+void exfat_set_entry_size(struct dentry_t *p_entry, u64 size);
-+struct timestamp_t *tm_current(struct timestamp_t *tm);
-+void fat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
-+			u8 mode);
-+void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
-+			  u8 mode);
-+void fat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
-+			u8 mode);
-+void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
-+			  u8 mode);
-+s32 fat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir, s32 entry,
-+		       u32 type, u32 start_clu, u64 size);
-+s32 exfat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+			 s32 entry, u32 type, u32 start_clu, u64 size);
-+s32 fat_init_ext_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+			   s32 entry, s32 num_entries,
-+			   struct uni_name_t *p_uniname,
-+			   struct dos_name_t *p_dosname);
-+s32 exfat_init_ext_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+			     s32 entry, s32 num_entries,
-+			     struct uni_name_t *p_uniname,
-+		struct dos_name_t *p_dosname);
-+void init_dos_entry(struct dos_dentry_t *ep, u32 type, u32 start_clu);
-+void init_ext_entry(struct ext_dentry_t *ep, s32 order, u8 chksum,
-+		    u16 *uniname);
-+void init_file_entry(struct file_dentry_t *ep, u32 type);
-+void init_strm_entry(struct strm_dentry_t *ep, u8 flags, u32 start_clu,
-+		     u64 size);
-+void init_name_entry(struct name_dentry_t *ep, u16 *uniname);
-+void fat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+			  s32 entry, s32 order, s32 num_entries);
-+void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+			    s32 entry, s32 order, s32 num_entries);
-+
-+s32 find_location(struct super_block *sb, struct chain_t *p_dir, s32 entry,
-+		  sector_t *sector, s32 *offset);
-+struct dentry_t *get_entry_with_sector(struct super_block *sb, sector_t sector,
-+				       s32 offset);
-+struct dentry_t *get_entry_in_dir(struct super_block *sb, struct chain_t *p_dir,
-+				  s32 entry, sector_t *sector);
-+struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb,
-+					       struct chain_t *p_dir, s32 entry,
-+					       u32 type,
-+					       struct dentry_t **file_ep);
-+void release_entry_set(struct entry_set_cache_t *es);
-+s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es);
-+s32 write_partial_entries_in_entry_set(struct super_block *sb,
-+				       struct entry_set_cache_t *es,
-+				       struct dentry_t *ep, u32 count);
-+s32 search_deleted_or_unused_entry(struct super_block *sb,
-+				   struct chain_t *p_dir, s32 num_entries);
-+s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir,
-+		     s32 num_entries);
-+s32 fat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+		       struct uni_name_t *p_uniname, s32 num_entries,
-+		       struct dos_name_t *p_dosname, u32 type);
-+s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+			 struct uni_name_t *p_uniname, s32 num_entries,
-+			 struct dos_name_t *p_dosname, u32 type);
-+s32 fat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir,
-+			  s32 entry, struct dentry_t *p_entry);
-+s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir,
-+			    s32 entry, struct dentry_t *p_entry);
-+s32 count_dos_name_entries(struct super_block *sb, struct chain_t *p_dir,
-+			   u32 type);
-+void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir,
-+			 s32 entry);
-+void update_dir_checksum_with_entry_set(struct super_block *sb,
-+					struct entry_set_cache_t *es);
-+bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir);
-+
-+/* name conversion functions */
-+s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir,
-+				 struct uni_name_t *p_uniname, s32 *entries,
-+				 struct dos_name_t *p_dosname);
-+void get_uni_name_from_dos_entry(struct super_block *sb,
-+				 struct dos_dentry_t *ep,
-+				 struct uni_name_t *p_uniname, u8 mode);
-+void fat_get_uni_name_from_ext_entry(struct super_block *sb,
-+				     struct chain_t *p_dir, s32 entry,
-+				     u16 *uniname);
-+void exfat_get_uni_name_from_ext_entry(struct super_block *sb,
-+				       struct chain_t *p_dir, s32 entry,
-+				       u16 *uniname);
-+s32 extract_uni_name_from_ext_entry(struct ext_dentry_t *ep,
-+				    u16 *uniname, s32 order);
-+s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep,
-+				     u16 *uniname, s32 order);
-+s32 fat_generate_dos_name(struct super_block *sb, struct chain_t *p_dir,
-+			  struct dos_name_t *p_dosname);
-+void fat_attach_count_to_dos_name(u8 *dosname, s32 count);
-+s32 fat_calc_num_entries(struct uni_name_t *p_uniname);
-+s32 exfat_calc_num_entries(struct 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, struct chain_t *p_dir,
-+		 struct uni_name_t *p_uniname);
-+s32 resolve_name(u8 *name, u8 **arg);
-+
-+/* file operation functions */
-+s32 fat16_mount(struct super_block *sb, struct pbr_sector_t *p_pbr);
-+s32 fat32_mount(struct super_block *sb, struct pbr_sector_t *p_pbr);
-+s32 exfat_mount(struct super_block *sb, struct pbr_sector_t *p_pbr);
-+s32 create_dir(struct inode *inode, struct chain_t *p_dir,
-+	       struct uni_name_t *p_uniname, struct file_id_t *fid);
-+s32 create_file(struct inode *inode, struct chain_t *p_dir,
-+		struct uni_name_t *p_uniname, u8 mode, struct file_id_t *fid);
-+void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry);
-+s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 old_entry,
-+		struct uni_name_t *p_uniname, struct file_id_t *fid);
-+s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry,
-+	      struct chain_t *p_newdir, struct uni_name_t *p_uniname,
-+	      struct file_id_t *fid);
-+
-+/* sector read/write functions */
-+int sector_read(struct super_block *sb, sector_t sec,
-+		struct buffer_head **bh, bool read);
-+int sector_write(struct super_block *sb, sector_t sec,
-+		 struct buffer_head *bh, bool sync);
-+int multi_sector_read(struct super_block *sb, sector_t sec,
-+		      struct buffer_head **bh, s32 num_secs, bool read);
-+int multi_sector_write(struct super_block *sb, sector_t sec,
-+		       struct buffer_head *bh, s32 num_secs, bool sync);
-+
-+void bdev_open(struct super_block *sb);
-+void bdev_close(struct super_block *sb);
-+int bdev_read(struct super_block *sb, sector_t secno,
-+	      struct buffer_head **bh, u32 num_secs, bool read);
-+int bdev_write(struct super_block *sb, sector_t secno,
-+	       struct buffer_head *bh, u32 num_secs, bool sync);
-+int bdev_sync(struct super_block *sb);
-+
-+extern const u8 uni_upcase[];
-+#endif /* _EXFAT_H */
-diff --git a/drivers/staging/exfat/exfat_blkdev.c b/drivers/staging/exfat/exfat_blkdev.c
-new file mode 100644
-index 000000000000..f086c75e7076
---- /dev/null
-+++ b/drivers/staging/exfat/exfat_blkdev.c
-@@ -0,0 +1,136 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
-+ */
-+
-+#include <linux/blkdev.h>
-+#include <linux/buffer_head.h>
-+#include <linux/fs.h>
-+#include "exfat.h"
-+
-+void bdev_open(struct super_block *sb)
-+{
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	if (p_bd->opened)
-+		return;
-+
-+	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;
-+}
-+
-+void bdev_close(struct super_block *sb)
-+{
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	p_bd->opened = false;
-+}
-+
-+int bdev_read(struct super_block *sb, sector_t secno, struct buffer_head **bh,
-+	      u32 num_secs, bool read)
-+{
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+	struct 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 0;
-+
-+	WARN(!p_fs->dev_ejected,
-+	     "[EXFAT] No bh, device seems wrong or to be ejected.\n");
-+
-+	return FFS_MEDIAERR;
-+}
-+
-+int bdev_write(struct super_block *sb, sector_t secno, struct buffer_head *bh,
-+	       u32 num_secs, bool sync)
-+{
-+	s32 count;
-+	struct buffer_head *bh2;
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+	struct 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)
-+			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 0;
-+
-+no_bh:
-+	WARN(!p_fs->dev_ejected,
-+	     "[EXFAT] No bh, device seems wrong or to be ejected.\n");
-+
-+	return FFS_MEDIAERR;
-+}
-+
-+int bdev_sync(struct super_block *sb)
-+{
-+	struct 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);
-+}
-diff --git a/drivers/staging/exfat/exfat_cache.c b/drivers/staging/exfat/exfat_cache.c
-new file mode 100644
-index 000000000000..f05d692c2b1e
---- /dev/null
-+++ b/drivers/staging/exfat/exfat_cache.c
-@@ -0,0 +1,722 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
-+ */
-+
-+#include <linux/buffer_head.h>
-+#include <linux/fs.h>
-+#include <linux/mutex.h>
-+#include "exfat.h"
-+
-+#define LOCKBIT		0x01
-+#define DIRTYBIT	0x02
-+
-+/* Local variables */
-+static DEFINE_SEMAPHORE(f_sem);
-+static DEFINE_SEMAPHORE(b_sem);
-+
-+static struct buf_cache_t *FAT_cache_find(struct super_block *sb, sector_t sec)
-+{
-+	s32 off;
-+	struct buf_cache_t *bp, *hp;
-+	struct 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;
-+}
-+
-+static void push_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list)
-+{
-+	bp->next = list->next;
-+	bp->prev = list;
-+	list->next->prev = bp;
-+	list->next = bp;
-+}
-+
-+static void push_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list)
-+{
-+	bp->prev = list->prev;
-+	bp->next = list;
-+	list->prev->next = bp;
-+	list->prev = bp;
-+}
-+
-+static void move_to_mru(struct buf_cache_t *bp, struct buf_cache_t *list)
-+{
-+	bp->prev->next = bp->next;
-+	bp->next->prev = bp->prev;
-+	push_to_mru(bp, list);
-+}
-+
-+static void move_to_lru(struct buf_cache_t *bp, struct buf_cache_t *list)
-+{
-+	bp->prev->next = bp->next;
-+	bp->next->prev = bp->prev;
-+	push_to_lru(bp, list);
-+}
-+
-+static struct buf_cache_t *FAT_cache_get(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+	struct 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;
-+}
-+
-+static void FAT_cache_insert_hash(struct super_block *sb,
-+				  struct buf_cache_t *bp)
-+{
-+	s32 off;
-+	struct buf_cache_t *hp;
-+	struct 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;
-+}
-+
-+static void FAT_cache_remove_hash(struct buf_cache_t *bp)
-+{
-+	(bp->hash_prev)->hash_next = bp->hash_next;
-+	(bp->hash_next)->hash_prev = bp->hash_prev;
-+}
-+
-+static void buf_cache_insert_hash(struct super_block *sb,
-+				  struct buf_cache_t *bp)
-+{
-+	s32 off;
-+	struct buf_cache_t *hp;
-+	struct 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;
-+}
-+
-+static void buf_cache_remove_hash(struct buf_cache_t *bp)
-+{
-+	(bp->hash_prev)->hash_next = bp->hash_next;
-+	(bp->hash_next)->hash_prev = bp->hash_prev;
-+}
-+
-+void buf_init(struct super_block *sb)
-+{
-+	struct 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;
-+	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 = NULL;
-+		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;
-+	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 = NULL;
-+		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];
-+		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];
-+		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]);
-+}
-+
-+void buf_shutdown(struct super_block *sb)
-+{
-+}
-+
-+static int __FAT_read(struct super_block *sb, u32 loc, u32 *content)
-+{
-+	s32 off;
-+	u32 _content;
-+	sector_t sec;
-+	u8 *fat_sector, *fat_entry;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct 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;
-+		}
-+		*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;
-+		}
-+		*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;
-+		}
-+		*content = CLUSTER_32(_content);
-+		return 0;
-+	} else if (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];
-+		_content = GET32_A(fat_entry);
-+
-+		if (_content >= CLUSTER_32(0xFFFFFFF8)) {
-+			*content = CLUSTER_32(~0);
-+			return 0;
-+		}
-+		*content = CLUSTER_32(_content);
-+		return 0;
-+	}
-+
-+	/* Unknown volume type, throw in the towel and go home */
-+	*content = CLUSTER_32(~0);
-+	return 0;
-+}
-+
-+/* in : sb, loc
-+ * out: content
-+ * returns 0 on success
-+ *            -1 on error
-+ */
-+int FAT_read(struct super_block *sb, u32 loc, u32 *content)
-+{
-+	s32 ret;
-+
-+	down(&f_sem);
-+	ret = __FAT_read(sb, loc, content);
-+	up(&f_sem);
-+
-+	return ret;
-+}
-+
-+static s32 __FAT_write(struct super_block *sb, u32 loc, u32 content)
-+{
-+	s32 off;
-+	sector_t sec;
-+	u8 *fat_sector, *fat_entry;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct 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;
-+}
-+
-+int FAT_write(struct super_block *sb, u32 loc, u32 content)
-+{
-+	s32 ret;
-+
-+	down(&f_sem);
-+	ret = __FAT_write(sb, loc, content);
-+	up(&f_sem);
-+
-+	return ret;
-+}
-+
-+u8 *FAT_getblk(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	bp = FAT_cache_find(sb, sec);
-+	if (bp) {
-+		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;
-+}
-+
-+void FAT_modify(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+
-+	bp = FAT_cache_find(sb, sec);
-+	if (bp)
-+		sector_write(sb, sec, bp->buf_bh, 0);
-+}
-+
-+void FAT_release_all(struct super_block *sb)
-+{
-+	struct buf_cache_t *bp;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	down(&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;
-+	}
-+
-+	up(&f_sem);
-+}
-+
-+void FAT_sync(struct super_block *sb)
-+{
-+	struct buf_cache_t *bp;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	down(&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;
-+	}
-+
-+	up(&f_sem);
-+}
-+
-+static struct buf_cache_t *buf_cache_find(struct super_block *sb, sector_t sec)
-+{
-+	s32 off;
-+	struct buf_cache_t *bp, *hp;
-+	struct 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;
-+}
-+
-+static struct buf_cache_t *buf_cache_get(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+	struct 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;
-+}
-+
-+static u8 *__buf_getblk(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	bp = buf_cache_find(sb, sec);
-+	if (bp) {
-+		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;
-+}
-+
-+u8 *buf_getblk(struct super_block *sb, sector_t sec)
-+{
-+	u8 *buf;
-+
-+	down(&b_sem);
-+	buf = __buf_getblk(sb, sec);
-+	up(&b_sem);
-+
-+	return buf;
-+}
-+
-+void buf_modify(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+
-+	down(&b_sem);
-+
-+	bp = buf_cache_find(sb, sec);
-+	if (likely(bp))
-+		sector_write(sb, sec, bp->buf_bh, 0);
-+
-+	WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
-+	     (unsigned long long)sec);
-+
-+	up(&b_sem);
-+}
-+
-+void buf_lock(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+
-+	down(&b_sem);
-+
-+	bp = buf_cache_find(sb, sec);
-+	if (likely(bp))
-+		bp->flag |= LOCKBIT;
-+
-+	WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
-+	     (unsigned long long)sec);
-+
-+	up(&b_sem);
-+}
-+
-+void buf_unlock(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+
-+	down(&b_sem);
-+
-+	bp = buf_cache_find(sb, sec);
-+	if (likely(bp))
-+		bp->flag &= ~(LOCKBIT);
-+
-+	WARN(!bp, "[EXFAT] failed to find buffer_cache(sector:%llu).\n",
-+	     (unsigned long long)sec);
-+
-+	up(&b_sem);
-+}
-+
-+void buf_release(struct super_block *sb, sector_t sec)
-+{
-+	struct buf_cache_t *bp;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	down(&b_sem);
-+
-+	bp = buf_cache_find(sb, sec);
-+	if (likely(bp)) {
-+		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);
-+	}
-+
-+	up(&b_sem);
-+}
-+
-+void buf_release_all(struct super_block *sb)
-+{
-+	struct buf_cache_t *bp;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	down(&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;
-+	}
-+
-+	up(&b_sem);
-+}
-+
-+void buf_sync(struct super_block *sb)
-+{
-+	struct buf_cache_t *bp;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	down(&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;
-+	}
-+
-+	up(&b_sem);
-+}
-diff --git a/drivers/staging/exfat/exfat_core.c b/drivers/staging/exfat/exfat_core.c
-new file mode 100644
-index 000000000000..9f76ca175c80
---- /dev/null
-+++ b/drivers/staging/exfat/exfat_core.c
-@@ -0,0 +1,3704 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
-+ */
-+
-+#include <linux/types.h>
-+#include <linux/buffer_head.h>
-+#include <linux/fs.h>
-+#include <linux/mutex.h>
-+#include <linux/blkdev.h>
-+#include <linux/slab.h>
-+#include "exfat.h"
-+
-+
-+static void __set_sb_dirty(struct super_block *sb)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+
-+	sbi->s_dirt = 1;
-+}
-+
-+static u8 name_buf[MAX_PATH_LENGTH * MAX_CHARSET_SIZE];
-+
-+static char *reserved_names[] = {
-+	"AUX     ", "CON     ", "NUL     ", "PRN     ",
-+	"COM1    ", "COM2    ", "COM3    ", "COM4    ",
-+	"COM5    ", "COM6    ", "COM7    ", "COM8    ", "COM9    ",
-+	"LPT1    ", "LPT2    ", "LPT3    ", "LPT4    ",
-+	"LPT5    ", "LPT6    ", "LPT7    ", "LPT8    ", "LPT9    ",
-+	NULL
-+};
-+
-+static u8 free_bit[] = {
-+	0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, /*   0 ~  19 */
-+	0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, /*  20 ~  39 */
-+	0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /*  40 ~  59 */
-+	0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, /*  60 ~  79 */
-+	0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, 0, 1, 0, 2, /*  80 ~  99 */
-+	0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, /* 100 ~ 119 */
-+	0, 1, 0, 2, 0, 1, 0, 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /* 120 ~ 139 */
-+	0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 5, /* 140 ~ 159 */
-+	0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, /* 160 ~ 179 */
-+	0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 6, 0, 1, 0, 2, 0, 1, 0, 3, /* 180 ~ 199 */
-+	0, 1, 0, 2, 0, 1, 0, 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, /* 200 ~ 219 */
-+	0, 1, 0, 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4, /* 220 ~ 239 */
-+	0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0                 /* 240 ~ 254 */
-+};
-+
-+static u8 used_bit[] = {
-+	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, /*   0 ~  19 */
-+	2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, /*  20 ~  39 */
-+	2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, /*  40 ~  59 */
-+	4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, /*  60 ~  79 */
-+	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, /*  80 ~  99 */
-+	3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, /* 100 ~ 119 */
-+	4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, /* 120 ~ 139 */
-+	3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, /* 140 ~ 159 */
-+	2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, /* 160 ~ 179 */
-+	4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5, /* 180 ~ 199 */
-+	3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, /* 200 ~ 219 */
-+	5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, /* 220 ~ 239 */
-+	4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8              /* 240 ~ 255 */
-+};
-+
-+#define BITMAP_LOC(v)           ((v) >> 3)
-+#define BITMAP_SHIFT(v)         ((v) & 0x07)
-+
-+static inline 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;
-+}
-+
-+static inline void exfat_bitmap_set(u8 *bitmap, int i)
-+{
-+	bitmap[BITMAP_LOC(i)] |= (0x01 << BITMAP_SHIFT(i));
-+}
-+
-+static inline void exfat_bitmap_clear(u8 *bitmap, int i)
-+{
-+	bitmap[BITMAP_LOC(i)] &= ~(0x01 << BITMAP_SHIFT(i));
-+}
-+
-+/*
-+ *  File System Management Functions
-+ */
-+
-+void fs_set_vol_flags(struct super_block *sb, u32 new_flag)
-+{
-+	struct pbr_sector_t *p_pbr;
-+	struct bpbex_t *p_bpb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (p_fs->vol_flag == new_flag)
-+		return;
-+
-+	p_fs->vol_flag = new_flag;
-+
-+	if (p_fs->vol_type == EXFAT) {
-+		if (p_fs->pbr_bh == NULL) {
-+			if (sector_read(sb, p_fs->PBR_sector,
-+					&p_fs->pbr_bh, 1) != FFS_SUCCESS)
-+				return;
-+		}
-+
-+		p_pbr = (struct pbr_sector_t *)p_fs->pbr_bh->b_data;
-+		p_bpb = (struct bpbex_t *)p_pbr->bpb;
-+		SET16(p_bpb->vol_flags, (u16)new_flag);
-+
-+		/* XXX duyoung
-+		 * what can we do here? (cuz fs_set_vol_flags() is void)
-+		 */
-+		if ((new_flag == VOL_DIRTY) && (!buffer_dirty(p_fs->pbr_bh)))
-+			sector_write(sb, p_fs->PBR_sector, p_fs->pbr_bh, 1);
-+		else
-+			sector_write(sb, p_fs->PBR_sector, p_fs->pbr_bh, 0);
-+	}
-+}
-+
-+void fs_error(struct super_block *sb)
-+{
-+	struct exfat_mount_options *opts = &EXFAT_SB(sb)->options;
-+
-+	if (opts->errors == EXFAT_ERRORS_PANIC) {
-+		panic("[EXFAT] Filesystem panic from previous error\n");
-+	} else if ((opts->errors == EXFAT_ERRORS_RO) && !sb_rdonly(sb)) {
-+		sb->s_flags |= SB_RDONLY;
-+		pr_err("[EXFAT] Filesystem has been set read-only\n");
-+	}
-+}
-+
-+/*
-+ *  Cluster Management Functions
-+ */
-+
-+s32 clear_cluster(struct super_block *sb, u32 clu)
-+{
-+	sector_t s, n;
-+	s32 ret = FFS_SUCCESS;
-+	struct buffer_head *tmp_bh = NULL;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	if (clu == CLUSTER_32(0)) { /* FAT16 root_dir */
-+		s = p_fs->root_start_sector;
-+		n = p_fs->data_start_sector;
-+	} else {
-+		s = START_SECTOR(clu);
-+		n = s + p_fs->sectors_per_clu;
-+	}
-+
-+	for (; s < n; s++) {
-+		ret = sector_read(sb, s, &tmp_bh, 0);
-+		if (ret != FFS_SUCCESS)
-+			return ret;
-+
-+		memset((char *)tmp_bh->b_data, 0x0, p_bd->sector_size);
-+		ret = sector_write(sb, s, tmp_bh, 0);
-+		if (ret != FFS_SUCCESS)
-+			break;
-+	}
-+
-+	brelse(tmp_bh);
-+	return ret;
-+}
-+
-+s32 fat_alloc_cluster(struct super_block *sb, s32 num_alloc,
-+		      struct chain_t *p_chain)
-+{
-+	int i, num_clusters = 0;
-+	u32 new_clu, last_clu = CLUSTER_32(~0), read_clu;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	new_clu = p_chain->dir;
-+	if (new_clu == CLUSTER_32(~0))
-+		new_clu = p_fs->clu_srch_ptr;
-+	else if (new_clu >= p_fs->num_clusters)
-+		new_clu = 2;
-+
-+	__set_sb_dirty(sb);
-+
-+	p_chain->dir = CLUSTER_32(~0);
-+
-+	for (i = 2; i < p_fs->num_clusters; i++) {
-+		if (FAT_read(sb, new_clu, &read_clu) != 0)
-+			return -1;
-+
-+		if (read_clu == CLUSTER_32(0)) {
-+			if (FAT_write(sb, new_clu, CLUSTER_32(~0)) < 0)
-+				return -1;
-+			num_clusters++;
-+
-+			if (p_chain->dir == CLUSTER_32(~0)) {
-+				p_chain->dir = new_clu;
-+			} else {
-+				if (FAT_write(sb, last_clu, new_clu) < 0)
-+					return -1;
-+			}
-+
-+			last_clu = new_clu;
-+
-+			if ((--num_alloc) == 0) {
-+				p_fs->clu_srch_ptr = new_clu;
-+				if (p_fs->used_clusters != (u32) ~0)
-+					p_fs->used_clusters += num_clusters;
-+
-+				return num_clusters;
-+			}
-+		}
-+		if ((++new_clu) >= p_fs->num_clusters)
-+			new_clu = 2;
-+	}
-+
-+	p_fs->clu_srch_ptr = new_clu;
-+	if (p_fs->used_clusters != (u32) ~0)
-+		p_fs->used_clusters += num_clusters;
-+
-+	return num_clusters;
-+}
-+
-+s32 exfat_alloc_cluster(struct super_block *sb, s32 num_alloc,
-+			struct chain_t *p_chain)
-+{
-+	s32 num_clusters = 0;
-+	u32 hint_clu, new_clu, last_clu = CLUSTER_32(~0);
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	hint_clu = p_chain->dir;
-+	if (hint_clu == CLUSTER_32(~0)) {
-+		hint_clu = test_alloc_bitmap(sb, p_fs->clu_srch_ptr-2);
-+		if (hint_clu == CLUSTER_32(~0))
-+			return 0;
-+	} else if (hint_clu >= p_fs->num_clusters) {
-+		hint_clu = 2;
-+		p_chain->flags = 0x01;
-+	}
-+
-+	__set_sb_dirty(sb);
-+
-+	p_chain->dir = CLUSTER_32(~0);
-+
-+	while ((new_clu = test_alloc_bitmap(sb, hint_clu-2)) != CLUSTER_32(~0)) {
-+		if (new_clu != hint_clu) {
-+			if (p_chain->flags == 0x03) {
-+				exfat_chain_cont_cluster(sb, p_chain->dir,
-+							 num_clusters);
-+				p_chain->flags = 0x01;
-+			}
-+		}
-+
-+		if (set_alloc_bitmap(sb, new_clu-2) != FFS_SUCCESS)
-+			return -1;
-+
-+		num_clusters++;
-+
-+		if (p_chain->flags == 0x01) {
-+			if (FAT_write(sb, new_clu, CLUSTER_32(~0)) < 0)
-+				return -1;
-+		}
-+
-+		if (p_chain->dir == CLUSTER_32(~0)) {
-+			p_chain->dir = new_clu;
-+		} else {
-+			if (p_chain->flags == 0x01) {
-+				if (FAT_write(sb, last_clu, new_clu) < 0)
-+					return -1;
-+			}
-+		}
-+		last_clu = new_clu;
-+
-+		if ((--num_alloc) == 0) {
-+			p_fs->clu_srch_ptr = hint_clu;
-+			if (p_fs->used_clusters != (u32) ~0)
-+				p_fs->used_clusters += num_clusters;
-+
-+			p_chain->size += num_clusters;
-+			return num_clusters;
-+		}
-+
-+		hint_clu = new_clu + 1;
-+		if (hint_clu >= p_fs->num_clusters) {
-+			hint_clu = 2;
-+
-+			if (p_chain->flags == 0x03) {
-+				exfat_chain_cont_cluster(sb, p_chain->dir,
-+							 num_clusters);
-+				p_chain->flags = 0x01;
-+			}
-+		}
-+	}
-+
-+	p_fs->clu_srch_ptr = hint_clu;
-+	if (p_fs->used_clusters != (u32) ~0)
-+		p_fs->used_clusters += num_clusters;
-+
-+	p_chain->size += num_clusters;
-+	return num_clusters;
-+}
-+
-+void fat_free_cluster(struct super_block *sb, struct chain_t *p_chain,
-+		      s32 do_relse)
-+{
-+	s32 num_clusters = 0;
-+	u32 clu, prev;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	int i;
-+	sector_t sector;
-+
-+	if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0)))
-+		return;
-+	__set_sb_dirty(sb);
-+	clu = p_chain->dir;
-+
-+	if (p_chain->size <= 0)
-+		return;
-+
-+	do {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		if (do_relse) {
-+			sector = START_SECTOR(clu);
-+			for (i = 0; i < p_fs->sectors_per_clu; i++)
-+				buf_release(sb, sector+i);
-+		}
-+
-+		prev = clu;
-+		if (FAT_read(sb, clu, &clu) == -1)
-+			break;
-+
-+		if (FAT_write(sb, prev, CLUSTER_32(0)) < 0)
-+			break;
-+		num_clusters++;
-+
-+	} while (clu != CLUSTER_32(~0));
-+
-+	if (p_fs->used_clusters != (u32) ~0)
-+		p_fs->used_clusters -= num_clusters;
-+}
-+
-+void exfat_free_cluster(struct super_block *sb, struct chain_t *p_chain,
-+			s32 do_relse)
-+{
-+	s32 num_clusters = 0;
-+	u32 clu;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	int i;
-+	sector_t sector;
-+
-+	if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0)))
-+		return;
-+
-+	if (p_chain->size <= 0) {
-+		pr_err("[EXFAT] free_cluster : skip free-req clu:%u, because of zero-size truncation\n",
-+		       p_chain->dir);
-+		return;
-+	}
-+
-+	__set_sb_dirty(sb);
-+	clu = p_chain->dir;
-+
-+	if (p_chain->flags == 0x03) {
-+		do {
-+			if (do_relse) {
-+				sector = START_SECTOR(clu);
-+				for (i = 0; i < p_fs->sectors_per_clu; i++)
-+					buf_release(sb, sector+i);
-+			}
-+
-+			if (clr_alloc_bitmap(sb, clu-2) != FFS_SUCCESS)
-+				break;
-+			clu++;
-+
-+			num_clusters++;
-+		} while (num_clusters < p_chain->size);
-+	} else {
-+		do {
-+			if (p_fs->dev_ejected)
-+				break;
-+
-+			if (do_relse) {
-+				sector = START_SECTOR(clu);
-+				for (i = 0; i < p_fs->sectors_per_clu; i++)
-+					buf_release(sb, sector+i);
-+			}
-+
-+			if (clr_alloc_bitmap(sb, clu-2) != FFS_SUCCESS)
-+				break;
-+
-+			if (FAT_read(sb, clu, &clu) == -1)
-+				break;
-+			num_clusters++;
-+		} while ((clu != CLUSTER_32(0)) && (clu != CLUSTER_32(~0)));
-+	}
-+
-+	if (p_fs->used_clusters != (u32) ~0)
-+		p_fs->used_clusters -= num_clusters;
-+}
-+
-+u32 find_last_cluster(struct super_block *sb, struct chain_t *p_chain)
-+{
-+	u32 clu, next;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	clu = p_chain->dir;
-+
-+	if (p_chain->flags == 0x03) {
-+		clu += p_chain->size - 1;
-+	} else {
-+		while ((FAT_read(sb, clu, &next) == 0) &&
-+		       (next != CLUSTER_32(~0))) {
-+			if (p_fs->dev_ejected)
-+				break;
-+			clu = next;
-+		}
-+	}
-+
-+	return clu;
-+}
-+
-+s32 count_num_clusters(struct super_block *sb, struct chain_t *p_chain)
-+{
-+	int i, count = 0;
-+	u32 clu;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if ((p_chain->dir == CLUSTER_32(0)) || (p_chain->dir == CLUSTER_32(~0)))
-+		return 0;
-+
-+	clu = p_chain->dir;
-+
-+	if (p_chain->flags == 0x03) {
-+		count = p_chain->size;
-+	} else {
-+		for (i = 2; i < p_fs->num_clusters; i++) {
-+			count++;
-+			if (FAT_read(sb, clu, &clu) != 0)
-+				return 0;
-+			if (clu == CLUSTER_32(~0))
-+				break;
-+		}
-+	}
-+
-+	return count;
-+}
-+
-+s32 fat_count_used_clusters(struct super_block *sb)
-+{
-+	int i, count = 0;
-+	u32 clu;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	for (i = 2; i < p_fs->num_clusters; i++) {
-+		if (FAT_read(sb, i, &clu) != 0)
-+			break;
-+		if (clu != CLUSTER_32(0))
-+			count++;
-+	}
-+
-+	return count;
-+}
-+
-+s32 exfat_count_used_clusters(struct super_block *sb)
-+{
-+	int i, map_i, map_b, count = 0;
-+	u8 k;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	map_i = map_b = 0;
-+
-+	for (i = 2; i < p_fs->num_clusters; i += 8) {
-+		k = *(((u8 *) p_fs->vol_amap[map_i]->b_data) + map_b);
-+		count += used_bit[k];
-+
-+		if ((++map_b) >= p_bd->sector_size) {
-+			map_i++;
-+			map_b = 0;
-+		}
-+	}
-+
-+	return count;
-+}
-+
-+void exfat_chain_cont_cluster(struct super_block *sb, u32 chain, s32 len)
-+{
-+	if (len == 0)
-+		return;
-+
-+	while (len > 1) {
-+		if (FAT_write(sb, chain, chain+1) < 0)
-+			break;
-+		chain++;
-+		len--;
-+	}
-+	FAT_write(sb, chain, CLUSTER_32(~0));
-+}
-+
-+/*
-+ *  Allocation Bitmap Management Functions
-+ */
-+
-+s32 load_alloc_bitmap(struct super_block *sb)
-+{
-+	int i, j, ret;
-+	u32 map_size;
-+	u32 type;
-+	sector_t sector;
-+	struct chain_t clu;
-+	struct bmap_dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	clu.dir = p_fs->root_dir;
-+	clu.flags = 0x01;
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		for (i = 0; i < p_fs->dentries_per_clu; i++) {
-+			ep = (struct bmap_dentry_t *)get_entry_in_dir(sb, &clu,
-+								      i, NULL);
-+			if (!ep)
-+				return FFS_MEDIAERR;
-+
-+			type = p_fs->fs_func->get_entry_type((struct dentry_t *)ep);
-+
-+			if (type == TYPE_UNUSED)
-+				break;
-+			if (type != TYPE_BITMAP)
-+				continue;
-+
-+			if (ep->flags == 0x0) {
-+				p_fs->map_clu  = GET32_A(ep->start_clu);
-+				map_size = (u32) GET64_A(ep->size);
-+
-+				p_fs->map_sectors = ((map_size-1) >> p_bd->sector_size_bits) + 1;
-+
-+				p_fs->vol_amap = kmalloc_array(p_fs->map_sectors,
-+							       sizeof(struct buffer_head *),
-+							       GFP_KERNEL);
-+				if (p_fs->vol_amap == NULL)
-+					return FFS_MEMORYERR;
-+
-+				sector = START_SECTOR(p_fs->map_clu);
-+
-+				for (j = 0; j < p_fs->map_sectors; j++) {
-+					p_fs->vol_amap[j] = NULL;
-+					ret = sector_read(sb, sector+j, &(p_fs->vol_amap[j]), 1);
-+					if (ret != FFS_SUCCESS) {
-+						/*  release all buffers and free vol_amap */
-+						i = 0;
-+						while (i < j)
-+							brelse(p_fs->vol_amap[i++]);
-+
-+						kfree(p_fs->vol_amap);
-+						p_fs->vol_amap = NULL;
-+						return ret;
-+					}
-+				}
-+
-+				p_fs->pbr_bh = NULL;
-+				return FFS_SUCCESS;
-+			}
-+		}
-+
-+		if (FAT_read(sb, clu.dir, &clu.dir) != 0)
-+			return FFS_MEDIAERR;
-+	}
-+
-+	return FFS_FORMATERR;
-+}
-+
-+void free_alloc_bitmap(struct super_block *sb)
-+{
-+	int i;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	brelse(p_fs->pbr_bh);
-+
-+	for (i = 0; i < p_fs->map_sectors; i++)
-+		__brelse(p_fs->vol_amap[i]);
-+
-+	kfree(p_fs->vol_amap);
-+	p_fs->vol_amap = NULL;
-+}
-+
-+s32 set_alloc_bitmap(struct super_block *sb, u32 clu)
-+{
-+	int i, b;
-+	sector_t sector;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	i = clu >> (p_bd->sector_size_bits + 3);
-+	b = clu & ((p_bd->sector_size << 3) - 1);
-+
-+	sector = START_SECTOR(p_fs->map_clu) + i;
-+
-+	exfat_bitmap_set((u8 *) p_fs->vol_amap[i]->b_data, b);
-+
-+	return sector_write(sb, sector, p_fs->vol_amap[i], 0);
-+}
-+
-+s32 clr_alloc_bitmap(struct super_block *sb, u32 clu)
-+{
-+	int i, b;
-+	sector_t sector;
-+#ifdef CONFIG_EXFAT_DISCARD
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct exfat_mount_options *opts = &sbi->options;
-+	int ret;
-+#endif /* CONFIG_EXFAT_DISCARD */
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	i = clu >> (p_bd->sector_size_bits + 3);
-+	b = clu & ((p_bd->sector_size << 3) - 1);
-+
-+	sector = START_SECTOR(p_fs->map_clu) + i;
-+
-+	exfat_bitmap_clear((u8 *) p_fs->vol_amap[i]->b_data, b);
-+
-+	return sector_write(sb, sector, p_fs->vol_amap[i], 0);
-+
-+#ifdef CONFIG_EXFAT_DISCARD
-+	if (opts->discard) {
-+		ret = sb_issue_discard(sb, START_SECTOR(clu),
-+				       (1 << p_fs->sectors_per_clu_bits),
-+				       GFP_NOFS, 0);
-+		if (ret == -EOPNOTSUPP) {
-+			pr_warn("discard not supported by device, disabling");
-+			opts->discard = 0;
-+		}
-+	}
-+#endif /* CONFIG_EXFAT_DISCARD */
-+}
-+
-+u32 test_alloc_bitmap(struct super_block *sb, u32 clu)
-+{
-+	int i, map_i, map_b;
-+	u32 clu_base, clu_free;
-+	u8 k, clu_mask;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	clu_base = (clu & ~(0x7)) + 2;
-+	clu_mask = (1 << (clu - clu_base + 2)) - 1;
-+
-+	map_i = clu >> (p_bd->sector_size_bits + 3);
-+	map_b = (clu >> 3) & p_bd->sector_size_mask;
-+
-+	for (i = 2; i < p_fs->num_clusters; i += 8) {
-+		k = *(((u8 *) p_fs->vol_amap[map_i]->b_data) + map_b);
-+		if (clu_mask > 0) {
-+			k |= clu_mask;
-+			clu_mask = 0;
-+		}
-+		if (k < 0xFF) {
-+			clu_free = clu_base + free_bit[k];
-+			if (clu_free < p_fs->num_clusters)
-+				return clu_free;
-+		}
-+		clu_base += 8;
-+
-+		if (((++map_b) >= p_bd->sector_size) ||
-+		    (clu_base >= p_fs->num_clusters)) {
-+			if ((++map_i) >= p_fs->map_sectors) {
-+				clu_base = 2;
-+				map_i = 0;
-+			}
-+			map_b = 0;
-+		}
-+	}
-+
-+	return CLUSTER_32(~0);
-+}
-+
-+void sync_alloc_bitmap(struct super_block *sb)
-+{
-+	int i;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (p_fs->vol_amap == NULL)
-+		return;
-+
-+	for (i = 0; i < p_fs->map_sectors; i++)
-+		sync_dirty_buffer(p_fs->vol_amap[i]);
-+}
-+
-+/*
-+ *  Upcase table Management Functions
-+ */
-+static s32 __load_upcase_table(struct super_block *sb, sector_t sector,
-+			       u32 num_sectors, u32 utbl_checksum)
-+{
-+	int i, ret = FFS_ERROR;
-+	u32 j;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+	struct buffer_head *tmp_bh = NULL;
-+	sector_t end_sector = num_sectors + sector;
-+
-+	u8	skip = FALSE;
-+	u32	index = 0;
-+	u16	uni = 0;
-+	u16 **upcase_table;
-+
-+	u32 checksum = 0;
-+
-+	upcase_table = p_fs->vol_utbl = kmalloc(UTBL_COL_COUNT * sizeof(u16 *),
-+						GFP_KERNEL);
-+	if (upcase_table == NULL)
-+		return FFS_MEMORYERR;
-+	memset(upcase_table, 0, UTBL_COL_COUNT * sizeof(u16 *));
-+
-+	while (sector < end_sector) {
-+		ret = sector_read(sb, sector, &tmp_bh, 1);
-+		if (ret != FFS_SUCCESS) {
-+			pr_debug("sector read (0x%llX)fail\n",
-+				 (unsigned long long)sector);
-+			goto error;
-+		}
-+		sector++;
-+
-+		for (i = 0; i < p_bd->sector_size && index <= 0xFFFF; i += 2) {
-+			uni = GET16(((u8 *) tmp_bh->b_data)+i);
-+
-+			checksum = ((checksum & 1) ? 0x80000000 : 0) +
-+				   (checksum >> 1) + *(((u8 *)tmp_bh->b_data) +
-+						       i);
-+			checksum = ((checksum & 1) ? 0x80000000 : 0) +
-+				   (checksum >> 1) + *(((u8 *)tmp_bh->b_data) +
-+						       (i + 1));
-+
-+			if (skip) {
-+				pr_debug("skip from 0x%X ", index);
-+				index += uni;
-+				pr_debug("to 0x%X (amount of 0x%X)\n",
-+					 index, uni);
-+				skip = FALSE;
-+			} else if (uni == index)
-+				index++;
-+			else if (uni == 0xFFFF)
-+				skip = TRUE;
-+			else { /* uni != index , uni != 0xFFFF */
-+				u16 col_index = get_col_index(index);
-+
-+				if (upcase_table[col_index] == NULL) {
-+					pr_debug("alloc = 0x%X\n", col_index);
-+					upcase_table[col_index] = kmalloc_array(UTBL_ROW_COUNT,
-+						sizeof(u16), GFP_KERNEL);
-+					if (upcase_table[col_index] == NULL) {
-+						ret = FFS_MEMORYERR;
-+						goto error;
-+					}
-+
-+					for (j = 0; j < UTBL_ROW_COUNT; j++)
-+						upcase_table[col_index][j] = (col_index << LOW_INDEX_BIT) | j;
-+				}
-+
-+				upcase_table[col_index][get_row_index(index)] = uni;
-+				index++;
-+			}
-+		}
-+	}
-+	if (index >= 0xFFFF && utbl_checksum == checksum) {
-+		if (tmp_bh)
-+			brelse(tmp_bh);
-+		return FFS_SUCCESS;
-+	}
-+	ret = FFS_ERROR;
-+error:
-+	if (tmp_bh)
-+		brelse(tmp_bh);
-+	free_upcase_table(sb);
-+	return ret;
-+}
-+
-+static s32 __load_default_upcase_table(struct super_block *sb)
-+{
-+	int i, ret = FFS_ERROR;
-+	u32 j;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	u8	skip = FALSE;
-+	u32	index = 0;
-+	u16	uni = 0;
-+	u16 **upcase_table;
-+
-+	upcase_table = p_fs->vol_utbl = kmalloc(UTBL_COL_COUNT * sizeof(u16 *),
-+						GFP_KERNEL);
-+	if (upcase_table == NULL)
-+		return FFS_MEMORYERR;
-+	memset(upcase_table, 0, UTBL_COL_COUNT * sizeof(u16 *));
-+
-+	for (i = 0; index <= 0xFFFF && i < NUM_UPCASE*2; i += 2) {
-+		uni = GET16(uni_upcase + i);
-+		if (skip) {
-+			pr_debug("skip from 0x%X ", index);
-+			index += uni;
-+			pr_debug("to 0x%X (amount of 0x%X)\n", index, uni);
-+			skip = FALSE;
-+		} else if (uni == index)
-+			index++;
-+		else if (uni == 0xFFFF)
-+			skip = TRUE;
-+		else { /* uni != index , uni != 0xFFFF */
-+			u16 col_index = get_col_index(index);
-+
-+			if (upcase_table[col_index] == NULL) {
-+				pr_debug("alloc = 0x%X\n", col_index);
-+				upcase_table[col_index] = kmalloc_array(UTBL_ROW_COUNT,
-+									sizeof(u16),
-+									GFP_KERNEL);
-+				if (upcase_table[col_index] == NULL) {
-+					ret = FFS_MEMORYERR;
-+					goto error;
-+				}
-+
-+				for (j = 0; j < UTBL_ROW_COUNT; j++)
-+					upcase_table[col_index][j] = (col_index << LOW_INDEX_BIT) | j;
-+			}
-+
-+			upcase_table[col_index][get_row_index(index)] = uni;
-+			index++;
-+		}
-+	}
-+
-+	if (index >= 0xFFFF)
-+		return FFS_SUCCESS;
-+
-+error:
-+	/* FATAL error: default upcase table has error */
-+	free_upcase_table(sb);
-+	return ret;
-+}
-+
-+s32 load_upcase_table(struct super_block *sb)
-+{
-+	int i;
-+	u32 tbl_clu, tbl_size;
-+	sector_t sector;
-+	u32 type, num_sectors;
-+	struct chain_t clu;
-+	struct case_dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	clu.dir = p_fs->root_dir;
-+	clu.flags = 0x01;
-+
-+	if (p_fs->dev_ejected)
-+		return FFS_MEDIAERR;
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		for (i = 0; i < p_fs->dentries_per_clu; i++) {
-+			ep = (struct case_dentry_t *)get_entry_in_dir(sb, &clu,
-+								      i, NULL);
-+			if (!ep)
-+				return FFS_MEDIAERR;
-+
-+			type = p_fs->fs_func->get_entry_type((struct dentry_t *)ep);
-+
-+			if (type == TYPE_UNUSED)
-+				break;
-+			if (type != TYPE_UPCASE)
-+				continue;
-+
-+			tbl_clu  = GET32_A(ep->start_clu);
-+			tbl_size = (u32) GET64_A(ep->size);
-+
-+			sector = START_SECTOR(tbl_clu);
-+			num_sectors = ((tbl_size-1) >> p_bd->sector_size_bits) + 1;
-+			if (__load_upcase_table(sb, sector, num_sectors,
-+						GET32_A(ep->checksum)) != FFS_SUCCESS)
-+				break;
-+			return FFS_SUCCESS;
-+		}
-+		if (FAT_read(sb, clu.dir, &clu.dir) != 0)
-+			return FFS_MEDIAERR;
-+	}
-+	/* load default upcase table */
-+	return __load_default_upcase_table(sb);
-+}
-+
-+void free_upcase_table(struct super_block *sb)
-+{
-+	u32 i;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	u16 **upcase_table;
-+
-+	upcase_table = p_fs->vol_utbl;
-+	for (i = 0; i < UTBL_COL_COUNT; i++)
-+		kfree(upcase_table[i]);
-+
-+	kfree(p_fs->vol_utbl);
-+	p_fs->vol_utbl = NULL;
-+}
-+
-+/*
-+ *  Directory Entry Management Functions
-+ */
-+
-+u32 fat_get_entry_type(struct dentry_t *p_entry)
-+{
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *) p_entry;
-+
-+	if (*(ep->name) == 0x0)
-+		return TYPE_UNUSED;
-+
-+	else if (*(ep->name) == 0xE5)
-+		return TYPE_DELETED;
-+
-+	else if (ep->attr == ATTR_EXTEND)
-+		return TYPE_EXTEND;
-+
-+	else if ((ep->attr & (ATTR_SUBDIR|ATTR_VOLUME)) == ATTR_VOLUME)
-+		return TYPE_VOLUME;
-+
-+	else if ((ep->attr & (ATTR_SUBDIR|ATTR_VOLUME)) == ATTR_SUBDIR)
-+		return TYPE_DIR;
-+
-+	return TYPE_FILE;
-+}
-+
-+u32 exfat_get_entry_type(struct dentry_t *p_entry)
-+{
-+	struct file_dentry_t *ep = (struct file_dentry_t *) p_entry;
-+
-+	if (ep->type == 0x0) {
-+		return TYPE_UNUSED;
-+	} else if (ep->type < 0x80) {
-+		return TYPE_DELETED;
-+	} else if (ep->type == 0x80) {
-+		return TYPE_INVALID;
-+	} else if (ep->type < 0xA0) {
-+		if (ep->type == 0x81) {
-+			return TYPE_BITMAP;
-+		} else if (ep->type == 0x82) {
-+			return TYPE_UPCASE;
-+		} else if (ep->type == 0x83) {
-+			return TYPE_VOLUME;
-+		} else if (ep->type == 0x85) {
-+			if (GET16_A(ep->attr) & ATTR_SUBDIR)
-+				return TYPE_DIR;
-+			else
-+				return TYPE_FILE;
-+		}
-+		return TYPE_CRITICAL_PRI;
-+	} else if (ep->type < 0xC0) {
-+		if (ep->type == 0xA0)
-+			return TYPE_GUID;
-+		else if (ep->type == 0xA1)
-+			return TYPE_PADDING;
-+		else if (ep->type == 0xA2)
-+			return TYPE_ACLTAB;
-+		return TYPE_BENIGN_PRI;
-+	} else if (ep->type < 0xE0) {
-+		if (ep->type == 0xC0)
-+			return TYPE_STREAM;
-+		else if (ep->type == 0xC1)
-+			return TYPE_EXTEND;
-+		else if (ep->type == 0xC2)
-+			return TYPE_ACL;
-+		return TYPE_CRITICAL_SEC;
-+	}
-+
-+	return TYPE_BENIGN_SEC;
-+}
-+
-+void fat_set_entry_type(struct dentry_t *p_entry, u32 type)
-+{
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *) p_entry;
-+
-+	if (type == TYPE_UNUSED)
-+		*(ep->name) = 0x0;
-+
-+	else if (type == TYPE_DELETED)
-+		*(ep->name) = 0xE5;
-+
-+	else if (type == TYPE_EXTEND)
-+		ep->attr = ATTR_EXTEND;
-+
-+	else if (type == TYPE_DIR)
-+		ep->attr = ATTR_SUBDIR;
-+
-+	else if (type == TYPE_FILE)
-+		ep->attr = ATTR_ARCHIVE;
-+
-+	else if (type == TYPE_SYMLINK)
-+		ep->attr = ATTR_ARCHIVE | ATTR_SYMLINK;
-+}
-+
-+void exfat_set_entry_type(struct dentry_t *p_entry, u32 type)
-+{
-+	struct file_dentry_t *ep = (struct file_dentry_t *) p_entry;
-+
-+	if (type == TYPE_UNUSED) {
-+		ep->type = 0x0;
-+	} else if (type == TYPE_DELETED) {
-+		ep->type &= ~0x80;
-+	} else if (type == TYPE_STREAM) {
-+		ep->type = 0xC0;
-+	} else if (type == TYPE_EXTEND) {
-+		ep->type = 0xC1;
-+	} else if (type == TYPE_BITMAP) {
-+		ep->type = 0x81;
-+	} else if (type == TYPE_UPCASE) {
-+		ep->type = 0x82;
-+	} else if (type == TYPE_VOLUME) {
-+		ep->type = 0x83;
-+	} else if (type == TYPE_DIR) {
-+		ep->type = 0x85;
-+		SET16_A(ep->attr, ATTR_SUBDIR);
-+	} else if (type == TYPE_FILE) {
-+		ep->type = 0x85;
-+		SET16_A(ep->attr, ATTR_ARCHIVE);
-+	} else if (type == TYPE_SYMLINK) {
-+		ep->type = 0x85;
-+		SET16_A(ep->attr, ATTR_ARCHIVE | ATTR_SYMLINK);
-+	}
-+}
-+
-+u32 fat_get_entry_attr(struct dentry_t *p_entry)
-+{
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *) p_entry;
-+
-+	return (u32) ep->attr;
-+}
-+
-+u32 exfat_get_entry_attr(struct dentry_t *p_entry)
-+{
-+	struct file_dentry_t *ep = (struct file_dentry_t *) p_entry;
-+
-+	return (u32) GET16_A(ep->attr);
-+}
-+
-+void fat_set_entry_attr(struct dentry_t *p_entry, u32 attr)
-+{
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *) p_entry;
-+
-+	ep->attr = (u8) attr;
-+}
-+
-+void exfat_set_entry_attr(struct dentry_t *p_entry, u32 attr)
-+{
-+	struct file_dentry_t *ep = (struct file_dentry_t *) p_entry;
-+
-+	SET16_A(ep->attr, (u16) attr);
-+}
-+
-+u8 fat_get_entry_flag(struct dentry_t *p_entry)
-+{
-+	return 0x01;
-+}
-+
-+u8 exfat_get_entry_flag(struct dentry_t *p_entry)
-+{
-+	struct strm_dentry_t *ep = (struct strm_dentry_t *) p_entry;
-+
-+	return ep->flags;
-+}
-+
-+void fat_set_entry_flag(struct dentry_t *p_entry, u8 flags)
-+{
-+}
-+
-+void exfat_set_entry_flag(struct dentry_t *p_entry, u8 flags)
-+{
-+	struct strm_dentry_t *ep = (struct strm_dentry_t *) p_entry;
-+
-+	ep->flags = flags;
-+}
-+
-+u32 fat_get_entry_clu0(struct dentry_t *p_entry)
-+{
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *) p_entry;
-+
-+	return ((u32)GET16_A(ep->start_clu_hi) << 16) |
-+		GET16_A(ep->start_clu_lo);
-+}
-+
-+u32 exfat_get_entry_clu0(struct dentry_t *p_entry)
-+{
-+	struct strm_dentry_t *ep = (struct strm_dentry_t *) p_entry;
-+
-+	return GET32_A(ep->start_clu);
-+}
-+
-+void fat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu)
-+{
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry;
-+
-+	SET16_A(ep->start_clu_lo, CLUSTER_16(start_clu));
-+	SET16_A(ep->start_clu_hi, CLUSTER_16(start_clu >> 16));
-+}
-+
-+void exfat_set_entry_clu0(struct dentry_t *p_entry, u32 start_clu)
-+{
-+	struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
-+
-+	SET32_A(ep->start_clu, start_clu);
-+}
-+
-+u64 fat_get_entry_size(struct dentry_t *p_entry)
-+{
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry;
-+
-+	return (u64) GET32_A(ep->size);
-+}
-+
-+u64 exfat_get_entry_size(struct dentry_t *p_entry)
-+{
-+	struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
-+
-+	return GET64_A(ep->valid_size);
-+}
-+
-+void fat_set_entry_size(struct dentry_t *p_entry, u64 size)
-+{
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry;
-+
-+	SET32_A(ep->size, (u32) size);
-+}
-+
-+void exfat_set_entry_size(struct dentry_t *p_entry, u64 size)
-+{
-+	struct strm_dentry_t *ep = (struct strm_dentry_t *)p_entry;
-+
-+	SET64_A(ep->valid_size, size);
-+	SET64_A(ep->size, size);
-+}
-+
-+void fat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
-+			u8 mode)
-+{
-+	u16 t = 0x00, d = 0x21;
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry;
-+
-+	switch (mode) {
-+	case TM_CREATE:
-+		t = GET16_A(ep->create_time);
-+		d = GET16_A(ep->create_date);
-+		break;
-+	case TM_MODIFY:
-+		t = GET16_A(ep->modify_time);
-+		d = GET16_A(ep->modify_date);
-+		break;
-+	}
-+
-+	tp->sec  = (t & 0x001F) << 1;
-+	tp->min  = (t >> 5) & 0x003F;
-+	tp->hour = (t >> 11);
-+	tp->day  = (d & 0x001F);
-+	tp->mon  = (d >> 5) & 0x000F;
-+	tp->year = (d >> 9);
-+}
-+
-+void exfat_get_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
-+			  u8 mode)
-+{
-+	u16 t = 0x00, d = 0x21;
-+	struct file_dentry_t *ep = (struct file_dentry_t *)p_entry;
-+
-+	switch (mode) {
-+	case TM_CREATE:
-+		t = GET16_A(ep->create_time);
-+		d = GET16_A(ep->create_date);
-+		break;
-+	case TM_MODIFY:
-+		t = GET16_A(ep->modify_time);
-+		d = GET16_A(ep->modify_date);
-+		break;
-+	case TM_ACCESS:
-+		t = GET16_A(ep->access_time);
-+		d = GET16_A(ep->access_date);
-+		break;
-+	}
-+
-+	tp->sec  = (t & 0x001F) << 1;
-+	tp->min  = (t >> 5) & 0x003F;
-+	tp->hour = (t >> 11);
-+	tp->day  = (d & 0x001F);
-+	tp->mon  = (d >> 5) & 0x000F;
-+	tp->year = (d >> 9);
-+}
-+
-+void fat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
-+			u8 mode)
-+{
-+	u16 t, d;
-+	struct dos_dentry_t *ep = (struct dos_dentry_t *)p_entry;
-+
-+	t = (tp->hour << 11) | (tp->min << 5) | (tp->sec >> 1);
-+	d = (tp->year <<  9) | (tp->mon << 5) |  tp->day;
-+
-+	switch (mode) {
-+	case TM_CREATE:
-+		SET16_A(ep->create_time, t);
-+		SET16_A(ep->create_date, d);
-+		break;
-+	case TM_MODIFY:
-+		SET16_A(ep->modify_time, t);
-+		SET16_A(ep->modify_date, d);
-+		break;
-+	}
-+}
-+
-+void exfat_set_entry_time(struct dentry_t *p_entry, struct timestamp_t *tp,
-+			  u8 mode)
-+{
-+	u16 t, d;
-+	struct file_dentry_t *ep = (struct file_dentry_t *)p_entry;
-+
-+	t = (tp->hour << 11) | (tp->min << 5) | (tp->sec >> 1);
-+	d = (tp->year <<  9) | (tp->mon << 5) |  tp->day;
-+
-+	switch (mode) {
-+	case TM_CREATE:
-+		SET16_A(ep->create_time, t);
-+		SET16_A(ep->create_date, d);
-+		break;
-+	case TM_MODIFY:
-+		SET16_A(ep->modify_time, t);
-+		SET16_A(ep->modify_date, d);
-+		break;
-+	case TM_ACCESS:
-+		SET16_A(ep->access_time, t);
-+		SET16_A(ep->access_date, d);
-+		break;
-+	}
-+}
-+
-+s32 fat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir, s32 entry,
-+		       u32 type, u32 start_clu, u64 size)
-+{
-+	sector_t sector;
-+	struct dos_dentry_t *dos_ep;
-+
-+	dos_ep = (struct dos_dentry_t *)get_entry_in_dir(sb, p_dir, entry,
-+							 &sector);
-+	if (!dos_ep)
-+		return FFS_MEDIAERR;
-+
-+	init_dos_entry(dos_ep, type, start_clu);
-+	buf_modify(sb, sector);
-+
-+	return FFS_SUCCESS;
-+}
-+
-+s32 exfat_init_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+			 s32 entry, u32 type, u32 start_clu, u64 size)
-+{
-+	sector_t sector;
-+	u8 flags;
-+	struct file_dentry_t *file_ep;
-+	struct strm_dentry_t *strm_ep;
-+
-+	flags = (type == TYPE_FILE) ? 0x01 : 0x03;
-+
-+	/* we cannot use get_entry_set_in_dir here because file ep is not initialized yet */
-+	file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry,
-+							   &sector);
-+	if (!file_ep)
-+		return FFS_MEDIAERR;
-+
-+	strm_ep = (struct strm_dentry_t *)get_entry_in_dir(sb, p_dir, entry+1,
-+							   &sector);
-+	if (!strm_ep)
-+		return FFS_MEDIAERR;
-+
-+	init_file_entry(file_ep, type);
-+	buf_modify(sb, sector);
-+
-+	init_strm_entry(strm_ep, flags, start_clu, size);
-+	buf_modify(sb, sector);
-+
-+	return FFS_SUCCESS;
-+}
-+
-+static s32 fat_init_ext_entry(struct super_block *sb, struct chain_t *p_dir,
-+			      s32 entry, s32 num_entries,
-+			      struct uni_name_t *p_uniname,
-+			      struct dos_name_t *p_dosname)
-+{
-+	int i;
-+	sector_t sector;
-+	u8 chksum;
-+	u16 *uniname = p_uniname->name;
-+	struct dos_dentry_t *dos_ep;
-+	struct ext_dentry_t *ext_ep;
-+
-+	dos_ep = (struct dos_dentry_t *)get_entry_in_dir(sb, p_dir, entry,
-+							 &sector);
-+	if (!dos_ep)
-+		return FFS_MEDIAERR;
-+
-+	dos_ep->lcase = p_dosname->name_case;
-+	memcpy(dos_ep->name, p_dosname->name, DOS_NAME_LENGTH);
-+	buf_modify(sb, sector);
-+
-+	if ((--num_entries) > 0) {
-+		chksum = calc_checksum_1byte((void *)dos_ep->name,
-+					     DOS_NAME_LENGTH, 0);
-+
-+		for (i = 1; i < num_entries; i++) {
-+			ext_ep = (struct ext_dentry_t *)get_entry_in_dir(sb,
-+									 p_dir,
-+									 entry - i,
-+									 &sector);
-+			if (!ext_ep)
-+				return FFS_MEDIAERR;
-+
-+			init_ext_entry(ext_ep, i, chksum, uniname);
-+			buf_modify(sb, sector);
-+			uniname += 13;
-+		}
-+
-+		ext_ep = (struct ext_dentry_t *)get_entry_in_dir(sb, p_dir,
-+								 entry - i,
-+								 &sector);
-+		if (!ext_ep)
-+			return FFS_MEDIAERR;
-+
-+		init_ext_entry(ext_ep, i+0x40, chksum, uniname);
-+		buf_modify(sb, sector);
-+	}
-+
-+	return FFS_SUCCESS;
-+}
-+
-+static s32 exfat_init_ext_entry(struct super_block *sb, struct chain_t *p_dir,
-+				s32 entry, s32 num_entries,
-+				struct uni_name_t *p_uniname,
-+				struct dos_name_t *p_dosname)
-+{
-+	int i;
-+	sector_t sector;
-+	u16 *uniname = p_uniname->name;
-+	struct file_dentry_t *file_ep;
-+	struct strm_dentry_t *strm_ep;
-+	struct name_dentry_t *name_ep;
-+
-+	file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry,
-+							   &sector);
-+	if (!file_ep)
-+		return FFS_MEDIAERR;
-+
-+	file_ep->num_ext = (u8)(num_entries - 1);
-+	buf_modify(sb, sector);
-+
-+	strm_ep = (struct strm_dentry_t *)get_entry_in_dir(sb, p_dir, entry+1,
-+							   &sector);
-+	if (!strm_ep)
-+		return FFS_MEDIAERR;
-+
-+	strm_ep->name_len = p_uniname->name_len;
-+	SET16_A(strm_ep->name_hash, p_uniname->name_hash);
-+	buf_modify(sb, sector);
-+
-+	for (i = 2; i < num_entries; i++) {
-+		name_ep = (struct name_dentry_t *)get_entry_in_dir(sb, p_dir,
-+								   entry + i,
-+								   &sector);
-+		if (!name_ep)
-+			return FFS_MEDIAERR;
-+
-+		init_name_entry(name_ep, uniname);
-+		buf_modify(sb, sector);
-+		uniname += 15;
-+	}
-+
-+	update_dir_checksum(sb, p_dir, entry);
-+
-+	return FFS_SUCCESS;
-+}
-+
-+void init_dos_entry(struct dos_dentry_t *ep, u32 type, u32 start_clu)
-+{
-+	struct timestamp_t tm, *tp;
-+
-+	fat_set_entry_type((struct dentry_t *) ep, type);
-+	SET16_A(ep->start_clu_lo, CLUSTER_16(start_clu));
-+	SET16_A(ep->start_clu_hi, CLUSTER_16(start_clu >> 16));
-+	SET32_A(ep->size, 0);
-+
-+	tp = tm_current(&tm);
-+	fat_set_entry_time((struct dentry_t *) ep, tp, TM_CREATE);
-+	fat_set_entry_time((struct dentry_t *) ep, tp, TM_MODIFY);
-+	SET16_A(ep->access_date, 0);
-+	ep->create_time_ms = 0;
-+}
-+
-+void init_ext_entry(struct ext_dentry_t *ep, s32 order, u8 chksum, u16 *uniname)
-+{
-+	int i;
-+	u8 end = FALSE;
-+
-+	fat_set_entry_type((struct dentry_t *) ep, TYPE_EXTEND);
-+	ep->order = (u8) order;
-+	ep->sysid = 0;
-+	ep->checksum = chksum;
-+	SET16_A(ep->start_clu, 0);
-+
-+	for (i = 0; i < 10; i += 2) {
-+		if (!end) {
-+			SET16(ep->unicode_0_4+i, *uniname);
-+			if (*uniname == 0x0)
-+				end = TRUE;
-+			else
-+				uniname++;
-+		} else {
-+			SET16(ep->unicode_0_4+i, 0xFFFF);
-+		}
-+	}
-+
-+	for (i = 0; i < 12; i += 2) {
-+		if (!end) {
-+			SET16_A(ep->unicode_5_10 + i, *uniname);
-+			if (*uniname == 0x0)
-+				end = TRUE;
-+			else
-+				uniname++;
-+		} else {
-+			SET16_A(ep->unicode_5_10 + i, 0xFFFF);
-+		}
-+	}
-+
-+	for (i = 0; i < 4; i += 2) {
-+		if (!end) {
-+			SET16_A(ep->unicode_11_12 + i, *uniname);
-+			if (*uniname == 0x0)
-+				end = TRUE;
-+			else
-+				uniname++;
-+		} else {
-+			SET16_A(ep->unicode_11_12 + i, 0xFFFF);
-+		}
-+	}
-+}
-+
-+void init_file_entry(struct file_dentry_t *ep, u32 type)
-+{
-+	struct timestamp_t tm, *tp;
-+
-+	exfat_set_entry_type((struct dentry_t *)ep, type);
-+
-+	tp = tm_current(&tm);
-+	exfat_set_entry_time((struct dentry_t *)ep, tp, TM_CREATE);
-+	exfat_set_entry_time((struct dentry_t *)ep, tp, TM_MODIFY);
-+	exfat_set_entry_time((struct dentry_t *)ep, tp, TM_ACCESS);
-+	ep->create_time_ms = 0;
-+	ep->modify_time_ms = 0;
-+	ep->access_time_ms = 0;
-+}
-+
-+void init_strm_entry(struct strm_dentry_t *ep, u8 flags, u32 start_clu, u64 size)
-+{
-+	exfat_set_entry_type((struct dentry_t *)ep, TYPE_STREAM);
-+	ep->flags = flags;
-+	SET32_A(ep->start_clu, start_clu);
-+	SET64_A(ep->valid_size, size);
-+	SET64_A(ep->size, size);
-+}
-+
-+void init_name_entry(struct name_dentry_t *ep, u16 *uniname)
-+{
-+	int i;
-+
-+	exfat_set_entry_type((struct dentry_t *)ep, TYPE_EXTEND);
-+	ep->flags = 0x0;
-+
-+	for (i = 0; i < 30; i++, i++) {
-+		SET16_A(ep->unicode_0_14+i, *uniname);
-+		if (*uniname == 0x0)
-+			break;
-+		uniname++;
-+	}
-+}
-+
-+void fat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+		s32 entry, s32 order, s32 num_entries)
-+{
-+	int i;
-+	sector_t sector;
-+	struct dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	for (i = num_entries-1; i >= order; i--) {
-+		ep = get_entry_in_dir(sb, p_dir, entry-i, &sector);
-+		if (!ep)
-+			return;
-+
-+		p_fs->fs_func->set_entry_type(ep, TYPE_DELETED);
-+		buf_modify(sb, sector);
-+	}
-+}
-+
-+void exfat_delete_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+		s32 entry, s32 order, s32 num_entries)
-+{
-+	int i;
-+	sector_t sector;
-+	struct dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	for (i = order; i < num_entries; i++) {
-+		ep = get_entry_in_dir(sb, p_dir, entry+i, &sector);
-+		if (!ep)
-+			return;
-+
-+		p_fs->fs_func->set_entry_type(ep, TYPE_DELETED);
-+		buf_modify(sb, sector);
-+	}
-+}
-+
-+void update_dir_checksum(struct super_block *sb, struct chain_t *p_dir,
-+			 s32 entry)
-+{
-+	int i, num_entries;
-+	sector_t sector;
-+	u16 chksum;
-+	struct file_dentry_t *file_ep;
-+	struct dentry_t *ep;
-+
-+	file_ep = (struct file_dentry_t *)get_entry_in_dir(sb, p_dir, entry,
-+							   &sector);
-+	if (!file_ep)
-+		return;
-+
-+	buf_lock(sb, sector);
-+
-+	num_entries = (s32) file_ep->num_ext + 1;
-+	chksum = calc_checksum_2byte((void *)file_ep, DENTRY_SIZE, 0,
-+				     CS_DIR_ENTRY);
-+
-+	for (i = 1; i < num_entries; i++) {
-+		ep = get_entry_in_dir(sb, p_dir, entry+i, NULL);
-+		if (!ep) {
-+			buf_unlock(sb, sector);
-+			return;
-+		}
-+
-+		chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum,
-+					     CS_DEFAULT);
-+	}
-+
-+	SET16_A(file_ep->checksum, chksum);
-+	buf_modify(sb, sector);
-+	buf_unlock(sb, sector);
-+}
-+
-+void update_dir_checksum_with_entry_set(struct super_block *sb,
-+					struct entry_set_cache_t *es)
-+{
-+	struct dentry_t *ep;
-+	u16 chksum = 0;
-+	s32 chksum_type = CS_DIR_ENTRY, i;
-+
-+	ep = (struct dentry_t *)&(es->__buf);
-+	for (i = 0; i < es->num_entries; i++) {
-+		pr_debug("%s ep %p\n", __func__, ep);
-+		chksum = calc_checksum_2byte((void *)ep, DENTRY_SIZE, chksum,
-+					     chksum_type);
-+		ep++;
-+		chksum_type = CS_DEFAULT;
-+	}
-+
-+	ep = (struct dentry_t *)&(es->__buf);
-+	SET16_A(((struct file_dentry_t *)ep)->checksum, chksum);
-+	write_whole_entry_set(sb, es);
-+}
-+
-+static s32 _walk_fat_chain(struct super_block *sb, struct chain_t *p_dir,
-+			   s32 byte_offset, u32 *clu)
-+{
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	s32 clu_offset;
-+	u32 cur_clu;
-+
-+	clu_offset = byte_offset >> p_fs->cluster_size_bits;
-+	cur_clu = p_dir->dir;
-+
-+	if (p_dir->flags == 0x03) {
-+		cur_clu += clu_offset;
-+	} else {
-+		while (clu_offset > 0) {
-+			if (FAT_read(sb, cur_clu, &cur_clu) == -1)
-+				return FFS_MEDIAERR;
-+			clu_offset--;
-+		}
-+	}
-+
-+	if (clu)
-+		*clu = cur_clu;
-+	return FFS_SUCCESS;
-+}
-+
-+s32 find_location(struct super_block *sb, struct chain_t *p_dir, s32 entry,
-+		  sector_t *sector, s32 *offset)
-+{
-+	s32 off, ret;
-+	u32 clu = 0;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	off = entry << DENTRY_SIZE_BITS;
-+
-+	if (p_dir->dir == CLUSTER_32(0)) { /* FAT16 root_dir */
-+		*offset = off & p_bd->sector_size_mask;
-+		*sector = off >> p_bd->sector_size_bits;
-+		*sector += p_fs->root_start_sector;
-+	} else {
-+		ret = _walk_fat_chain(sb, p_dir, off, &clu);
-+		if (ret != FFS_SUCCESS)
-+			return ret;
-+
-+		/* byte offset in cluster */
-+		off &= p_fs->cluster_size - 1;
-+
-+		/* byte offset in sector    */
-+		*offset = off & p_bd->sector_size_mask;
-+
-+		/* sector offset in cluster */
-+		*sector = off >> p_bd->sector_size_bits;
-+		*sector += START_SECTOR(clu);
-+	}
-+	return FFS_SUCCESS;
-+}
-+
-+struct dentry_t *get_entry_with_sector(struct super_block *sb, sector_t sector,
-+				       s32 offset)
-+{
-+	u8 *buf;
-+
-+	buf = buf_getblk(sb, sector);
-+
-+	if (buf == NULL)
-+		return NULL;
-+
-+	return (struct dentry_t *)(buf + offset);
-+}
-+
-+struct dentry_t *get_entry_in_dir(struct super_block *sb, struct chain_t *p_dir,
-+				  s32 entry, sector_t *sector)
-+{
-+	s32 off;
-+	sector_t sec;
-+	u8 *buf;
-+
-+	if (find_location(sb, p_dir, entry, &sec, &off) != FFS_SUCCESS)
-+		return NULL;
-+
-+	buf = buf_getblk(sb, sec);
-+
-+	if (buf == NULL)
-+		return NULL;
-+
-+	if (sector != NULL)
-+		*sector = sec;
-+	return (struct dentry_t *)(buf + off);
-+}
-+
-+/* returns a set of dentries for a file or dir.
-+ * Note that this is a copy (dump) of dentries so that user should call write_entry_set()
-+ * to apply changes made in this entry set to the real device.
-+ * in:
-+ *   sb+p_dir+entry: indicates a file/dir
-+ *   type:  specifies how many dentries should be included.
-+ * out:
-+ *   file_ep: will point the first dentry(= file dentry) on success
-+ * return:
-+ *   pointer of entry set on success,
-+ *   NULL on failure.
-+ */
-+
-+#define ES_MODE_STARTED				0
-+#define ES_MODE_GET_FILE_ENTRY			1
-+#define ES_MODE_GET_STRM_ENTRY			2
-+#define ES_MODE_GET_NAME_ENTRY			3
-+#define ES_MODE_GET_CRITICAL_SEC_ENTRY		4
-+struct entry_set_cache_t *get_entry_set_in_dir(struct super_block *sb,
-+					       struct chain_t *p_dir, s32 entry,
-+					       u32 type,
-+					       struct dentry_t **file_ep)
-+{
-+	s32 off, ret, byte_offset;
-+	u32 clu = 0;
-+	sector_t sec;
-+	u32 entry_type;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+	struct entry_set_cache_t *es = NULL;
-+	struct dentry_t *ep, *pos;
-+	u8 *buf;
-+	u8 num_entries;
-+	s32 mode = ES_MODE_STARTED;
-+	size_t bufsize;
-+
-+	pr_debug("%s entered p_dir dir %u flags %x size %d\n",
-+		__func__, p_dir->dir, p_dir->flags, p_dir->size);
-+
-+	byte_offset = entry << DENTRY_SIZE_BITS;
-+	ret = _walk_fat_chain(sb, p_dir, byte_offset, &clu);
-+	if (ret != FFS_SUCCESS)
-+		return NULL;
-+
-+
-+	/* byte offset in cluster */
-+	byte_offset &= p_fs->cluster_size - 1;
-+
-+	/* byte offset in sector    */
-+	off = byte_offset & p_bd->sector_size_mask;
-+
-+	/* sector offset in cluster */
-+	sec = byte_offset >> p_bd->sector_size_bits;
-+	sec += START_SECTOR(clu);
-+
-+	buf = buf_getblk(sb, sec);
-+	if (buf == NULL)
-+		goto err_out;
-+
-+
-+	ep = (struct dentry_t *)(buf + off);
-+	entry_type = p_fs->fs_func->get_entry_type(ep);
-+
-+	if ((entry_type != TYPE_FILE)
-+		&& (entry_type != TYPE_DIR))
-+		goto err_out;
-+
-+	if (type == ES_ALL_ENTRIES)
-+		num_entries = ((struct file_dentry_t *)ep)->num_ext+1;
-+	else
-+		num_entries = type;
-+
-+	bufsize = offsetof(struct entry_set_cache_t, __buf) + (num_entries) *
-+		  sizeof(struct dentry_t);
-+	pr_debug("%s: trying to kmalloc %zx bytes for %d entries\n", __func__,
-+		 bufsize, num_entries);
-+	es = kmalloc(bufsize, GFP_KERNEL);
-+	if (es == NULL)
-+		goto err_out;
-+
-+	es->num_entries = num_entries;
-+	es->sector = sec;
-+	es->offset = off;
-+	es->alloc_flag = p_dir->flags;
-+
-+	pos = (struct dentry_t *) &(es->__buf);
-+
-+	while (num_entries) {
-+		/*
-+		 * instead of copying whole sector, we will check every entry.
-+		 * this will provide minimum stablity and consistancy.
-+		 */
-+		entry_type = p_fs->fs_func->get_entry_type(ep);
-+
-+		if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED))
-+			goto err_out;
-+
-+		switch (mode) {
-+		case ES_MODE_STARTED:
-+			if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR))
-+				mode = ES_MODE_GET_FILE_ENTRY;
-+			else
-+				goto err_out;
-+			break;
-+		case ES_MODE_GET_FILE_ENTRY:
-+			if (entry_type == TYPE_STREAM)
-+				mode = ES_MODE_GET_STRM_ENTRY;
-+			else
-+				goto err_out;
-+			break;
-+		case ES_MODE_GET_STRM_ENTRY:
-+			if (entry_type == TYPE_EXTEND)
-+				mode = ES_MODE_GET_NAME_ENTRY;
-+			else
-+				goto err_out;
-+			break;
-+		case ES_MODE_GET_NAME_ENTRY:
-+			if (entry_type == TYPE_EXTEND)
-+				break;
-+			else if (entry_type == TYPE_STREAM)
-+				goto err_out;
-+			else if (entry_type & TYPE_CRITICAL_SEC)
-+				mode = ES_MODE_GET_CRITICAL_SEC_ENTRY;
-+			else
-+				goto err_out;
-+			break;
-+		case ES_MODE_GET_CRITICAL_SEC_ENTRY:
-+			if ((entry_type == TYPE_EXTEND) ||
-+			    (entry_type == TYPE_STREAM))
-+				goto err_out;
-+			else if ((entry_type & TYPE_CRITICAL_SEC) !=
-+				 TYPE_CRITICAL_SEC)
-+				goto err_out;
-+			break;
-+		}
-+
-+		memcpy(pos, ep, sizeof(struct dentry_t));
-+
-+		if (--num_entries == 0)
-+			break;
-+
-+		if (((off + DENTRY_SIZE) & p_bd->sector_size_mask) <
-+		    (off &  p_bd->sector_size_mask)) {
-+			/* get the next sector */
-+			if (IS_LAST_SECTOR_IN_CLUSTER(sec)) {
-+				if (es->alloc_flag == 0x03) {
-+					clu++;
-+				} else {
-+					if (FAT_read(sb, clu, &clu) == -1)
-+						goto err_out;
-+				}
-+				sec = START_SECTOR(clu);
-+			} else {
-+				sec++;
-+			}
-+			buf = buf_getblk(sb, sec);
-+			if (buf == NULL)
-+				goto err_out;
-+			off = 0;
-+			ep = (struct dentry_t *)(buf);
-+		} else {
-+			ep++;
-+			off += DENTRY_SIZE;
-+		}
-+		pos++;
-+	}
-+
-+	if (file_ep)
-+		*file_ep = (struct dentry_t *)&(es->__buf);
-+
-+	pr_debug("%s exiting es %p sec %llu offset %d flags %d, num_entries %u buf ptr %p\n",
-+		   __func__, es, (unsigned long long)es->sector, es->offset,
-+		   es->alloc_flag, es->num_entries, &es->__buf);
-+	return es;
-+err_out:
-+	pr_debug("%s exited NULL (es %p)\n", __func__, es);
-+	kfree(es);
-+	return NULL;
-+}
-+
-+void release_entry_set(struct entry_set_cache_t *es)
-+{
-+	pr_debug("%s es=%p\n", __func__, es);
-+	kfree(es);
-+}
-+
-+
-+static s32 __write_partial_entries_in_entry_set(struct super_block *sb,
-+						struct entry_set_cache_t *es,
-+						sector_t sec, s32 off, u32 count)
-+{
-+	s32 num_entries, buf_off = (off - es->offset);
-+	u32 remaining_byte_in_sector, copy_entries;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+	u32 clu;
-+	u8 *buf, *esbuf = (u8 *)&(es->__buf);
-+
-+	pr_debug("%s entered es %p sec %llu off %d count %d\n",
-+		__func__, es, (unsigned long long)sec, off, count);
-+	num_entries = count;
-+
-+	while (num_entries) {
-+		/* white per sector base */
-+		remaining_byte_in_sector = (1 << p_bd->sector_size_bits) - off;
-+		copy_entries = min_t(s32,
-+				     remaining_byte_in_sector >> DENTRY_SIZE_BITS,
-+				     num_entries);
-+		buf = buf_getblk(sb, sec);
-+		if (buf == NULL)
-+			goto err_out;
-+		pr_debug("es->buf %p buf_off %u\n", esbuf, buf_off);
-+		pr_debug("copying %d entries from %p to sector %llu\n",
-+			copy_entries, (esbuf + buf_off),
-+			(unsigned long long)sec);
-+		memcpy(buf + off, esbuf + buf_off,
-+		       copy_entries << DENTRY_SIZE_BITS);
-+		buf_modify(sb, sec);
-+		num_entries -= copy_entries;
-+
-+		if (num_entries) {
-+			/* get next sector */
-+			if (IS_LAST_SECTOR_IN_CLUSTER(sec)) {
-+				clu = GET_CLUSTER_FROM_SECTOR(sec);
-+				if (es->alloc_flag == 0x03) {
-+					clu++;
-+				} else {
-+					if (FAT_read(sb, clu, &clu) == -1)
-+						goto err_out;
-+				}
-+				sec = START_SECTOR(clu);
-+			} else {
-+				sec++;
-+			}
-+			off = 0;
-+			buf_off += copy_entries << DENTRY_SIZE_BITS;
-+		}
-+	}
-+
-+	pr_debug("%s exited successfully\n", __func__);
-+	return FFS_SUCCESS;
-+err_out:
-+	pr_debug("%s failed\n", __func__);
-+	return FFS_ERROR;
-+}
-+
-+/* write back all entries in entry set */
-+s32 write_whole_entry_set(struct super_block *sb, struct entry_set_cache_t *es)
-+{
-+	return __write_partial_entries_in_entry_set(sb, es, es->sector,
-+						    es->offset,
-+						    es->num_entries);
-+}
-+
-+/* write back some entries in entry set */
-+s32 write_partial_entries_in_entry_set(struct super_block *sb,
-+	struct entry_set_cache_t *es, struct dentry_t *ep, u32 count)
-+{
-+	s32 ret, byte_offset, off;
-+	u32 clu = 0;
-+	sector_t sec;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+	struct chain_t dir;
-+
-+	/* vaidity check */
-+	if (ep + count  > ((struct dentry_t *)&(es->__buf)) + es->num_entries)
-+		return FFS_ERROR;
-+
-+	dir.dir = GET_CLUSTER_FROM_SECTOR(es->sector);
-+	dir.flags = es->alloc_flag;
-+	dir.size = 0xffffffff;		/* XXX */
-+
-+	byte_offset = (es->sector - START_SECTOR(dir.dir)) <<
-+			p_bd->sector_size_bits;
-+	byte_offset += ((void **)ep - &(es->__buf)) + es->offset;
-+
-+	ret = _walk_fat_chain(sb, &dir, byte_offset, &clu);
-+	if (ret != FFS_SUCCESS)
-+		return ret;
-+
-+	/* byte offset in cluster */
-+	byte_offset &= p_fs->cluster_size - 1;
-+
-+	/* byte offset in sector    */
-+	off = byte_offset & p_bd->sector_size_mask;
-+
-+	/* sector offset in cluster */
-+	sec = byte_offset >> p_bd->sector_size_bits;
-+	sec += START_SECTOR(clu);
-+	return __write_partial_entries_in_entry_set(sb, es, sec, off, count);
-+}
-+
-+/* search EMPTY CONTINUOUS "num_entries" entries */
-+s32 search_deleted_or_unused_entry(struct super_block *sb,
-+				   struct chain_t *p_dir, s32 num_entries)
-+{
-+	int i, dentry, num_empty = 0;
-+	s32 dentries_per_clu;
-+	u32 type;
-+	struct chain_t clu;
-+	struct dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+		dentries_per_clu = p_fs->dentries_in_root;
-+	else
-+		dentries_per_clu = p_fs->dentries_per_clu;
-+
-+	if (p_fs->hint_uentry.dir == p_dir->dir) {
-+		if (p_fs->hint_uentry.entry == -1)
-+			return -1;
-+
-+		clu.dir = p_fs->hint_uentry.clu.dir;
-+		clu.size = p_fs->hint_uentry.clu.size;
-+		clu.flags = p_fs->hint_uentry.clu.flags;
-+
-+		dentry = p_fs->hint_uentry.entry;
-+	} else {
-+		p_fs->hint_uentry.entry = -1;
-+
-+		clu.dir = p_dir->dir;
-+		clu.size = p_dir->size;
-+		clu.flags = p_dir->flags;
-+
-+		dentry = 0;
-+	}
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+			i = dentry % dentries_per_clu;
-+		else
-+			i = dentry & (dentries_per_clu-1);
-+
-+		for (; i < dentries_per_clu; i++, dentry++) {
-+			ep = get_entry_in_dir(sb, &clu, i, NULL);
-+			if (!ep)
-+				return -1;
-+
-+			type = p_fs->fs_func->get_entry_type(ep);
-+
-+			if (type == TYPE_UNUSED) {
-+				num_empty++;
-+				if (p_fs->hint_uentry.entry == -1) {
-+					p_fs->hint_uentry.dir = p_dir->dir;
-+					p_fs->hint_uentry.entry = dentry;
-+
-+					p_fs->hint_uentry.clu.dir = clu.dir;
-+					p_fs->hint_uentry.clu.size = clu.size;
-+					p_fs->hint_uentry.clu.flags = clu.flags;
-+				}
-+			} else if (type == TYPE_DELETED) {
-+				num_empty++;
-+			} else {
-+				num_empty = 0;
-+			}
-+
-+			if (num_empty >= num_entries) {
-+				p_fs->hint_uentry.dir = CLUSTER_32(~0);
-+				p_fs->hint_uentry.entry = -1;
-+
-+				if (p_fs->vol_type == EXFAT)
-+					return dentry - (num_entries-1);
-+				else
-+					return dentry;
-+			}
-+		}
-+
-+		if (p_dir->dir == CLUSTER_32(0))
-+			break; /* FAT16 root_dir */
-+
-+		if (clu.flags == 0x03) {
-+			if ((--clu.size) > 0)
-+				clu.dir++;
-+			else
-+				clu.dir = CLUSTER_32(~0);
-+		} else {
-+			if (FAT_read(sb, clu.dir, &clu.dir) != 0)
-+				return -1;
-+		}
-+	}
-+
-+	return -1;
-+}
-+
-+s32 find_empty_entry(struct inode *inode, struct chain_t *p_dir, s32 num_entries)
-+{
-+	s32 ret, dentry;
-+	u32 last_clu;
-+	sector_t sector;
-+	u64 size = 0;
-+	struct chain_t clu;
-+	struct dentry_t *ep = NULL;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+
-+	if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+		return search_deleted_or_unused_entry(sb, p_dir, num_entries);
-+
-+	while ((dentry = search_deleted_or_unused_entry(sb, p_dir, num_entries)) < 0) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		if (p_fs->vol_type == EXFAT) {
-+			if (p_dir->dir != p_fs->root_dir)
-+				size = i_size_read(inode);
-+		}
-+
-+		last_clu = find_last_cluster(sb, p_dir);
-+		clu.dir = last_clu + 1;
-+		clu.size = 0;
-+		clu.flags = p_dir->flags;
-+
-+		/* (1) allocate a cluster */
-+		ret = p_fs->fs_func->alloc_cluster(sb, 1, &clu);
-+		if (ret < 1)
-+			return -1;
-+
-+		if (clear_cluster(sb, clu.dir) != FFS_SUCCESS)
-+			return -1;
-+
-+		/* (2) append to the FAT chain */
-+		if (clu.flags != p_dir->flags) {
-+			exfat_chain_cont_cluster(sb, p_dir->dir, p_dir->size);
-+			p_dir->flags = 0x01;
-+			p_fs->hint_uentry.clu.flags = 0x01;
-+		}
-+		if (clu.flags == 0x01)
-+			if (FAT_write(sb, last_clu, clu.dir) < 0)
-+				return -1;
-+
-+		if (p_fs->hint_uentry.entry == -1) {
-+			p_fs->hint_uentry.dir = p_dir->dir;
-+			p_fs->hint_uentry.entry = p_dir->size << (p_fs->cluster_size_bits - DENTRY_SIZE_BITS);
-+
-+			p_fs->hint_uentry.clu.dir = clu.dir;
-+			p_fs->hint_uentry.clu.size = 0;
-+			p_fs->hint_uentry.clu.flags = clu.flags;
-+		}
-+		p_fs->hint_uentry.clu.size++;
-+		p_dir->size++;
-+
-+		/* (3) update the directory entry */
-+		if (p_fs->vol_type == EXFAT) {
-+			if (p_dir->dir != p_fs->root_dir) {
-+				size += p_fs->cluster_size;
-+
-+				ep = get_entry_in_dir(sb, &fid->dir,
-+						      fid->entry + 1, &sector);
-+				if (!ep)
-+					return -1;
-+				p_fs->fs_func->set_entry_size(ep, size);
-+				p_fs->fs_func->set_entry_flag(ep, p_dir->flags);
-+				buf_modify(sb, sector);
-+
-+				update_dir_checksum(sb, &(fid->dir),
-+						    fid->entry);
-+			}
-+		}
-+
-+		i_size_write(inode, i_size_read(inode)+p_fs->cluster_size);
-+		EXFAT_I(inode)->mmu_private += p_fs->cluster_size;
-+		EXFAT_I(inode)->fid.size += p_fs->cluster_size;
-+		EXFAT_I(inode)->fid.flags = p_dir->flags;
-+		inode->i_blocks += 1 << (p_fs->cluster_size_bits - 9);
-+	}
-+
-+	return dentry;
-+}
-+
-+/* return values of fat_find_dir_entry()
-+ * >= 0 : return dir entiry position with the name in dir
-+ * -1 : (root dir, ".") it is the root dir itself
-+ * -2 : entry with the name does not exist
-+ */
-+s32 fat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+		       struct uni_name_t *p_uniname, s32 num_entries,
-+		       struct dos_name_t *p_dosname, u32 type)
-+{
-+	int i, dentry = 0, lossy = FALSE, len;
-+	s32 order = 0, is_feasible_entry = TRUE, has_ext_entry = FALSE;
-+	s32 dentries_per_clu;
-+	u32 entry_type;
-+	u16 entry_uniname[14], *uniname = NULL, unichar;
-+	struct chain_t clu;
-+	struct dentry_t *ep;
-+	struct dos_dentry_t *dos_ep;
-+	struct ext_dentry_t *ext_ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (p_dir->dir == p_fs->root_dir) {
-+		if ((!nls_uniname_cmp(sb, p_uniname->name,
-+				      (u16 *)UNI_CUR_DIR_NAME)) ||
-+			(!nls_uniname_cmp(sb, p_uniname->name,
-+					  (u16 *)UNI_PAR_DIR_NAME)))
-+			return -1; // special case, root directory itself
-+	}
-+
-+	if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+		dentries_per_clu = p_fs->dentries_in_root;
-+	else
-+		dentries_per_clu = p_fs->dentries_per_clu;
-+
-+	clu.dir = p_dir->dir;
-+	clu.flags = p_dir->flags;
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		for (i = 0; i < dentries_per_clu; i++, dentry++) {
-+			ep = get_entry_in_dir(sb, &clu, i, NULL);
-+			if (!ep)
-+				return -2;
-+
-+			entry_type = p_fs->fs_func->get_entry_type(ep);
-+
-+			if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) {
-+				if ((type == TYPE_ALL) || (type == entry_type)) {
-+					if (is_feasible_entry && has_ext_entry)
-+						return dentry;
-+
-+					dos_ep = (struct dos_dentry_t *) ep;
-+					if ((!lossy) && (!nls_dosname_cmp(sb, p_dosname->name, dos_ep->name)))
-+						return dentry;
-+				}
-+				is_feasible_entry = TRUE;
-+				has_ext_entry = FALSE;
-+			} else if (entry_type == TYPE_EXTEND) {
-+				if (is_feasible_entry) {
-+					ext_ep = (struct ext_dentry_t *) ep;
-+					if (ext_ep->order > 0x40) {
-+						order = (s32)(ext_ep->order - 0x40);
-+						uniname = p_uniname->name + 13 * (order-1);
-+					} else {
-+						order = (s32) ext_ep->order;
-+						uniname -= 13;
-+					}
-+
-+					len = extract_uni_name_from_ext_entry(ext_ep, entry_uniname, order);
-+
-+					unichar = *(uniname+len);
-+					*(uniname+len) = 0x0;
-+
-+					if (nls_uniname_cmp(sb, uniname, entry_uniname))
-+						is_feasible_entry = FALSE;
-+
-+					*(uniname+len) = unichar;
-+				}
-+				has_ext_entry = TRUE;
-+			} else if (entry_type == TYPE_UNUSED) {
-+				return -2;
-+			}
-+			is_feasible_entry = TRUE;
-+			has_ext_entry = FALSE;
-+		}
-+
-+		if (p_dir->dir == CLUSTER_32(0))
-+			break; /* FAT16 root_dir */
-+
-+		if (FAT_read(sb, clu.dir, &clu.dir) != 0)
-+			return -2;
-+	}
-+
-+	return -2;
-+}
-+
-+/* return values of exfat_find_dir_entry()
-+ * >= 0 : return dir entiry position with the name in dir
-+ * -1 : (root dir, ".") it is the root dir itself
-+ * -2 : entry with the name does not exist
-+ */
-+s32 exfat_find_dir_entry(struct super_block *sb, struct chain_t *p_dir,
-+			 struct uni_name_t *p_uniname, s32 num_entries,
-+			 struct dos_name_t *p_dosname, u32 type)
-+{
-+	int i = 0, dentry = 0, num_ext_entries = 0, len, step;
-+	s32 order = 0, is_feasible_entry = FALSE;
-+	s32 dentries_per_clu, num_empty = 0;
-+	u32 entry_type;
-+	u16 entry_uniname[16], *uniname = NULL, unichar;
-+	struct chain_t clu;
-+	struct dentry_t *ep;
-+	struct file_dentry_t *file_ep;
-+	struct strm_dentry_t *strm_ep;
-+	struct name_dentry_t *name_ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (p_dir->dir == p_fs->root_dir) {
-+		if ((!nls_uniname_cmp(sb, p_uniname->name,
-+				      (u16 *)UNI_CUR_DIR_NAME)) ||
-+			(!nls_uniname_cmp(sb, p_uniname->name,
-+					  (u16 *)UNI_PAR_DIR_NAME)))
-+			return -1; // special case, root directory itself
-+	}
-+
-+	if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+		dentries_per_clu = p_fs->dentries_in_root;
-+	else
-+		dentries_per_clu = p_fs->dentries_per_clu;
-+
-+	clu.dir = p_dir->dir;
-+	clu.size = p_dir->size;
-+	clu.flags = p_dir->flags;
-+
-+	p_fs->hint_uentry.dir = p_dir->dir;
-+	p_fs->hint_uentry.entry = -1;
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		while (i < dentries_per_clu) {
-+			ep = get_entry_in_dir(sb, &clu, i, NULL);
-+			if (!ep)
-+				return -2;
-+
-+			entry_type = p_fs->fs_func->get_entry_type(ep);
-+			step = 1;
-+
-+			if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) {
-+				is_feasible_entry = FALSE;
-+
-+				if (p_fs->hint_uentry.entry == -1) {
-+					num_empty++;
-+
-+					if (num_empty == 1) {
-+						p_fs->hint_uentry.clu.dir = clu.dir;
-+						p_fs->hint_uentry.clu.size = clu.size;
-+						p_fs->hint_uentry.clu.flags = clu.flags;
-+					}
-+					if ((num_empty >= num_entries) || (entry_type == TYPE_UNUSED))
-+						p_fs->hint_uentry.entry = dentry - (num_empty-1);
-+				}
-+
-+				if (entry_type == TYPE_UNUSED)
-+					return -2;
-+			} else {
-+				num_empty = 0;
-+
-+				if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) {
-+					file_ep = (struct file_dentry_t *) ep;
-+					if ((type == TYPE_ALL) || (type == entry_type)) {
-+						num_ext_entries = file_ep->num_ext;
-+						is_feasible_entry = TRUE;
-+					} else {
-+						is_feasible_entry = FALSE;
-+						step = file_ep->num_ext + 1;
-+					}
-+				} else if (entry_type == TYPE_STREAM) {
-+					if (is_feasible_entry) {
-+						strm_ep = (struct strm_dentry_t *)ep;
-+						if (p_uniname->name_hash == GET16_A(strm_ep->name_hash) &&
-+						    p_uniname->name_len == strm_ep->name_len) {
-+							order = 1;
-+						} else {
-+							is_feasible_entry = FALSE;
-+							step = num_ext_entries;
-+						}
-+					}
-+				} else if (entry_type == TYPE_EXTEND) {
-+					if (is_feasible_entry) {
-+						name_ep = (struct name_dentry_t *)ep;
-+
-+						if ((++order) == 2)
-+							uniname = p_uniname->name;
-+						else
-+							uniname += 15;
-+
-+						len = extract_uni_name_from_name_entry(name_ep,
-+								entry_uniname, order);
-+
-+						unichar = *(uniname+len);
-+						*(uniname+len) = 0x0;
-+
-+						if (nls_uniname_cmp(sb, uniname, entry_uniname)) {
-+							is_feasible_entry = FALSE;
-+							step = num_ext_entries - order + 1;
-+						} else if (order == num_ext_entries) {
-+							p_fs->hint_uentry.dir = CLUSTER_32(~0);
-+							p_fs->hint_uentry.entry = -1;
-+							return dentry - (num_ext_entries);
-+						}
-+
-+						*(uniname+len) = unichar;
-+					}
-+				} else {
-+					is_feasible_entry = FALSE;
-+				}
-+			}
-+
-+			i += step;
-+			dentry += step;
-+		}
-+
-+		i -= dentries_per_clu;
-+
-+		if (p_dir->dir == CLUSTER_32(0))
-+			break; /* FAT16 root_dir */
-+
-+		if (clu.flags == 0x03) {
-+			if ((--clu.size) > 0)
-+				clu.dir++;
-+			else
-+				clu.dir = CLUSTER_32(~0);
-+		} else {
-+			if (FAT_read(sb, clu.dir, &clu.dir) != 0)
-+				return -2;
-+		}
-+	}
-+
-+	return -2;
-+}
-+
-+s32 fat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir,
-+			  s32 entry, struct dentry_t *p_entry)
-+{
-+	s32 count = 0;
-+	u8 chksum;
-+	struct dos_dentry_t *dos_ep = (struct dos_dentry_t *) p_entry;
-+	struct ext_dentry_t *ext_ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	chksum = calc_checksum_1byte((void *) dos_ep->name, DOS_NAME_LENGTH, 0);
-+
-+	for (entry--; entry >= 0; entry--) {
-+		ext_ep = (struct ext_dentry_t *)get_entry_in_dir(sb, p_dir,
-+								 entry, NULL);
-+		if (!ext_ep)
-+			return -1;
-+
-+		if ((p_fs->fs_func->get_entry_type((struct dentry_t *)ext_ep) ==
-+		     TYPE_EXTEND) && (ext_ep->checksum == chksum)) {
-+			count++;
-+			if (ext_ep->order > 0x40)
-+				return count;
-+		} else {
-+			return count;
-+		}
-+	}
-+
-+	return count;
-+}
-+
-+s32 exfat_count_ext_entries(struct super_block *sb, struct chain_t *p_dir,
-+			    s32 entry, struct dentry_t *p_entry)
-+{
-+	int i, count = 0;
-+	u32 type;
-+	struct file_dentry_t *file_ep = (struct file_dentry_t *)p_entry;
-+	struct dentry_t *ext_ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	for (i = 0, entry++; i < file_ep->num_ext; i++, entry++) {
-+		ext_ep = get_entry_in_dir(sb, p_dir, entry, NULL);
-+		if (!ext_ep)
-+			return -1;
-+
-+		type = p_fs->fs_func->get_entry_type(ext_ep);
-+		if ((type == TYPE_EXTEND) || (type == TYPE_STREAM))
-+			count++;
-+		else
-+			return count;
-+	}
-+
-+	return count;
-+}
-+
-+s32 count_dos_name_entries(struct super_block *sb, struct chain_t *p_dir,
-+			   u32 type)
-+{
-+	int i, count = 0;
-+	s32 dentries_per_clu;
-+	u32 entry_type;
-+	struct chain_t clu;
-+	struct dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+		dentries_per_clu = p_fs->dentries_in_root;
-+	else
-+		dentries_per_clu = p_fs->dentries_per_clu;
-+
-+	clu.dir = p_dir->dir;
-+	clu.size = p_dir->size;
-+	clu.flags = p_dir->flags;
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		for (i = 0; i < dentries_per_clu; i++) {
-+			ep = get_entry_in_dir(sb, &clu, i, NULL);
-+			if (!ep)
-+				return -1;
-+
-+			entry_type = p_fs->fs_func->get_entry_type(ep);
-+
-+			if (entry_type == TYPE_UNUSED)
-+				return count;
-+			if (!(type & TYPE_CRITICAL_PRI) &&
-+			    !(type & TYPE_BENIGN_PRI))
-+				continue;
-+
-+			if ((type == TYPE_ALL) || (type == entry_type))
-+				count++;
-+		}
-+
-+		if (p_dir->dir == CLUSTER_32(0))
-+			break; /* FAT16 root_dir */
-+
-+		if (clu.flags == 0x03) {
-+			if ((--clu.size) > 0)
-+				clu.dir++;
-+			else
-+				clu.dir = CLUSTER_32(~0);
-+		} else {
-+			if (FAT_read(sb, clu.dir, &clu.dir) != 0)
-+				return -1;
-+		}
-+	}
-+
-+	return count;
-+}
-+
-+bool is_dir_empty(struct super_block *sb, struct chain_t *p_dir)
-+{
-+	int i, count = 0;
-+	s32 dentries_per_clu;
-+	u32 type;
-+	struct chain_t clu;
-+	struct dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+		dentries_per_clu = p_fs->dentries_in_root;
-+	else
-+		dentries_per_clu = p_fs->dentries_per_clu;
-+
-+	clu.dir = p_dir->dir;
-+	clu.size = p_dir->size;
-+	clu.flags = p_dir->flags;
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		for (i = 0; i < dentries_per_clu; i++) {
-+			ep = get_entry_in_dir(sb, &clu, i, NULL);
-+			if (!ep)
-+				break;
-+
-+			type = p_fs->fs_func->get_entry_type(ep);
-+
-+			if (type == TYPE_UNUSED)
-+				return TRUE;
-+			if ((type != TYPE_FILE) && (type != TYPE_DIR))
-+				continue;
-+
-+			if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+				return FALSE;
-+
-+			if (p_fs->vol_type == EXFAT)
-+				return FALSE;
-+			if ((p_dir->dir == p_fs->root_dir) || ((++count) > 2))
-+				return FALSE;
-+		}
-+
-+		if (p_dir->dir == CLUSTER_32(0))
-+			break; /* FAT16 root_dir */
-+
-+		if (clu.flags == 0x03) {
-+			if ((--clu.size) > 0)
-+				clu.dir++;
-+			else
-+				clu.dir = CLUSTER_32(~0);
-+		}
-+		if (FAT_read(sb, clu.dir, &clu.dir) != 0)
-+			break;
-+	}
-+
-+	return TRUE;
-+}
-+
-+/*
-+ *  Name Conversion Functions
-+ */
-+
-+/* input  : dir, uni_name
-+ * output : num_of_entry, dos_name(format : aaaaaa~1.bbb)
-+ */
-+s32 get_num_entries_and_dos_name(struct super_block *sb, struct chain_t *p_dir,
-+				 struct uni_name_t *p_uniname, s32 *entries,
-+				 struct dos_name_t *p_dosname)
-+{
-+	s32 ret, num_entries;
-+	bool lossy = false;
-+	char **r;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	num_entries = p_fs->fs_func->calc_num_entries(p_uniname);
-+	if (num_entries == 0)
-+		return FFS_INVALIDPATH;
-+
-+	if (p_fs->vol_type != EXFAT) {
-+		nls_uniname_to_dosname(sb, p_dosname, p_uniname, &lossy);
-+
-+		if (lossy) {
-+			ret = fat_generate_dos_name(sb, p_dir, p_dosname);
-+			if (ret)
-+				return ret;
-+		} else {
-+			for (r = reserved_names; *r; r++) {
-+				if (!strncmp((void *)p_dosname->name, *r, 8))
-+					return FFS_INVALIDPATH;
-+			}
-+
-+			if (p_dosname->name_case != 0xFF)
-+				num_entries = 1;
-+		}
-+
-+		if (num_entries > 1)
-+			p_dosname->name_case = 0x0;
-+	}
-+
-+	*entries = num_entries;
-+
-+	return FFS_SUCCESS;
-+}
-+
-+void get_uni_name_from_dos_entry(struct super_block *sb,
-+				 struct dos_dentry_t *ep,
-+				 struct uni_name_t *p_uniname, u8 mode)
-+{
-+	struct dos_name_t dos_name;
-+
-+	if (mode == 0x0)
-+		dos_name.name_case = 0x0;
-+	else
-+		dos_name.name_case = ep->lcase;
-+
-+	memcpy(dos_name.name, ep->name, DOS_NAME_LENGTH);
-+	nls_dosname_to_uniname(sb, p_uniname, &dos_name);
-+}
-+
-+void fat_get_uni_name_from_ext_entry(struct super_block *sb,
-+				     struct chain_t *p_dir, s32 entry,
-+				     u16 *uniname)
-+{
-+	int i;
-+	struct ext_dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	for (entry--, i = 1; entry >= 0; entry--, i++) {
-+		ep = (struct ext_dentry_t *)get_entry_in_dir(sb, p_dir, entry,
-+							     NULL);
-+		if (!ep)
-+			return;
-+
-+		if (p_fs->fs_func->get_entry_type((struct dentry_t *)ep) ==
-+		    TYPE_EXTEND) {
-+			extract_uni_name_from_ext_entry(ep, uniname, i);
-+			if (ep->order > 0x40)
-+				return;
-+		} else {
-+			return;
-+		}
-+
-+		uniname += 13;
-+	}
-+}
-+
-+void exfat_get_uni_name_from_ext_entry(struct super_block *sb,
-+				       struct chain_t *p_dir, s32 entry,
-+				       u16 *uniname)
-+{
-+	int i;
-+	struct dentry_t *ep;
-+	struct entry_set_cache_t *es;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	es = get_entry_set_in_dir(sb, p_dir, entry, ES_ALL_ENTRIES, &ep);
-+	if (es == NULL || es->num_entries < 3) {
-+		if (es)
-+			release_entry_set(es);
-+		return;
-+	}
-+
-+	ep += 2;
-+
-+	/*
-+	 * First entry  : file entry
-+	 * Second entry : stream-extension entry
-+	 * Third entry  : first file-name entry
-+	 * So, the index of first file-name dentry should start from 2.
-+	 */
-+	for (i = 2; i < es->num_entries; i++, ep++) {
-+		if (p_fs->fs_func->get_entry_type(ep) == TYPE_EXTEND)
-+			extract_uni_name_from_name_entry((struct name_dentry_t *)
-+							 ep, uniname, i);
-+		else
-+			goto out;
-+		uniname += 15;
-+	}
-+
-+out:
-+	release_entry_set(es);
-+}
-+
-+s32 extract_uni_name_from_ext_entry(struct ext_dentry_t *ep, u16 *uniname,
-+				    s32 order)
-+{
-+	int i, len = 0;
-+
-+	for (i = 0; i < 10; i += 2) {
-+		*uniname = GET16(ep->unicode_0_4 + i);
-+		if (*uniname == 0x0)
-+			return len;
-+		uniname++;
-+		len++;
-+	}
-+
-+	if (order < 20) {
-+		for (i = 0; i < 12; i += 2) {
-+			*uniname = GET16_A(ep->unicode_5_10 + i);
-+			if (*uniname == 0x0)
-+				return len;
-+			uniname++;
-+			len++;
-+		}
-+	} else {
-+		for (i = 0; i < 8; i += 2) {
-+			*uniname = GET16_A(ep->unicode_5_10 + i);
-+			if (*uniname == 0x0)
-+				return len;
-+			uniname++;
-+			len++;
-+		}
-+		*uniname = 0x0; /* uniname[MAX_NAME_LENGTH-1] */
-+		return len;
-+	}
-+
-+	for (i = 0; i < 4; i += 2) {
-+		*uniname = GET16_A(ep->unicode_11_12 + i);
-+		if (*uniname == 0x0)
-+			return len;
-+		uniname++;
-+		len++;
-+	}
-+
-+	*uniname = 0x0;
-+	return len;
-+}
-+
-+s32 extract_uni_name_from_name_entry(struct name_dentry_t *ep, u16 *uniname,
-+				     s32 order)
-+{
-+	int i, len = 0;
-+
-+	for (i = 0; i < 30; i += 2) {
-+		*uniname = GET16_A(ep->unicode_0_14 + i);
-+		if (*uniname == 0x0)
-+			return len;
-+		uniname++;
-+		len++;
-+	}
-+
-+	*uniname = 0x0;
-+	return len;
-+}
-+
-+s32 fat_generate_dos_name(struct super_block *sb, struct chain_t *p_dir,
-+			  struct dos_name_t *p_dosname)
-+{
-+	int i, j, count = 0, count_begin = FALSE;
-+	s32 dentries_per_clu;
-+	u32 type;
-+	u8 bmap[128/* 1 ~ 1023 */];
-+	struct chain_t clu;
-+	struct dos_dentry_t *ep;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	memset(bmap, 0, sizeof(bmap));
-+	exfat_bitmap_set(bmap, 0);
-+
-+	if (p_dir->dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+		dentries_per_clu = p_fs->dentries_in_root;
-+	else
-+		dentries_per_clu = p_fs->dentries_per_clu;
-+
-+	clu.dir = p_dir->dir;
-+	clu.flags = p_dir->flags;
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		for (i = 0; i < dentries_per_clu; i++) {
-+			ep = (struct dos_dentry_t *)get_entry_in_dir(sb, &clu,
-+								     i, NULL);
-+			if (!ep)
-+				return FFS_MEDIAERR;
-+
-+			type = p_fs->fs_func->get_entry_type((struct dentry_t *)
-+							     ep);
-+
-+			if (type == TYPE_UNUSED)
-+				break;
-+			if ((type != TYPE_FILE) && (type != TYPE_DIR))
-+				continue;
-+
-+			count = 0;
-+			count_begin = FALSE;
-+
-+			for (j = 0; j < 8; j++) {
-+				if (ep->name[j] == ' ')
-+					break;
-+
-+				if (ep->name[j] == '~') {
-+					count_begin = TRUE;
-+				} else if (count_begin) {
-+					if ((ep->name[j] >= '0') &&
-+					    (ep->name[j] <= '9')) {
-+						count = count * 10 +
-+							(ep->name[j] - '0');
-+					} else {
-+						count = 0;
-+						count_begin = FALSE;
-+					}
-+				}
-+			}
-+
-+			if ((count > 0) && (count < 1024))
-+				exfat_bitmap_set(bmap, count);
-+		}
-+
-+		if (p_dir->dir == CLUSTER_32(0))
-+			break; /* FAT16 root_dir */
-+
-+		if (FAT_read(sb, clu.dir, &clu.dir) != 0)
-+			return FFS_MEDIAERR;
-+	}
-+
-+	count = 0;
-+	for (i = 0; i < 128; i++) {
-+		if (bmap[i] != 0xFF) {
-+			for (j = 0; j < 8; j++) {
-+				if (exfat_bitmap_test(&bmap[i], j) == 0) {
-+					count = (i << 3) + j;
-+					break;
-+				}
-+			}
-+			if (count != 0)
-+				break;
-+		}
-+	}
-+
-+	if ((count == 0) || (count >= 1024))
-+		return FFS_FILEEXIST;
-+	fat_attach_count_to_dos_name(p_dosname->name, count);
-+
-+	/* Now dos_name has DOS~????.EXT */
-+	return FFS_SUCCESS;
-+}
-+
-+void fat_attach_count_to_dos_name(u8 *dosname, s32 count)
-+{
-+	int i, j, length;
-+	char str_count[6];
-+
-+	snprintf(str_count, sizeof(str_count), "~%d", count);
-+	length = strlen(str_count);
-+
-+	i = 0;
-+	j = 0;
-+	while (j <= (8 - length)) {
-+		i = j;
-+		if (dosname[j] == ' ')
-+			break;
-+		if (dosname[j] & 0x80)
-+			j += 2;
-+		else
-+			j++;
-+	}
-+
-+	for (j = 0; j < length; i++, j++)
-+		dosname[i] = (u8)str_count[j];
-+
-+	if (i == 7)
-+		dosname[7] = ' ';
-+}
-+
-+s32 fat_calc_num_entries(struct uni_name_t *p_uniname)
-+{
-+	s32 len;
-+
-+	len = p_uniname->name_len;
-+	if (len == 0)
-+		return 0;
-+
-+	/* 1 dos name entry + extended entries */
-+	return (len - 1) / 13 + 2;
-+}
-+
-+s32 exfat_calc_num_entries(struct uni_name_t *p_uniname)
-+{
-+	s32 len;
-+
-+	len = p_uniname->name_len;
-+	if (len == 0)
-+		return 0;
-+
-+	/* 1 file entry + 1 stream entry + name entries */
-+	return (len - 1) / 15 + 3;
-+}
-+
-+u8 calc_checksum_1byte(void *data, s32 len, u8 chksum)
-+{
-+	int i;
-+	u8 *c = (u8 *)data;
-+
-+	for (i = 0; i < len; i++, c++)
-+		chksum = (((chksum & 1) << 7) | ((chksum & 0xFE) >> 1)) + *c;
-+
-+	return chksum;
-+}
-+
-+u16 calc_checksum_2byte(void *data, s32 len, u16 chksum, s32 type)
-+{
-+	int i;
-+	u8 *c = (u8 *)data;
-+
-+	switch (type) {
-+	case CS_DIR_ENTRY:
-+		for (i = 0; i < len; i++, c++) {
-+			if ((i == 2) || (i == 3))
-+				continue;
-+			chksum = (((chksum & 1) << 15) |
-+				  ((chksum & 0xFFFE) >> 1)) + (u16)*c;
-+		}
-+		break;
-+	default
-+			:
-+		for (i = 0; i < len; i++, c++)
-+			chksum = (((chksum & 1) << 15) |
-+				  ((chksum & 0xFFFE) >> 1)) + (u16)*c;
-+	}
-+
-+	return chksum;
-+}
-+
-+u32 calc_checksum_4byte(void *data, s32 len, u32 chksum, s32 type)
-+{
-+	int i;
-+	u8 *c = (u8 *)data;
-+
-+	switch (type) {
-+	case CS_PBR_SECTOR:
-+		for (i = 0; i < len; i++, c++) {
-+			if ((i == 106) || (i == 107) || (i == 112))
-+				continue;
-+			chksum = (((chksum & 1) << 31) |
-+				  ((chksum & 0xFFFFFFFE) >> 1)) + (u32)*c;
-+		}
-+		break;
-+	default
-+			:
-+		for (i = 0; i < len; i++, c++)
-+			chksum = (((chksum & 1) << 31) |
-+				  ((chksum & 0xFFFFFFFE) >> 1)) + (u32)*c;
-+	}
-+
-+	return chksum;
-+}
-+
-+/*
-+ *  Name Resolution Functions
-+ */
-+
-+/* return values of resolve_path()
-+ * > 0 : return the length of the path
-+ * < 0 : return error
-+ */
-+s32 resolve_path(struct inode *inode, char *path, struct chain_t *p_dir,
-+		 struct uni_name_t *p_uniname)
-+{
-+	bool lossy = false;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+
-+	if (strlen(path) >= (MAX_NAME_LENGTH * MAX_CHARSET_SIZE))
-+		return FFS_INVALIDPATH;
-+
-+	strcpy(name_buf, path);
-+
-+	nls_cstring_to_uniname(sb, p_uniname, name_buf, &lossy);
-+	if (lossy)
-+		return FFS_INVALIDPATH;
-+
-+	fid->size = i_size_read(inode);
-+
-+	p_dir->dir = fid->start_clu;
-+	p_dir->size = (s32)(fid->size >> p_fs->cluster_size_bits);
-+	p_dir->flags = fid->flags;
-+
-+	return FFS_SUCCESS;
-+}
-+
-+/*
-+ *  File Operation Functions
-+ */
-+static struct fs_func fat_fs_func = {
-+	.alloc_cluster = fat_alloc_cluster,
-+	.free_cluster = fat_free_cluster,
-+	.count_used_clusters = fat_count_used_clusters,
-+
-+	.init_dir_entry = fat_init_dir_entry,
-+	.init_ext_entry = fat_init_ext_entry,
-+	.find_dir_entry = fat_find_dir_entry,
-+	.delete_dir_entry = fat_delete_dir_entry,
-+	.get_uni_name_from_ext_entry = fat_get_uni_name_from_ext_entry,
-+	.count_ext_entries = fat_count_ext_entries,
-+	.calc_num_entries = fat_calc_num_entries,
-+
-+	.get_entry_type = fat_get_entry_type,
-+	.set_entry_type = fat_set_entry_type,
-+	.get_entry_attr = fat_get_entry_attr,
-+	.set_entry_attr = fat_set_entry_attr,
-+	.get_entry_flag = fat_get_entry_flag,
-+	.set_entry_flag = fat_set_entry_flag,
-+	.get_entry_clu0 = fat_get_entry_clu0,
-+	.set_entry_clu0 = fat_set_entry_clu0,
-+	.get_entry_size = fat_get_entry_size,
-+	.set_entry_size = fat_set_entry_size,
-+	.get_entry_time = fat_get_entry_time,
-+	.set_entry_time = fat_set_entry_time,
-+};
-+
-+s32 fat16_mount(struct super_block *sb, struct pbr_sector_t *p_pbr)
-+{
-+	s32 num_reserved, num_root_sectors;
-+	struct bpb16_t *p_bpb = (struct bpb16_t *)p_pbr->bpb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	if (p_bpb->num_fats == 0)
-+		return FFS_FORMATERR;
-+
-+	num_root_sectors = GET16(p_bpb->num_root_entries) << DENTRY_SIZE_BITS;
-+	num_root_sectors = ((num_root_sectors - 1) >>
-+			    p_bd->sector_size_bits) + 1;
-+
-+	p_fs->sectors_per_clu = p_bpb->sectors_per_clu;
-+	p_fs->sectors_per_clu_bits = ilog2(p_bpb->sectors_per_clu);
-+	p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits +
-+				  p_bd->sector_size_bits;
-+	p_fs->cluster_size = 1 << p_fs->cluster_size_bits;
-+
-+	p_fs->num_FAT_sectors = GET16(p_bpb->num_fat_sectors);
-+
-+	p_fs->FAT1_start_sector = p_fs->PBR_sector + GET16(p_bpb->num_reserved);
-+	if (p_bpb->num_fats == 1)
-+		p_fs->FAT2_start_sector = p_fs->FAT1_start_sector;
-+	else
-+		p_fs->FAT2_start_sector = p_fs->FAT1_start_sector +
-+					  p_fs->num_FAT_sectors;
-+
-+	p_fs->root_start_sector = p_fs->FAT2_start_sector +
-+				  p_fs->num_FAT_sectors;
-+	p_fs->data_start_sector = p_fs->root_start_sector + num_root_sectors;
-+
-+	p_fs->num_sectors = GET16(p_bpb->num_sectors);
-+	if (p_fs->num_sectors == 0)
-+		p_fs->num_sectors = GET32(p_bpb->num_huge_sectors);
-+
-+	num_reserved = p_fs->data_start_sector - p_fs->PBR_sector;
-+	p_fs->num_clusters = ((p_fs->num_sectors - num_reserved) >>
-+			      p_fs->sectors_per_clu_bits) + 2;
-+	/* because the cluster index starts with 2 */
-+
-+	if (p_fs->num_clusters < FAT12_THRESHOLD)
-+		p_fs->vol_type = FAT12;
-+	else
-+		p_fs->vol_type = FAT16;
-+	p_fs->vol_id = GET32(p_bpb->vol_serial);
-+
-+	p_fs->root_dir = 0;
-+	p_fs->dentries_in_root = GET16(p_bpb->num_root_entries);
-+	p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits -
-+				       DENTRY_SIZE_BITS);
-+
-+	p_fs->vol_flag = VOL_CLEAN;
-+	p_fs->clu_srch_ptr = 2;
-+	p_fs->used_clusters = (u32)~0;
-+
-+	p_fs->fs_func = &fat_fs_func;
-+
-+	return FFS_SUCCESS;
-+}
-+
-+s32 fat32_mount(struct super_block *sb, struct pbr_sector_t *p_pbr)
-+{
-+	s32 num_reserved;
-+	struct bpb32_t *p_bpb = (struct bpb32_t *)p_pbr->bpb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	if (p_bpb->num_fats == 0)
-+		return FFS_FORMATERR;
-+
-+	p_fs->sectors_per_clu = p_bpb->sectors_per_clu;
-+	p_fs->sectors_per_clu_bits = ilog2(p_bpb->sectors_per_clu);
-+	p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits +
-+				  p_bd->sector_size_bits;
-+	p_fs->cluster_size = 1 << p_fs->cluster_size_bits;
-+
-+	p_fs->num_FAT_sectors = GET32(p_bpb->num_fat32_sectors);
-+
-+	p_fs->FAT1_start_sector = p_fs->PBR_sector + GET16(p_bpb->num_reserved);
-+	if (p_bpb->num_fats == 1)
-+		p_fs->FAT2_start_sector = p_fs->FAT1_start_sector;
-+	else
-+		p_fs->FAT2_start_sector = p_fs->FAT1_start_sector +
-+					  p_fs->num_FAT_sectors;
-+
-+	p_fs->root_start_sector = p_fs->FAT2_start_sector +
-+				  p_fs->num_FAT_sectors;
-+	p_fs->data_start_sector = p_fs->root_start_sector;
-+
-+	p_fs->num_sectors = GET32(p_bpb->num_huge_sectors);
-+	num_reserved = p_fs->data_start_sector - p_fs->PBR_sector;
-+
-+	p_fs->num_clusters = ((p_fs->num_sectors - num_reserved) >>
-+			      p_fs->sectors_per_clu_bits) + 2;
-+	/* because the cluster index starts with 2 */
-+
-+	p_fs->vol_type = FAT32;
-+	p_fs->vol_id = GET32(p_bpb->vol_serial);
-+
-+	p_fs->root_dir = GET32(p_bpb->root_cluster);
-+	p_fs->dentries_in_root = 0;
-+	p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits -
-+				       DENTRY_SIZE_BITS);
-+
-+	p_fs->vol_flag = VOL_CLEAN;
-+	p_fs->clu_srch_ptr = 2;
-+	p_fs->used_clusters = (u32)~0;
-+
-+	p_fs->fs_func = &fat_fs_func;
-+
-+	return FFS_SUCCESS;
-+}
-+
-+static struct fs_func exfat_fs_func = {
-+	.alloc_cluster = exfat_alloc_cluster,
-+	.free_cluster = exfat_free_cluster,
-+	.count_used_clusters = exfat_count_used_clusters,
-+
-+	.init_dir_entry = exfat_init_dir_entry,
-+	.init_ext_entry = exfat_init_ext_entry,
-+	.find_dir_entry = exfat_find_dir_entry,
-+	.delete_dir_entry = exfat_delete_dir_entry,
-+	.get_uni_name_from_ext_entry = exfat_get_uni_name_from_ext_entry,
-+	.count_ext_entries = exfat_count_ext_entries,
-+	.calc_num_entries = exfat_calc_num_entries,
-+
-+	.get_entry_type = exfat_get_entry_type,
-+	.set_entry_type = exfat_set_entry_type,
-+	.get_entry_attr = exfat_get_entry_attr,
-+	.set_entry_attr = exfat_set_entry_attr,
-+	.get_entry_flag = exfat_get_entry_flag,
-+	.set_entry_flag = exfat_set_entry_flag,
-+	.get_entry_clu0 = exfat_get_entry_clu0,
-+	.set_entry_clu0 = exfat_set_entry_clu0,
-+	.get_entry_size = exfat_get_entry_size,
-+	.set_entry_size = exfat_set_entry_size,
-+	.get_entry_time = exfat_get_entry_time,
-+	.set_entry_time = exfat_set_entry_time,
-+};
-+
-+s32 exfat_mount(struct super_block *sb, struct pbr_sector_t *p_pbr)
-+{
-+	struct bpbex_t *p_bpb = (struct bpbex_t *)p_pbr->bpb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	if (p_bpb->num_fats == 0)
-+		return FFS_FORMATERR;
-+
-+	p_fs->sectors_per_clu = 1 << p_bpb->sectors_per_clu_bits;
-+	p_fs->sectors_per_clu_bits = p_bpb->sectors_per_clu_bits;
-+	p_fs->cluster_size_bits = p_fs->sectors_per_clu_bits +
-+				  p_bd->sector_size_bits;
-+	p_fs->cluster_size = 1 << p_fs->cluster_size_bits;
-+
-+	p_fs->num_FAT_sectors = GET32(p_bpb->fat_length);
-+
-+	p_fs->FAT1_start_sector = p_fs->PBR_sector + GET32(p_bpb->fat_offset);
-+	if (p_bpb->num_fats == 1)
-+		p_fs->FAT2_start_sector = p_fs->FAT1_start_sector;
-+	else
-+		p_fs->FAT2_start_sector = p_fs->FAT1_start_sector +
-+					  p_fs->num_FAT_sectors;
-+
-+	p_fs->root_start_sector = p_fs->PBR_sector + GET32(p_bpb->clu_offset);
-+	p_fs->data_start_sector = p_fs->root_start_sector;
-+
-+	p_fs->num_sectors = GET64(p_bpb->vol_length);
-+	p_fs->num_clusters = GET32(p_bpb->clu_count) + 2;
-+	/* because the cluster index starts with 2 */
-+
-+	p_fs->vol_type = EXFAT;
-+	p_fs->vol_id = GET32(p_bpb->vol_serial);
-+
-+	p_fs->root_dir = GET32(p_bpb->root_cluster);
-+	p_fs->dentries_in_root = 0;
-+	p_fs->dentries_per_clu = 1 << (p_fs->cluster_size_bits -
-+				       DENTRY_SIZE_BITS);
-+
-+	p_fs->vol_flag = (u32)GET16(p_bpb->vol_flags);
-+	p_fs->clu_srch_ptr = 2;
-+	p_fs->used_clusters = (u32)~0;
-+
-+	p_fs->fs_func = &exfat_fs_func;
-+
-+	return FFS_SUCCESS;
-+}
-+
-+s32 create_dir(struct inode *inode, struct chain_t *p_dir,
-+	       struct uni_name_t *p_uniname, struct file_id_t *fid)
-+{
-+	s32 ret, dentry, num_entries;
-+	u64 size;
-+	struct chain_t clu;
-+	struct dos_name_t dos_name, dot_name;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct fs_func *fs_func = p_fs->fs_func;
-+
-+	ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_entries,
-+					   &dos_name);
-+	if (ret)
-+		return ret;
-+
-+	/* find_empty_entry must be called before alloc_cluster */
-+	dentry = find_empty_entry(inode, p_dir, num_entries);
-+	if (dentry < 0)
-+		return FFS_FULL;
-+
-+	clu.dir = CLUSTER_32(~0);
-+	clu.size = 0;
-+	clu.flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
-+
-+	/* (1) allocate a cluster */
-+	ret = fs_func->alloc_cluster(sb, 1, &clu);
-+	if (ret < 0)
-+		return FFS_MEDIAERR;
-+	else if (ret == 0)
-+		return FFS_FULL;
-+
-+	ret = clear_cluster(sb, clu.dir);
-+	if (ret != FFS_SUCCESS)
-+		return ret;
-+
-+	if (p_fs->vol_type == EXFAT) {
-+		size = p_fs->cluster_size;
-+	} else {
-+		size = 0;
-+
-+		/* initialize the . and .. entry
-+		 * Information for . points to itself
-+		 * Information for .. points to parent dir
-+		 */
-+
-+		dot_name.name_case = 0x0;
-+		memcpy(dot_name.name, DOS_CUR_DIR_NAME, DOS_NAME_LENGTH);
-+
-+		ret = fs_func->init_dir_entry(sb, &clu, 0, TYPE_DIR, clu.dir,
-+					      0);
-+		if (ret != FFS_SUCCESS)
-+			return ret;
-+
-+		ret = fs_func->init_ext_entry(sb, &clu, 0, 1, NULL, &dot_name);
-+		if (ret != FFS_SUCCESS)
-+			return ret;
-+
-+		memcpy(dot_name.name, DOS_PAR_DIR_NAME, DOS_NAME_LENGTH);
-+
-+		if (p_dir->dir == p_fs->root_dir)
-+			ret = fs_func->init_dir_entry(sb, &clu, 1, TYPE_DIR,
-+						      CLUSTER_32(0), 0);
-+		else
-+			ret = fs_func->init_dir_entry(sb, &clu, 1, TYPE_DIR,
-+						      p_dir->dir, 0);
-+
-+		if (ret != FFS_SUCCESS)
-+			return ret;
-+
-+		ret = p_fs->fs_func->init_ext_entry(sb, &clu, 1, 1, NULL,
-+						    &dot_name);
-+		if (ret != FFS_SUCCESS)
-+			return ret;
-+	}
-+
-+	/* (2) update the directory entry */
-+	/* make sub-dir entry in parent directory */
-+	ret = fs_func->init_dir_entry(sb, p_dir, dentry, TYPE_DIR, clu.dir,
-+				      size);
-+	if (ret != FFS_SUCCESS)
-+		return ret;
-+
-+	ret = fs_func->init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname,
-+				      &dos_name);
-+	if (ret != FFS_SUCCESS)
-+		return ret;
-+
-+	fid->dir.dir = p_dir->dir;
-+	fid->dir.size = p_dir->size;
-+	fid->dir.flags = p_dir->flags;
-+	fid->entry = dentry;
-+
-+	fid->attr = ATTR_SUBDIR;
-+	fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
-+	fid->size = size;
-+	fid->start_clu = clu.dir;
-+
-+	fid->type = TYPE_DIR;
-+	fid->rwoffset = 0;
-+	fid->hint_last_off = -1;
-+
-+	return FFS_SUCCESS;
-+}
-+
-+s32 create_file(struct inode *inode, struct chain_t *p_dir,
-+		struct uni_name_t *p_uniname, u8 mode, struct file_id_t *fid)
-+{
-+	s32 ret, dentry, num_entries;
-+	struct dos_name_t dos_name;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct fs_func *fs_func = p_fs->fs_func;
-+
-+	ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname, &num_entries,
-+					   &dos_name);
-+	if (ret)
-+		return ret;
-+
-+	/* find_empty_entry must be called before alloc_cluster() */
-+	dentry = find_empty_entry(inode, p_dir, num_entries);
-+	if (dentry < 0)
-+		return FFS_FULL;
-+
-+	/* (1) update the directory entry */
-+	/* fill the dos name directory entry information of the created file.
-+	 * the first cluster is not determined yet. (0)
-+	 */
-+	ret = fs_func->init_dir_entry(sb, p_dir, dentry, TYPE_FILE | mode,
-+				      CLUSTER_32(0), 0);
-+	if (ret != FFS_SUCCESS)
-+		return ret;
-+
-+	ret = fs_func->init_ext_entry(sb, p_dir, dentry, num_entries, p_uniname,
-+				      &dos_name);
-+	if (ret != FFS_SUCCESS)
-+		return ret;
-+
-+	fid->dir.dir = p_dir->dir;
-+	fid->dir.size = p_dir->size;
-+	fid->dir.flags = p_dir->flags;
-+	fid->entry = dentry;
-+
-+	fid->attr = ATTR_ARCHIVE | mode;
-+	fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
-+	fid->size = 0;
-+	fid->start_clu = CLUSTER_32(~0);
-+
-+	fid->type = TYPE_FILE;
-+	fid->rwoffset = 0;
-+	fid->hint_last_off = -1;
-+
-+	return FFS_SUCCESS;
-+}
-+
-+void remove_file(struct inode *inode, struct chain_t *p_dir, s32 entry)
-+{
-+	s32 num_entries;
-+	sector_t sector;
-+	struct dentry_t *ep;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct fs_func *fs_func = p_fs->fs_func;
-+
-+	ep = get_entry_in_dir(sb, p_dir, entry, &sector);
-+	if (!ep)
-+		return;
-+
-+	buf_lock(sb, sector);
-+
-+	/* buf_lock() before call count_ext_entries() */
-+	num_entries = fs_func->count_ext_entries(sb, p_dir, entry, ep);
-+	if (num_entries < 0) {
-+		buf_unlock(sb, sector);
-+		return;
-+	}
-+	num_entries++;
-+
-+	buf_unlock(sb, sector);
-+
-+	/* (1) update the directory entry */
-+	fs_func->delete_dir_entry(sb, p_dir, entry, 0, num_entries);
-+}
-+
-+s32 rename_file(struct inode *inode, struct chain_t *p_dir, s32 oldentry,
-+		struct uni_name_t *p_uniname, struct file_id_t *fid)
-+{
-+	s32 ret, newentry = -1, num_old_entries, num_new_entries;
-+	sector_t sector_old, sector_new;
-+	struct dos_name_t dos_name;
-+	struct dentry_t *epold, *epnew;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct fs_func *fs_func = p_fs->fs_func;
-+
-+	epold = get_entry_in_dir(sb, p_dir, oldentry, &sector_old);
-+	if (!epold)
-+		return FFS_MEDIAERR;
-+
-+	buf_lock(sb, sector_old);
-+
-+	/* buf_lock() before call count_ext_entries() */
-+	num_old_entries = fs_func->count_ext_entries(sb, p_dir, oldentry,
-+						     epold);
-+	if (num_old_entries < 0) {
-+		buf_unlock(sb, sector_old);
-+		return FFS_MEDIAERR;
-+	}
-+	num_old_entries++;
-+
-+	ret = get_num_entries_and_dos_name(sb, p_dir, p_uniname,
-+					   &num_new_entries, &dos_name);
-+	if (ret) {
-+		buf_unlock(sb, sector_old);
-+		return ret;
-+	}
-+
-+	if (num_old_entries < num_new_entries) {
-+		newentry = find_empty_entry(inode, p_dir, num_new_entries);
-+		if (newentry < 0) {
-+			buf_unlock(sb, sector_old);
-+			return FFS_FULL;
-+		}
-+
-+		epnew = get_entry_in_dir(sb, p_dir, newentry, &sector_new);
-+		if (!epnew) {
-+			buf_unlock(sb, sector_old);
-+			return FFS_MEDIAERR;
-+		}
-+
-+		memcpy((void *)epnew, (void *)epold, DENTRY_SIZE);
-+		if (fs_func->get_entry_type(epnew) == TYPE_FILE) {
-+			fs_func->set_entry_attr(epnew,
-+						fs_func->get_entry_attr(epnew) |
-+						ATTR_ARCHIVE);
-+			fid->attr |= ATTR_ARCHIVE;
-+		}
-+		buf_modify(sb, sector_new);
-+		buf_unlock(sb, sector_old);
-+
-+		if (p_fs->vol_type == EXFAT) {
-+			epold = get_entry_in_dir(sb, p_dir, oldentry + 1,
-+						 &sector_old);
-+			buf_lock(sb, sector_old);
-+			epnew = get_entry_in_dir(sb, p_dir, newentry + 1,
-+						 &sector_new);
-+
-+			if (!epold || !epnew) {
-+				buf_unlock(sb, sector_old);
-+				return FFS_MEDIAERR;
-+			}
-+
-+			memcpy((void *)epnew, (void *)epold, DENTRY_SIZE);
-+			buf_modify(sb, sector_new);
-+			buf_unlock(sb, sector_old);
-+		}
-+
-+		ret = fs_func->init_ext_entry(sb, p_dir, newentry,
-+					      num_new_entries, p_uniname,
-+					      &dos_name);
-+		if (ret != FFS_SUCCESS)
-+			return ret;
-+
-+		fs_func->delete_dir_entry(sb, p_dir, oldentry, 0,
-+					  num_old_entries);
-+		fid->entry = newentry;
-+	} else {
-+		if (fs_func->get_entry_type(epold) == TYPE_FILE) {
-+			fs_func->set_entry_attr(epold,
-+						fs_func->get_entry_attr(epold) |
-+						ATTR_ARCHIVE);
-+			fid->attr |= ATTR_ARCHIVE;
-+		}
-+		buf_modify(sb, sector_old);
-+		buf_unlock(sb, sector_old);
-+
-+		ret = fs_func->init_ext_entry(sb, p_dir, oldentry,
-+					      num_new_entries, p_uniname,
-+					      &dos_name);
-+		if (ret != FFS_SUCCESS)
-+			return ret;
-+
-+		fs_func->delete_dir_entry(sb, p_dir, oldentry, num_new_entries,
-+					  num_old_entries);
-+	}
-+
-+	return FFS_SUCCESS;
-+}
-+
-+s32 move_file(struct inode *inode, struct chain_t *p_olddir, s32 oldentry,
-+	      struct chain_t *p_newdir, struct uni_name_t *p_uniname,
-+	      struct file_id_t *fid)
-+{
-+	s32 ret, newentry, num_new_entries, num_old_entries;
-+	sector_t sector_mov, sector_new;
-+	struct chain_t clu;
-+	struct dos_name_t dos_name;
-+	struct dentry_t *epmov, *epnew;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct fs_func *fs_func = p_fs->fs_func;
-+
-+	epmov = get_entry_in_dir(sb, p_olddir, oldentry, &sector_mov);
-+	if (!epmov)
-+		return FFS_MEDIAERR;
-+
-+	/* check if the source and target directory is the same */
-+	if (fs_func->get_entry_type(epmov) == TYPE_DIR &&
-+	    fs_func->get_entry_clu0(epmov) == p_newdir->dir)
-+		return FFS_INVALIDPATH;
-+
-+	buf_lock(sb, sector_mov);
-+
-+	/* buf_lock() before call count_ext_entries() */
-+	num_old_entries = fs_func->count_ext_entries(sb, p_olddir, oldentry,
-+						     epmov);
-+	if (num_old_entries < 0) {
-+		buf_unlock(sb, sector_mov);
-+		return FFS_MEDIAERR;
-+	}
-+	num_old_entries++;
-+
-+	ret = get_num_entries_and_dos_name(sb, p_newdir, p_uniname,
-+					   &num_new_entries, &dos_name);
-+	if (ret) {
-+		buf_unlock(sb, sector_mov);
-+		return ret;
-+	}
-+
-+	newentry = find_empty_entry(inode, p_newdir, num_new_entries);
-+	if (newentry < 0) {
-+		buf_unlock(sb, sector_mov);
-+		return FFS_FULL;
-+	}
-+
-+	epnew = get_entry_in_dir(sb, p_newdir, newentry, &sector_new);
-+	if (!epnew) {
-+		buf_unlock(sb, sector_mov);
-+		return FFS_MEDIAERR;
-+	}
-+
-+	memcpy((void *)epnew, (void *)epmov, DENTRY_SIZE);
-+	if (fs_func->get_entry_type(epnew) == TYPE_FILE) {
-+		fs_func->set_entry_attr(epnew, fs_func->get_entry_attr(epnew) |
-+					ATTR_ARCHIVE);
-+		fid->attr |= ATTR_ARCHIVE;
-+	}
-+	buf_modify(sb, sector_new);
-+	buf_unlock(sb, sector_mov);
-+
-+	if (p_fs->vol_type == EXFAT) {
-+		epmov = get_entry_in_dir(sb, p_olddir, oldentry + 1,
-+					 &sector_mov);
-+		buf_lock(sb, sector_mov);
-+		epnew = get_entry_in_dir(sb, p_newdir, newentry + 1,
-+					 &sector_new);
-+		if (!epmov || !epnew) {
-+			buf_unlock(sb, sector_mov);
-+			return FFS_MEDIAERR;
-+		}
-+
-+		memcpy((void *)epnew, (void *)epmov, DENTRY_SIZE);
-+		buf_modify(sb, sector_new);
-+		buf_unlock(sb, sector_mov);
-+	} else if (fs_func->get_entry_type(epnew) == TYPE_DIR) {
-+		/* change ".." pointer to new parent dir */
-+		clu.dir = fs_func->get_entry_clu0(epnew);
-+		clu.flags = 0x01;
-+
-+		epnew = get_entry_in_dir(sb, &clu, 1, &sector_new);
-+		if (!epnew)
-+			return FFS_MEDIAERR;
-+
-+		if (p_newdir->dir == p_fs->root_dir)
-+			fs_func->set_entry_clu0(epnew, CLUSTER_32(0));
-+		else
-+			fs_func->set_entry_clu0(epnew, p_newdir->dir);
-+		buf_modify(sb, sector_new);
-+	}
-+
-+	ret = fs_func->init_ext_entry(sb, p_newdir, newentry, num_new_entries,
-+				      p_uniname, &dos_name);
-+	if (ret != FFS_SUCCESS)
-+		return ret;
-+
-+	fs_func->delete_dir_entry(sb, p_olddir, oldentry, 0, num_old_entries);
-+
-+	fid->dir.dir = p_newdir->dir;
-+	fid->dir.size = p_newdir->size;
-+	fid->dir.flags = p_newdir->flags;
-+
-+	fid->entry = newentry;
-+
-+	return FFS_SUCCESS;
-+}
-+
-+/*
-+ *  Sector Read/Write Functions
-+ */
-+
-+int sector_read(struct super_block *sb, sector_t sec, struct buffer_head **bh,
-+		bool read)
-+{
-+	s32 ret = FFS_MEDIAERR;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if ((sec >= (p_fs->PBR_sector + p_fs->num_sectors)) &&
-+	    (p_fs->num_sectors > 0)) {
-+		pr_err("[EXFAT] %s: out of range error! (sec = %llu)\n",
-+		       __func__, (unsigned long long)sec);
-+		fs_error(sb);
-+		return ret;
-+	}
-+
-+	if (!p_fs->dev_ejected) {
-+		ret = bdev_read(sb, sec, bh, 1, read);
-+		if (ret != FFS_SUCCESS)
-+			p_fs->dev_ejected = TRUE;
-+	}
-+
-+	return ret;
-+}
-+
-+int sector_write(struct super_block *sb, sector_t sec, struct buffer_head *bh,
-+		 bool sync)
-+{
-+	s32 ret = FFS_MEDIAERR;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (sec >= (p_fs->PBR_sector + p_fs->num_sectors) &&
-+	    (p_fs->num_sectors > 0)) {
-+		pr_err("[EXFAT] %s: out of range error! (sec = %llu)\n",
-+		       __func__, (unsigned long long)sec);
-+		fs_error(sb);
-+		return ret;
-+	}
-+
-+	if (!bh) {
-+		pr_err("[EXFAT] %s: bh is NULL!\n", __func__);
-+		fs_error(sb);
-+		return ret;
-+	}
-+
-+	if (!p_fs->dev_ejected) {
-+		ret = bdev_write(sb, sec, bh, 1, sync);
-+		if (ret != FFS_SUCCESS)
-+			p_fs->dev_ejected = TRUE;
-+	}
-+
-+	return ret;
-+}
-+
-+int multi_sector_read(struct super_block *sb, sector_t sec,
-+		      struct buffer_head **bh, s32 num_secs, bool read)
-+{
-+	s32 ret = FFS_MEDIAERR;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (((sec + num_secs) > (p_fs->PBR_sector + p_fs->num_sectors)) &&
-+	    (p_fs->num_sectors > 0)) {
-+		pr_err("[EXFAT] %s: out of range error! (sec = %llu, num_secs = %d)\n",
-+		       __func__, (unsigned long long)sec, num_secs);
-+		fs_error(sb);
-+		return ret;
-+	}
-+
-+	if (!p_fs->dev_ejected) {
-+		ret = bdev_read(sb, sec, bh, num_secs, read);
-+		if (ret != FFS_SUCCESS)
-+			p_fs->dev_ejected = TRUE;
-+	}
-+
-+	return ret;
-+}
-+
-+int multi_sector_write(struct super_block *sb, sector_t sec,
-+		       struct buffer_head *bh, s32 num_secs, bool sync)
-+{
-+	s32 ret = FFS_MEDIAERR;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if ((sec + num_secs) > (p_fs->PBR_sector + p_fs->num_sectors) &&
-+	    (p_fs->num_sectors > 0)) {
-+		pr_err("[EXFAT] %s: out of range error! (sec = %llu, num_secs = %d)\n",
-+		       __func__, (unsigned long long)sec, num_secs);
-+		fs_error(sb);
-+		return ret;
-+	}
-+	if (!bh) {
-+		pr_err("[EXFAT] %s: bh is NULL!\n", __func__);
-+		fs_error(sb);
-+		return ret;
-+	}
-+
-+	if (!p_fs->dev_ejected) {
-+		ret = bdev_write(sb, sec, bh, num_secs, sync);
-+		if (ret != FFS_SUCCESS)
-+			p_fs->dev_ejected = TRUE;
-+	}
-+
-+	return ret;
-+}
-diff --git a/drivers/staging/exfat/exfat_nls.c b/drivers/staging/exfat/exfat_nls.c
-new file mode 100644
-index 000000000000..2ca58616159b
---- /dev/null
-+++ b/drivers/staging/exfat/exfat_nls.c
-@@ -0,0 +1,404 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
-+ */
-+
-+#include <linux/string.h>
-+#include <linux/nls.h>
-+#include "exfat.h"
-+
-+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
-+};
-+
-+static int convert_ch_to_uni(struct nls_table *nls, u16 *uni, u8 *ch,
-+			     bool *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 */
-+		pr_info("%s: fail to use nls\n", __func__);
-+		if (lossy)
-+			*lossy = true;
-+		*uni = (u16)'_';
-+		if (!strcmp(nls->charset, "utf8"))
-+			return 1;
-+		else
-+			return 2;
-+	}
-+
-+	return len;
-+}
-+
-+static int convert_uni_to_ch(struct nls_table *nls, u8 *ch, u16 uni,
-+			     bool *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 */
-+		pr_info("%s: fail to use nls\n", __func__);
-+		if (lossy)
-+			*lossy = true;
-+		ch[0] = '_';
-+		return 1;
-+	}
-+
-+	return len;
-+}
-+
-+u16 nls_upper(struct super_block *sb, u16 a)
-+{
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	if (EXFAT_SB(sb)->options.casesensitive)
-+		return a;
-+	if (p_fs->vol_utbl && p_fs->vol_utbl[get_col_index(a)])
-+		return p_fs->vol_utbl[get_col_index(a)][get_row_index(a)];
-+	else
-+		return a;
-+}
-+
-+static u16 *nls_wstrchr(u16 *str, u16 wchar)
-+{
-+	while (*str) {
-+		if (*(str++) == wchar)
-+			return str;
-+	}
-+
-+	return NULL;
-+}
-+
-+int nls_dosname_cmp(struct super_block *sb, u8 *a, u8 *b)
-+{
-+	return strncmp(a, b, DOS_NAME_LENGTH);
-+}
-+
-+int 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;
-+}
-+
-+void nls_uniname_to_dosname(struct super_block *sb,
-+			    struct dos_name_t *p_dosname,
-+			    struct uni_name_t *p_uniname, bool *p_lossy)
-+{
-+	int i, j, len;
-+	bool 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)
-+			*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)
-+			*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)
-+				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)
-+		*p_lossy = lossy;
-+}
-+
-+void nls_dosname_to_uniname(struct super_block *sb,
-+			    struct uni_name_t *p_uniname,
-+			    struct 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 = 0;
-+	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';
-+}
-+
-+void nls_uniname_to_cstring(struct super_block *sb, u8 *p_cstring,
-+			    struct 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) {
-+		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';
-+}
-+
-+void nls_cstring_to_uniname(struct super_block *sb,
-+			    struct uni_name_t *p_uniname, u8 *p_cstring,
-+			    bool *p_lossy)
-+{
-+	int i, j;
-+	bool 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(p_cstring);
-+
-+	while (*(--end_of_name) == ' ') {
-+		if (end_of_name < p_cstring)
-+			break;
-+	}
-+	*(++end_of_name) = '\0';
-+
-+	if (strcmp(p_cstring, ".") && strcmp(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) {
-+		i = utf8s_to_utf16s(p_cstring, MAX_NAME_LENGTH,
-+				    UTF16_HOST_ENDIAN, uniname,
-+				    MAX_NAME_LENGTH);
-+		for (j = 0; j < i; j++)
-+			SET16_A(upname + j * 2, nls_upper(sb, uniname[j]));
-+		uniname[i] = '\0';
-+	} else {
-+		i = 0;
-+		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(upname, j << 1, 0,
-+						   CS_DEFAULT);
-+
-+	if (p_lossy)
-+		*p_lossy = lossy;
-+}
-diff --git a/drivers/staging/exfat/exfat_super.c b/drivers/staging/exfat/exfat_super.c
-new file mode 100644
-index 000000000000..5b5c2ca8c9aa
---- /dev/null
-+++ b/drivers/staging/exfat/exfat_super.c
-@@ -0,0 +1,4137 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
-+ */
-+
-+#include <linux/version.h>
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/time.h>
-+#include <linux/slab.h>
-+#include <linux/seq_file.h>
-+#include <linux/pagemap.h>
-+#include <linux/mpage.h>
-+#include <linux/buffer_head.h>
-+#include <linux/exportfs.h>
-+#include <linux/mount.h>
-+#include <linux/vfs.h>
-+#include <linux/aio.h>
-+#include <linux/iversion.h>
-+#include <linux/parser.h>
-+#include <linux/uio.h>
-+#include <linux/writeback.h>
-+#include <linux/log2.h>
-+#include <linux/hash.h>
-+#include <linux/backing-dev.h>
-+#include <linux/sched.h>
-+#include <linux/fs_struct.h>
-+#include <linux/namei.h>
-+#include <linux/time.h>
-+
-+#include <linux/string.h>
-+#include <linux/nls.h>
-+#include <linux/mutex.h>
-+#include <linux/swap.h>
-+
-+#define EXFAT_VERSION  "1.3.0"
-+
-+#include "exfat.h"
-+
-+static struct kmem_cache *exfat_inode_cachep;
-+
-+// FIXME use commented lines
-+// static int exfat_default_codepage = CONFIG_EXFAT_DEFAULT_CODEPAGE;
-+// static char exfat_default_iocharset[] = CONFIG_EXFAT_DEFAULT_IOCHARSET;
-+static int exfat_default_codepage = CONFIG_FAT_DEFAULT_CODEPAGE;
-+static char exfat_default_iocharset[] = CONFIG_FAT_DEFAULT_IOCHARSET;
-+
-+#define INC_IVERSION(x) (inode_inc_iversion(x))
-+#define GET_IVERSION(x) (inode_peek_iversion_raw(x))
-+#define SET_IVERSION(x, y) (inode_set_iversion(x, y))
-+
-+static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos);
-+static int exfat_sync_inode(struct inode *inode);
-+static struct inode *exfat_build_inode(struct super_block *sb,
-+				       struct file_id_t *fid, loff_t i_pos);
-+static int exfat_write_inode(struct inode *inode,
-+			     struct writeback_control *wbc);
-+static void exfat_write_super(struct super_block *sb);
-+
-+#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) & 0x3) && (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,
-+};
-+
-+/* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */
-+static void exfat_time_fat2unix(struct exfat_sb_info *sbi,
-+				struct timespec64 *ts, struct date_time_t *tp)
-+{
-+	time_t year = tp->Year;
-+	time_t ld;
-+
-+	MAKE_LEAP_YEAR(ld, year);
-+
-+	if (IS_LEAP_YEAR(year) && (tp->Month) > 2)
-+		ld++;
-+
-+	ts->tv_sec = tp->Second +
-+		     tp->Minute * SECS_PER_MIN +
-+		     tp->Hour * SECS_PER_HOUR +
-+		     (ld + accum_days_in_year[(tp->Month)] +
-+		      (tp->Day - 1)) * SECS_PER_DAY +
-+		     (year * 365 + DAYS_DELTA_DECADE) * SECS_PER_DAY +
-+		     sys_tz.tz_minuteswest * SECS_PER_MIN;
-+
-+	ts->tv_nsec = 0;
-+}
-+
-+/* Convert linear UNIX date to a FAT time/date pair. */
-+static void exfat_time_unix2fat(struct exfat_sb_info *sbi,
-+				struct timespec64 *ts, struct date_time_t *tp)
-+{
-+	time_t second = ts->tv_sec;
-+	time_t day, month, year;
-+	time_t ld;
-+
-+	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->Second  = 0;
-+		tp->Minute  = 0;
-+		tp->Hour = 0;
-+		tp->Day  = 1;
-+		tp->Month  = 1;
-+		tp->Year = 0;
-+		return;
-+	}
-+#if (BITS_PER_LONG == 64)
-+	if (second >= UNIX_SECS_2108) {
-+		tp->Second  = 59;
-+		tp->Minute  = 59;
-+		tp->Hour = 23;
-+		tp->Day  = 31;
-+		tp->Month  = 12;
-+		tp->Year = 127;
-+		return;
-+	}
-+#endif
-+	day = second / SECS_PER_DAY - DAYS_DELTA_DECADE;
-+	year = day / 365;
-+	MAKE_LEAP_YEAR(ld, year);
-+	if (year * 365 + ld > day)
-+		year--;
-+
-+	MAKE_LEAP_YEAR(ld, year);
-+	day -= year * 365 + ld;
-+
-+	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->Second  = second % SECS_PER_MIN;
-+	tp->Minute  = (second / SECS_PER_MIN) % 60;
-+	tp->Hour = (second / SECS_PER_HOUR) % 24;
-+	tp->Day  = day + 1;
-+	tp->Month  = month;
-+	tp->Year = year;
-+}
-+
-+struct timestamp_t *tm_current(struct timestamp_t *tp)
-+{
-+	struct timespec64 ts;
-+	time_t second, day, leap_day, month, year;
-+
-+	ktime_get_real_ts64(&ts);
-+
-+	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;
-+}
-+
-+static void __lock_super(struct super_block *sb)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+
-+	mutex_lock(&sbi->s_lock);
-+}
-+
-+static void __unlock_super(struct super_block *sb)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+
-+	mutex_unlock(&sbi->s_lock);
-+}
-+
-+static int __is_sb_dirty(struct super_block *sb)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+
-+	return sbi->s_dirt;
-+}
-+
-+static void __set_sb_clean(struct super_block *sb)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+
-+	sbi->s_dirt = 0;
-+}
-+
-+static int __exfat_revalidate(struct dentry *dentry)
-+{
-+	return 0;
-+}
-+
-+static int exfat_revalidate(struct dentry *dentry, unsigned int flags)
-+{
-+	if (flags & LOOKUP_RCU)
-+		return -ECHILD;
-+
-+	if (dentry->d_inode)
-+		return 1;
-+	return __exfat_revalidate(dentry);
-+}
-+
-+static int exfat_revalidate_ci(struct dentry *dentry, unsigned int flags)
-+{
-+	if (flags & LOOKUP_RCU)
-+		return -ECHILD;
-+
-+	if (dentry->d_inode)
-+		return 1;
-+
-+	if (!flags)
-+		return 0;
-+
-+	if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
-+		return 0;
-+
-+	return __exfat_revalidate(dentry);
-+}
-+
-+static unsigned int __exfat_striptail_len(unsigned int len, const char *name)
-+{
-+	while (len && name[len - 1] == '.')
-+		len--;
-+	return len;
-+}
-+
-+static unsigned int exfat_striptail_len(const struct qstr *qstr)
-+{
-+	return __exfat_striptail_len(qstr->len, qstr->name);
-+}
-+
-+static int exfat_d_hash(const struct dentry *dentry, struct qstr *qstr)
-+{
-+	qstr->hash = full_name_hash(dentry, qstr->name,
-+				    exfat_striptail_len(qstr));
-+	return 0;
-+}
-+
-+static int exfat_d_hashi(const struct dentry *dentry, struct qstr *qstr)
-+{
-+	struct super_block *sb = dentry->d_sb;
-+	const unsigned char *name;
-+	unsigned int len;
-+	unsigned long hash;
-+
-+	name = qstr->name;
-+	len = exfat_striptail_len(qstr);
-+
-+	hash = init_name_hash(dentry);
-+	while (len--)
-+		hash = partial_name_hash(nls_upper(sb, *name++), hash);
-+	qstr->hash = end_name_hash(hash);
-+
-+	return 0;
-+}
-+
-+static int exfat_cmpi(const struct dentry *dentry, unsigned int len,
-+		      const char *str, const struct qstr *name)
-+{
-+	struct nls_table *t = EXFAT_SB(dentry->d_sb)->nls_io;
-+	unsigned int alen, blen;
-+
-+	alen = exfat_striptail_len(name);
-+	blen = __exfat_striptail_len(len, str);
-+	if (alen == blen) {
-+		if (t == NULL) {
-+			if (strncasecmp(name->name, str, alen) == 0)
-+				return 0;
-+		} else if (nls_strnicmp(t, name->name, str, alen) == 0)
-+			return 0;
-+	}
-+	return 1;
-+}
-+
-+static int exfat_cmp(const struct dentry *dentry, unsigned int len,
-+		     const char *str, const struct qstr *name)
-+{
-+	unsigned int alen, blen;
-+
-+	alen = exfat_striptail_len(name);
-+	blen = __exfat_striptail_len(len, str);
-+	if (alen == blen) {
-+		if (strncmp(name->name, str, alen) == 0)
-+			return 0;
-+	}
-+	return 1;
-+}
-+
-+static const struct dentry_operations exfat_ci_dentry_ops = {
-+	.d_revalidate   = exfat_revalidate_ci,
-+	.d_hash         = exfat_d_hashi,
-+	.d_compare      = exfat_cmpi,
-+};
-+
-+static const struct dentry_operations exfat_dentry_ops = {
-+	.d_revalidate   = exfat_revalidate,
-+	.d_hash         = exfat_d_hash,
-+	.d_compare      = exfat_cmp,
-+};
-+
-+static DEFINE_SEMAPHORE(z_sem);
-+
-+static inline void fs_sync(struct super_block *sb, bool do_sync)
-+{
-+	if (do_sync)
-+		bdev_sync(sb);
-+}
-+
-+/*
-+ * 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) & 0222)
-+		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 &= ~0222;
-+
-+	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 & 0222))
-+		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);
-+}
-+
-+static int ffsMountVol(struct super_block *sb)
-+{
-+	int i, ret;
-+	struct pbr_sector_t *p_pbr;
-+	struct buffer_head *tmp_bh = NULL;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+
-+	pr_info("[EXFAT] trying to mount...\n");
-+
-+	down(&z_sem);
-+
-+	buf_init(sb);
-+
-+	sema_init(&p_fs->v_sem, 1);
-+	p_fs->dev_ejected = FALSE;
-+
-+	/* open the block device */
-+	bdev_open(sb);
-+
-+	if (p_bd->sector_size < sb->s_blocksize) {
-+		ret = FFS_MEDIAERR;
-+		goto out;
-+	}
-+	if (p_bd->sector_size > sb->s_blocksize)
-+		sb_set_blocksize(sb, p_bd->sector_size);
-+
-+	/* read Sector 0 */
-+	if (sector_read(sb, 0, &tmp_bh, 1) != FFS_SUCCESS) {
-+		ret = FFS_MEDIAERR;
-+		goto out;
-+	}
-+
-+	p_fs->PBR_sector = 0;
-+
-+	p_pbr = (struct pbr_sector_t *) tmp_bh->b_data;
-+
-+	/* check the validity of PBR */
-+	if (GET16_A(p_pbr->signature) != PBR_SIGNATURE) {
-+		brelse(tmp_bh);
-+		bdev_close(sb);
-+		ret = FFS_FORMATERR;
-+		goto out;
-+	}
-+
-+	/* fill fs_stuct */
-+	for (i = 0; i < 53; i++)
-+		if (p_pbr->bpb[i])
-+			break;
-+
-+	if (i < 53) {
-+		if (GET16(p_pbr->bpb + 11)) /* num_fat_sectors */
-+			ret = fat16_mount(sb, p_pbr);
-+		else
-+			ret = fat32_mount(sb, p_pbr);
-+	} else {
-+		ret = exfat_mount(sb, p_pbr);
-+	}
-+
-+	brelse(tmp_bh);
-+
-+	if (ret) {
-+		bdev_close(sb);
-+		goto out;
-+	}
-+
-+	if (p_fs->vol_type == EXFAT) {
-+		ret = load_alloc_bitmap(sb);
-+		if (ret) {
-+			bdev_close(sb);
-+			goto out;
-+		}
-+		ret = load_upcase_table(sb);
-+		if (ret) {
-+			free_alloc_bitmap(sb);
-+			bdev_close(sb);
-+			goto out;
-+		}
-+	}
-+
-+	if (p_fs->dev_ejected) {
-+		if (p_fs->vol_type == EXFAT) {
-+			free_upcase_table(sb);
-+			free_alloc_bitmap(sb);
-+		}
-+		bdev_close(sb);
-+		ret = FFS_MEDIAERR;
-+		goto out;
-+	}
-+
-+	pr_info("[EXFAT] mounted successfully\n");
-+
-+out:
-+	up(&z_sem);
-+
-+	return ret;
-+}
-+
-+static int ffsUmountVol(struct super_block *sb)
-+{
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	int err = FFS_SUCCESS;
-+
-+	pr_info("[EXFAT] trying to unmount...\n");
-+
-+	down(&z_sem);
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+
-+	if (p_fs->vol_type == EXFAT) {
-+		free_upcase_table(sb);
-+		free_alloc_bitmap(sb);
-+	}
-+
-+	FAT_release_all(sb);
-+	buf_release_all(sb);
-+
-+	/* close the block device */
-+	bdev_close(sb);
-+
-+	if (p_fs->dev_ejected) {
-+		pr_info("[EXFAT] unmounted with media errors. Device is already ejected.\n");
-+		err = FFS_MEDIAERR;
-+	}
-+
-+	buf_shutdown(sb);
-+
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+	up(&z_sem);
-+
-+	pr_info("[EXFAT] unmounted successfully\n");
-+
-+	return err;
-+}
-+
-+static int ffsGetVolInfo(struct super_block *sb, struct vol_info_t *info)
-+{
-+	int err = FFS_SUCCESS;
-+	struct 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 */
-+	down(&p_fs->v_sem);
-+
-+	if (p_fs->used_clusters == (u32) ~0)
-+		p_fs->used_clusters = p_fs->fs_func->count_used_clusters(sb);
-+
-+	info->FatType = p_fs->vol_type;
-+	info->ClusterSize = p_fs->cluster_size;
-+	info->NumClusters = p_fs->num_clusters - 2; /* clu 0 & 1 */
-+	info->UsedClusters = p_fs->used_clusters;
-+	info->FreeClusters = info->NumClusters - info->UsedClusters;
-+
-+	if (p_fs->dev_ejected)
-+		err = FFS_MEDIAERR;
-+
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return err;
-+}
-+
-+static int ffsSyncVol(struct super_block *sb, bool do_sync)
-+{
-+	int err = FFS_SUCCESS;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	/* synchronize the file system */
-+	fs_sync(sb, do_sync);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+
-+	if (p_fs->dev_ejected)
-+		err = FFS_MEDIAERR;
-+
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return err;
-+}
-+
-+/*----------------------------------------------------------------------*/
-+/*  File Operation Functions                                            */
-+/*----------------------------------------------------------------------*/
-+
-+static int ffsLookupFile(struct inode *inode, char *path, struct file_id_t *fid)
-+{
-+	int ret, dentry, num_entries;
-+	struct chain_t dir;
-+	struct uni_name_t uni_name;
-+	struct dos_name_t dos_name;
-+	struct dentry_t *ep, *ep2;
-+	struct entry_set_cache_t *es = NULL;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	/* check the validity of pointer parameters */
-+	if ((fid == NULL) || (path == NULL) || (*path == '\0'))
-+		return FFS_ERROR;
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	/* check the validity of directory name in the given pathname */
-+	ret = resolve_path(inode, path, &dir, &uni_name);
-+	if (ret)
-+		goto out;
-+
-+	ret = get_num_entries_and_dos_name(sb, &dir, &uni_name, &num_entries,
-+					   &dos_name);
-+	if (ret)
-+		goto out;
-+
-+	/* search the file name for directories */
-+	dentry = p_fs->fs_func->find_dir_entry(sb, &dir, &uni_name, num_entries,
-+					       &dos_name, TYPE_ALL);
-+	if (dentry < -1) {
-+		return FFS_NOTFOUND;
-+		goto out;
-+	}
-+
-+	fid->dir.dir = dir.dir;
-+	fid->dir.size = dir.size;
-+	fid->dir.flags = dir.flags;
-+	fid->entry = dentry;
-+
-+	if (dentry == -1) {
-+		fid->type = TYPE_DIR;
-+		fid->rwoffset = 0;
-+		fid->hint_last_off = -1;
-+
-+		fid->attr = ATTR_SUBDIR;
-+		fid->flags = 0x01;
-+		fid->size = 0;
-+		fid->start_clu = p_fs->root_dir;
-+	} else {
-+		if (p_fs->vol_type == EXFAT) {
-+			es = get_entry_set_in_dir(sb, &dir, dentry,
-+						  ES_2_ENTRIES, &ep);
-+			if (!es) {
-+				ret =  FFS_MEDIAERR;
-+				goto out;
-+			}
-+			ep2 = ep+1;
-+		} else {
-+			ep = get_entry_in_dir(sb, &dir, dentry, NULL);
-+			if (!ep) {
-+				ret =  FFS_MEDIAERR;
-+				goto out;
-+			}
-+			ep2 = ep;
-+		}
-+
-+		fid->type = p_fs->fs_func->get_entry_type(ep);
-+		fid->rwoffset = 0;
-+		fid->hint_last_off = -1;
-+		fid->attr = p_fs->fs_func->get_entry_attr(ep);
-+
-+		fid->size = p_fs->fs_func->get_entry_size(ep2);
-+		if ((fid->type == TYPE_FILE) && (fid->size == 0)) {
-+			fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
-+			fid->start_clu = CLUSTER_32(~0);
-+		} else {
-+			fid->flags = p_fs->fs_func->get_entry_flag(ep2);
-+			fid->start_clu = p_fs->fs_func->get_entry_clu0(ep2);
-+		}
-+
-+		if (p_fs->vol_type == EXFAT)
-+			release_entry_set(es);
-+	}
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+static int ffsCreateFile(struct inode *inode, char *path, u8 mode,
-+			 struct file_id_t *fid)
-+{
-+	struct chain_t dir;
-+	struct uni_name_t uni_name;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	int ret;
-+
-+	/* check the validity of pointer parameters */
-+	if ((fid == NULL) || (path == NULL) || (*path == '\0'))
-+		return FFS_ERROR;
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	/* check the validity of directory name in the given pathname */
-+	ret = resolve_path(inode, path, &dir, &uni_name);
-+	if (ret)
-+		goto out;
-+
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	/* create a new file */
-+	ret = create_file(inode, &dir, &uni_name, mode, fid);
-+
-+#ifdef CONFIG_EXFAT_DELAYED_SYNC
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+#endif
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+static int ffsReadFile(struct inode *inode, struct file_id_t *fid, void *buffer,
-+		       u64 count, u64 *rcount)
-+{
-+	s32 offset, sec_offset, clu_offset;
-+	u32 clu;
-+	int ret;
-+	sector_t LogSector;
-+	u64 oneblkread, read_bytes;
-+	struct buffer_head *tmp_bh = NULL;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_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 */
-+	down(&p_fs->v_sem);
-+
-+	/* check if the given file ID is opened */
-+	if (fid->type != TYPE_FILE) {
-+		ret = FFS_PERMISSIONERR;
-+		goto out;
-+	}
-+
-+	if (fid->rwoffset > fid->size)
-+		fid->rwoffset = fid->size;
-+
-+	if (count > (fid->size - fid->rwoffset))
-+		count = fid->size - fid->rwoffset;
-+
-+	if (count == 0) {
-+		if (rcount != NULL)
-+			*rcount = 0;
-+		ret = FFS_EOF;
-+		goto out;
-+	}
-+
-+	read_bytes = 0;
-+
-+	while (count > 0) {
-+		clu_offset = (s32)(fid->rwoffset >> p_fs->cluster_size_bits);
-+		clu = fid->start_clu;
-+
-+		if (fid->flags == 0x03) {
-+			clu += clu_offset;
-+		} else {
-+			/* hint information */
-+			if ((clu_offset > 0) && (fid->hint_last_off > 0) &&
-+			    (clu_offset >= fid->hint_last_off)) {
-+				clu_offset -= fid->hint_last_off;
-+				clu = fid->hint_last_clu;
-+			}
-+
-+			while (clu_offset > 0) {
-+				/* clu = FAT_read(sb, clu); */
-+				if (FAT_read(sb, clu, &clu) == -1)
-+					return FFS_MEDIAERR;
-+
-+				clu_offset--;
-+			}
-+		}
-+
-+		/* hint information */
-+		fid->hint_last_off = (s32)(fid->rwoffset >>
-+					   p_fs->cluster_size_bits);
-+		fid->hint_last_clu = clu;
-+
-+		/* byte offset in cluster */
-+		offset = (s32)(fid->rwoffset & (p_fs->cluster_size-1));
-+
-+		/* sector offset in cluster */
-+		sec_offset = offset >> p_bd->sector_size_bits;
-+
-+		/* byte offset in sector */
-+		offset &= p_bd->sector_size_mask;
-+
-+		LogSector = START_SECTOR(clu) + sec_offset;
-+
-+		oneblkread = (u64)(p_bd->sector_size - offset);
-+		if (oneblkread > count)
-+			oneblkread = count;
-+
-+		if ((offset == 0) && (oneblkread == p_bd->sector_size)) {
-+			if (sector_read(sb, LogSector, &tmp_bh, 1) !=
-+			    FFS_SUCCESS)
-+				goto err_out;
-+			memcpy((char *)buffer + read_bytes,
-+			       (char *)tmp_bh->b_data, (s32)oneblkread);
-+		} else {
-+			if (sector_read(sb, LogSector, &tmp_bh, 1) !=
-+			    FFS_SUCCESS)
-+				goto err_out;
-+			memcpy((char *)buffer + read_bytes,
-+			       (char *)tmp_bh->b_data + offset,
-+			       (s32)oneblkread);
-+		}
-+		count -= oneblkread;
-+		read_bytes += oneblkread;
-+		fid->rwoffset += oneblkread;
-+	}
-+	brelse(tmp_bh);
-+
-+/* How did this ever work and not leak a brlse()?? */
-+err_out:
-+	/* set the size of read bytes */
-+	if (rcount != NULL)
-+		*rcount = read_bytes;
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+static int ffsWriteFile(struct inode *inode, struct file_id_t *fid,
-+			void *buffer, u64 count, u64 *wcount)
-+{
-+	s32 modified = FALSE, offset, sec_offset, clu_offset;
-+	s32 num_clusters, num_alloc, num_alloced = (s32) ~0;
-+	int ret = 0;
-+	u32 clu, last_clu;
-+	sector_t LogSector, sector = 0;
-+	u64 oneblkwrite, write_bytes;
-+	struct chain_t new_clu;
-+	struct timestamp_t tm;
-+	struct dentry_t *ep, *ep2;
-+	struct entry_set_cache_t *es = NULL;
-+	struct buffer_head *tmp_bh = NULL;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_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 */
-+	down(&p_fs->v_sem);
-+
-+	/* check if the given file ID is opened */
-+	if (fid->type != TYPE_FILE) {
-+		ret = FFS_PERMISSIONERR;
-+		goto out;
-+	}
-+
-+	if (fid->rwoffset > fid->size)
-+		fid->rwoffset = fid->size;
-+
-+	if (count == 0) {
-+		if (wcount != NULL)
-+			*wcount = 0;
-+		ret = FFS_SUCCESS;
-+		goto out;
-+	}
-+
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	if (fid->size == 0)
-+		num_clusters = 0;
-+	else
-+		num_clusters = (s32)((fid->size-1) >>
-+				     p_fs->cluster_size_bits) + 1;
-+
-+	write_bytes = 0;
-+
-+	while (count > 0) {
-+		clu_offset = (s32)(fid->rwoffset >> p_fs->cluster_size_bits);
-+		clu = last_clu = fid->start_clu;
-+
-+		if (fid->flags == 0x03) {
-+			if ((clu_offset > 0) && (clu != CLUSTER_32(~0))) {
-+				last_clu += clu_offset - 1;
-+
-+				if (clu_offset == num_clusters)
-+					clu = CLUSTER_32(~0);
-+				else
-+					clu += clu_offset;
-+			}
-+		} else {
-+			/* hint information */
-+			if ((clu_offset > 0) && (fid->hint_last_off > 0) &&
-+			    (clu_offset >= fid->hint_last_off)) {
-+				clu_offset -= fid->hint_last_off;
-+				clu = fid->hint_last_clu;
-+			}
-+
-+			while ((clu_offset > 0) && (clu != CLUSTER_32(~0))) {
-+				last_clu = clu;
-+				/* clu = FAT_read(sb, clu); */
-+				if (FAT_read(sb, clu, &clu) == -1) {
-+					ret = FFS_MEDIAERR;
-+					goto out;
-+				}
-+				clu_offset--;
-+			}
-+		}
-+
-+		if (clu == CLUSTER_32(~0)) {
-+			num_alloc = (s32)((count - 1) >>
-+					  p_fs->cluster_size_bits) + 1;
-+			new_clu.dir = (last_clu == CLUSTER_32(~0)) ?
-+					CLUSTER_32(~0) : last_clu+1;
-+			new_clu.size = 0;
-+			new_clu.flags = fid->flags;
-+
-+			/* (1) allocate a chain of clusters */
-+			num_alloced = p_fs->fs_func->alloc_cluster(sb,
-+								   num_alloc,
-+								   &new_clu);
-+			if (num_alloced == 0)
-+				break;
-+			else if (num_alloced < 0) {
-+				ret = FFS_MEDIAERR;
-+				goto out;
-+			}
-+
-+			/* (2) append to the FAT chain */
-+			if (last_clu == CLUSTER_32(~0)) {
-+				if (new_clu.flags == 0x01)
-+					fid->flags = 0x01;
-+				fid->start_clu = new_clu.dir;
-+				modified = TRUE;
-+			} else {
-+				if (new_clu.flags != fid->flags) {
-+					exfat_chain_cont_cluster(sb,
-+								 fid->start_clu,
-+								 num_clusters);
-+					fid->flags = 0x01;
-+					modified = TRUE;
-+				}
-+				if (new_clu.flags == 0x01)
-+					FAT_write(sb, last_clu, new_clu.dir);
-+			}
-+
-+			num_clusters += num_alloced;
-+			clu = new_clu.dir;
-+		}
-+
-+		/* hint information */
-+		fid->hint_last_off = (s32)(fid->rwoffset >>
-+					   p_fs->cluster_size_bits);
-+		fid->hint_last_clu = clu;
-+
-+		/* byte offset in cluster   */
-+		offset = (s32)(fid->rwoffset & (p_fs->cluster_size - 1));
-+
-+		/* sector offset in cluster */
-+		sec_offset = offset >> p_bd->sector_size_bits;
-+
-+		/* byte offset in sector    */
-+		offset &= p_bd->sector_size_mask;
-+
-+		LogSector = START_SECTOR(clu) + sec_offset;
-+
-+		oneblkwrite = (u64)(p_bd->sector_size - offset);
-+		if (oneblkwrite > count)
-+			oneblkwrite = count;
-+
-+		if ((offset == 0) && (oneblkwrite == p_bd->sector_size)) {
-+			if (sector_read(sb, LogSector, &tmp_bh, 0) !=
-+			    FFS_SUCCESS)
-+				goto err_out;
-+			memcpy((char *)tmp_bh->b_data,
-+			       (char *)buffer + write_bytes, (s32)oneblkwrite);
-+			if (sector_write(sb, LogSector, tmp_bh, 0) !=
-+			    FFS_SUCCESS) {
-+				brelse(tmp_bh);
-+				goto err_out;
-+			}
-+		} else {
-+			if ((offset > 0) ||
-+			    ((fid->rwoffset+oneblkwrite) < fid->size)) {
-+				if (sector_read(sb, LogSector, &tmp_bh, 1) !=
-+				    FFS_SUCCESS)
-+					goto err_out;
-+			} else {
-+				if (sector_read(sb, LogSector, &tmp_bh, 0) !=
-+				    FFS_SUCCESS)
-+					goto err_out;
-+			}
-+
-+			memcpy((char *)tmp_bh->b_data + offset,
-+			       (char *)buffer + write_bytes, (s32)oneblkwrite);
-+			if (sector_write(sb, LogSector, tmp_bh, 0) !=
-+			    FFS_SUCCESS) {
-+				brelse(tmp_bh);
-+				goto err_out;
-+			}
-+		}
-+
-+		count -= oneblkwrite;
-+		write_bytes += oneblkwrite;
-+		fid->rwoffset += oneblkwrite;
-+
-+		fid->attr |= ATTR_ARCHIVE;
-+
-+		if (fid->size < fid->rwoffset) {
-+			fid->size = fid->rwoffset;
-+			modified = TRUE;
-+		}
-+	}
-+
-+	brelse(tmp_bh);
-+
-+	/* (3) update the direcoty entry */
-+	if (p_fs->vol_type == EXFAT) {
-+		es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry,
-+					  ES_ALL_ENTRIES, &ep);
-+		if (es == NULL)
-+			goto err_out;
-+		ep2 = ep+1;
-+	} else {
-+		ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-+		if (!ep)
-+			goto err_out;
-+		ep2 = ep;
-+	}
-+
-+	p_fs->fs_func->set_entry_time(ep, tm_current(&tm), TM_MODIFY);
-+	p_fs->fs_func->set_entry_attr(ep, fid->attr);
-+
-+	if (p_fs->vol_type != EXFAT)
-+		buf_modify(sb, sector);
-+
-+	if (modified) {
-+		if (p_fs->fs_func->get_entry_flag(ep2) != fid->flags)
-+			p_fs->fs_func->set_entry_flag(ep2, fid->flags);
-+
-+		if (p_fs->fs_func->get_entry_size(ep2) != fid->size)
-+			p_fs->fs_func->set_entry_size(ep2, fid->size);
-+
-+		if (p_fs->fs_func->get_entry_clu0(ep2) != fid->start_clu)
-+			p_fs->fs_func->set_entry_clu0(ep2, fid->start_clu);
-+
-+		if (p_fs->vol_type != EXFAT)
-+			buf_modify(sb, sector);
-+	}
-+
-+	if (p_fs->vol_type == EXFAT) {
-+		update_dir_checksum_with_entry_set(sb, es);
-+		release_entry_set(es);
-+	}
-+
-+#ifdef CONFIG_EXFAT_DELAYED_SYNC
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+#endif
-+
-+err_out:
-+	/* set the size of written bytes */
-+	if (wcount != NULL)
-+		*wcount = write_bytes;
-+
-+	if (num_alloced == 0)
-+		ret = FFS_FULL;
-+
-+	else if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+static int ffsTruncateFile(struct inode *inode, u64 old_size, u64 new_size)
-+{
-+	s32 num_clusters;
-+	u32 last_clu = CLUSTER_32(0);
-+	int ret = 0;
-+	sector_t sector = 0;
-+	struct chain_t clu;
-+	struct timestamp_t tm;
-+	struct dentry_t *ep, *ep2;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+	struct entry_set_cache_t *es = NULL;
-+
-+	pr_debug("%s entered (inode %p size %llu)\n", __func__, inode,
-+		 new_size);
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	/* check if the given file ID is opened */
-+	if (fid->type != TYPE_FILE) {
-+		ret = FFS_PERMISSIONERR;
-+		goto out;
-+	}
-+
-+	if (fid->size != old_size) {
-+		pr_err("[EXFAT] truncate : can't skip it because of size-mismatch(old:%lld->fid:%lld).\n",
-+		       old_size, fid->size);
-+	}
-+
-+	if (old_size <= new_size) {
-+		ret = FFS_SUCCESS;
-+		goto out;
-+	}
-+
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	clu.dir = fid->start_clu;
-+	clu.size = (s32)((old_size-1) >> p_fs->cluster_size_bits) + 1;
-+	clu.flags = fid->flags;
-+
-+	if (new_size > 0) {
-+		num_clusters = (s32)((new_size-1) >>
-+				     p_fs->cluster_size_bits) + 1;
-+
-+		if (clu.flags == 0x03) {
-+			clu.dir += num_clusters;
-+		} else {
-+			while (num_clusters > 0) {
-+				last_clu = clu.dir;
-+				if (FAT_read(sb, clu.dir, &clu.dir) == -1)
-+					return FFS_MEDIAERR;
-+				num_clusters--;
-+			}
-+		}
-+
-+		clu.size -= num_clusters;
-+	}
-+
-+	fid->size = new_size;
-+	fid->attr |= ATTR_ARCHIVE;
-+	if (new_size == 0) {
-+		fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
-+		fid->start_clu = CLUSTER_32(~0);
-+	}
-+
-+	/* (1) update the directory entry */
-+	if (p_fs->vol_type == EXFAT) {
-+		es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
-+					  ES_ALL_ENTRIES, &ep);
-+		if (es == NULL) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+			}
-+		ep2 = ep+1;
-+	} else {
-+		ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-+		if (!ep) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+		ep2 = ep;
-+	}
-+
-+	p_fs->fs_func->set_entry_time(ep, tm_current(&tm), TM_MODIFY);
-+	p_fs->fs_func->set_entry_attr(ep, fid->attr);
-+
-+	p_fs->fs_func->set_entry_size(ep2, new_size);
-+	if (new_size == 0) {
-+		p_fs->fs_func->set_entry_flag(ep2, 0x01);
-+		p_fs->fs_func->set_entry_clu0(ep2, CLUSTER_32(0));
-+	}
-+
-+	if (p_fs->vol_type != EXFAT)
-+		buf_modify(sb, sector);
-+	else {
-+		update_dir_checksum_with_entry_set(sb, es);
-+		release_entry_set(es);
-+	}
-+
-+	/* (2) cut off from the FAT chain */
-+	if (last_clu != CLUSTER_32(0)) {
-+		if (fid->flags == 0x01)
-+			FAT_write(sb, last_clu, CLUSTER_32(~0));
-+	}
-+
-+	/* (3) free the clusters */
-+	p_fs->fs_func->free_cluster(sb, &clu, 0);
-+
-+	/* hint information */
-+	fid->hint_last_off = -1;
-+	if (fid->rwoffset > fid->size)
-+		fid->rwoffset = fid->size;
-+
-+#ifdef CONFIG_EXFAT_DELAYED_SYNC
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+#endif
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	pr_debug("%s exited (%d)\n", __func__, ret);
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+static void update_parent_info(struct file_id_t *fid,
-+			       struct inode *parent_inode)
-+{
-+	struct fs_info_t *p_fs = &(EXFAT_SB(parent_inode->i_sb)->fs_info);
-+	struct file_id_t *parent_fid = &(EXFAT_I(parent_inode)->fid);
-+
-+	if (unlikely((parent_fid->flags != fid->dir.flags) ||
-+		     (parent_fid->size !=
-+		      (fid->dir.size << p_fs->cluster_size_bits)) ||
-+		     (parent_fid->start_clu != fid->dir.dir))) {
-+		fid->dir.dir = parent_fid->start_clu;
-+		fid->dir.flags = parent_fid->flags;
-+		fid->dir.size = ((parent_fid->size + (p_fs->cluster_size-1))
-+						>> p_fs->cluster_size_bits);
-+	}
-+}
-+
-+static int ffsMoveFile(struct inode *old_parent_inode, struct file_id_t *fid,
-+		       struct inode *new_parent_inode, struct dentry *new_dentry)
-+{
-+	s32 ret;
-+	s32 dentry;
-+	struct chain_t olddir, newdir;
-+	struct chain_t *p_dir = NULL;
-+	struct uni_name_t uni_name;
-+	struct dentry_t *ep;
-+	struct super_block *sb = old_parent_inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	u8 *new_path = (u8 *) new_dentry->d_name.name;
-+	struct inode *new_inode = new_dentry->d_inode;
-+	int num_entries;
-+	struct file_id_t *new_fid = NULL;
-+	s32 new_entry = 0;
-+
-+	/* check the validity of the given file id */
-+	if (fid == NULL)
-+		return FFS_INVALIDFID;
-+
-+	/* check the validity of pointer parameters */
-+	if ((new_path == NULL) || (*new_path == '\0'))
-+		return FFS_ERROR;
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	update_parent_info(fid, old_parent_inode);
-+
-+	olddir.dir = fid->dir.dir;
-+	olddir.size = fid->dir.size;
-+	olddir.flags = fid->dir.flags;
-+
-+	dentry = fid->entry;
-+
-+	/* check if the old file is "." or ".." */
-+	if (p_fs->vol_type != EXFAT) {
-+		if ((olddir.dir != p_fs->root_dir) && (dentry < 2)) {
-+			ret = FFS_PERMISSIONERR;
-+			goto out2;
-+		}
-+	}
-+
-+	ep = get_entry_in_dir(sb, &olddir, dentry, NULL);
-+	if (!ep) {
-+		ret = FFS_MEDIAERR;
-+		goto out2;
-+	}
-+
-+	if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) {
-+		ret = FFS_PERMISSIONERR;
-+		goto out2;
-+	}
-+
-+	/* check whether new dir is existing directory and empty */
-+	if (new_inode) {
-+		u32 entry_type;
-+
-+		ret = FFS_MEDIAERR;
-+		new_fid = &EXFAT_I(new_inode)->fid;
-+
-+		update_parent_info(new_fid, new_parent_inode);
-+
-+		p_dir = &(new_fid->dir);
-+		new_entry = new_fid->entry;
-+		ep = get_entry_in_dir(sb, p_dir, new_entry, NULL);
-+		if (!ep)
-+			goto out;
-+
-+		entry_type = p_fs->fs_func->get_entry_type(ep);
-+
-+		if (entry_type == TYPE_DIR) {
-+			struct chain_t new_clu;
-+
-+			new_clu.dir = new_fid->start_clu;
-+			new_clu.size = (s32)((new_fid->size - 1) >>
-+					     p_fs->cluster_size_bits) + 1;
-+			new_clu.flags = new_fid->flags;
-+
-+			if (!is_dir_empty(sb, &new_clu)) {
-+				ret = FFS_FILEEXIST;
-+				goto out;
-+			}
-+		}
-+	}
-+
-+	/* check the validity of directory name in the given new pathname */
-+	ret = resolve_path(new_parent_inode, new_path, &newdir, &uni_name);
-+	if (ret)
-+		goto out2;
-+
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	if (olddir.dir == newdir.dir)
-+		ret = rename_file(new_parent_inode, &olddir, dentry, &uni_name,
-+				  fid);
-+	else
-+		ret = move_file(new_parent_inode, &olddir, dentry, &newdir,
-+				&uni_name, fid);
-+
-+	if ((ret == FFS_SUCCESS) && new_inode) {
-+		/* delete entries of new_dir */
-+		ep = get_entry_in_dir(sb, p_dir, new_entry, NULL);
-+		if (!ep)
-+			goto out;
-+
-+		num_entries = p_fs->fs_func->count_ext_entries(sb, p_dir,
-+							       new_entry, ep);
-+		if (num_entries < 0)
-+			goto out;
-+		p_fs->fs_func->delete_dir_entry(sb, p_dir, new_entry, 0,
-+						num_entries+1);
-+	}
-+out:
-+#ifdef CONFIG_EXFAT_DELAYED_SYNC
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+#endif
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+out2:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+static int ffsRemoveFile(struct inode *inode, struct file_id_t *fid)
-+{
-+	s32 dentry;
-+	int ret = FFS_SUCCESS;
-+	struct chain_t dir, clu_to_free;
-+	struct dentry_t *ep;
-+	struct super_block *sb = inode->i_sb;
-+	struct 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 */
-+	down(&p_fs->v_sem);
-+
-+	dir.dir = fid->dir.dir;
-+	dir.size = fid->dir.size;
-+	dir.flags = fid->dir.flags;
-+
-+	dentry = fid->entry;
-+
-+	ep = get_entry_in_dir(sb, &dir, dentry, NULL);
-+	if (!ep) {
-+		ret = FFS_MEDIAERR;
-+		goto out;
-+	}
-+
-+	if (p_fs->fs_func->get_entry_attr(ep) & ATTR_READONLY) {
-+		ret = FFS_PERMISSIONERR;
-+		goto out;
-+	}
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	/* (1) update the directory entry */
-+	remove_file(inode, &dir, dentry);
-+
-+	clu_to_free.dir = fid->start_clu;
-+	clu_to_free.size = (s32)((fid->size-1) >> p_fs->cluster_size_bits) + 1;
-+	clu_to_free.flags = fid->flags;
-+
-+	/* (2) free the clusters */
-+	p_fs->fs_func->free_cluster(sb, &clu_to_free, 0);
-+
-+	fid->size = 0;
-+	fid->start_clu = CLUSTER_32(~0);
-+	fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
-+
-+#ifdef CONFIG_EXFAT_DELAYED_SYNC
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+#endif
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+#if 0
-+/* Not currently wired up */
-+static int ffsSetAttr(struct inode *inode, u32 attr)
-+{
-+	u32 type;
-+	int ret = FFS_SUCCESS;
-+	sector_t sector = 0;
-+	struct dentry_t *ep;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+	u8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0;
-+	struct entry_set_cache_t *es = NULL;
-+
-+	if (fid->attr == attr) {
-+		if (p_fs->dev_ejected)
-+			return FFS_MEDIAERR;
-+		return FFS_SUCCESS;
-+	}
-+
-+	if (is_dir) {
-+		if ((fid->dir.dir == p_fs->root_dir) &&
-+		    (fid->entry == -1)) {
-+			if (p_fs->dev_ejected)
-+				return FFS_MEDIAERR;
-+			return FFS_SUCCESS;
-+		}
-+	}
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	/* get the directory entry of given file */
-+	if (p_fs->vol_type == EXFAT) {
-+		es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry,
-+					  ES_ALL_ENTRIES, &ep);
-+		if (es == NULL) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+	} else {
-+		ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-+		if (!ep) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+	}
-+
-+	type = p_fs->fs_func->get_entry_type(ep);
-+
-+	if (((type == TYPE_FILE) && (attr & ATTR_SUBDIR)) ||
-+	    ((type == TYPE_DIR) && (!(attr & ATTR_SUBDIR)))) {
-+		if (p_fs->dev_ejected)
-+			ret = FFS_MEDIAERR;
-+		else
-+			ret = FFS_ERROR;
-+
-+		if (p_fs->vol_type == EXFAT)
-+			release_entry_set(es);
-+		goto out;
-+	}
-+
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	/* set the file attribute */
-+	fid->attr = attr;
-+	p_fs->fs_func->set_entry_attr(ep, attr);
-+
-+	if (p_fs->vol_type != EXFAT)
-+		buf_modify(sb, sector);
-+	else {
-+		update_dir_checksum_with_entry_set(sb, es);
-+		release_entry_set(es);
-+	}
-+
-+#ifdef CONFIG_EXFAT_DELAYED_SYNC
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+#endif
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+#endif
-+
-+static int ffsReadStat(struct inode *inode, struct dir_entry_t *info)
-+{
-+	sector_t sector = 0;
-+	s32 count;
-+	int ret = FFS_SUCCESS;
-+	struct chain_t dir;
-+	struct uni_name_t uni_name;
-+	struct timestamp_t tm;
-+	struct dentry_t *ep, *ep2;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+	struct entry_set_cache_t *es = NULL;
-+	u8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0;
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	if (is_dir) {
-+		if ((fid->dir.dir == p_fs->root_dir) &&
-+		    (fid->entry == -1)) {
-+			info->Attr = ATTR_SUBDIR;
-+			memset((char *)&info->CreateTimestamp, 0,
-+			       sizeof(struct date_time_t));
-+			memset((char *)&info->ModifyTimestamp, 0,
-+			       sizeof(struct date_time_t));
-+			memset((char *)&info->AccessTimestamp, 0,
-+			       sizeof(struct date_time_t));
-+			strcpy(info->ShortName, ".");
-+			strcpy(info->Name, ".");
-+
-+			dir.dir = p_fs->root_dir;
-+			dir.flags = 0x01;
-+
-+			if (p_fs->root_dir == CLUSTER_32(0)) {
-+				/* FAT16 root_dir */
-+				info->Size = p_fs->dentries_in_root <<
-+						DENTRY_SIZE_BITS;
-+			} else {
-+				info->Size = count_num_clusters(sb, &dir) <<
-+						p_fs->cluster_size_bits;
-+			}
-+
-+			count = count_dos_name_entries(sb, &dir, TYPE_DIR);
-+			if (count < 0) {
-+				ret = FFS_MEDIAERR;
-+				goto out;
-+			}
-+			info->NumSubdirs = count;
-+
-+			if (p_fs->dev_ejected)
-+				ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+	}
-+
-+	/* get the directory entry of given file or directory */
-+	if (p_fs->vol_type == EXFAT) {
-+		es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry,
-+					  ES_2_ENTRIES, &ep);
-+		if (es == NULL) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+		ep2 = ep+1;
-+	} else {
-+		ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-+		if (!ep) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+		ep2 = ep;
-+		buf_lock(sb, sector);
-+	}
-+
-+	/* set FILE_INFO structure using the acquired struct dentry_t */
-+	info->Attr = p_fs->fs_func->get_entry_attr(ep);
-+
-+	p_fs->fs_func->get_entry_time(ep, &tm, TM_CREATE);
-+	info->CreateTimestamp.Year = tm.year;
-+	info->CreateTimestamp.Month = tm.mon;
-+	info->CreateTimestamp.Day = tm.day;
-+	info->CreateTimestamp.Hour = tm.hour;
-+	info->CreateTimestamp.Minute = tm.min;
-+	info->CreateTimestamp.Second = tm.sec;
-+	info->CreateTimestamp.MilliSecond = 0;
-+
-+	p_fs->fs_func->get_entry_time(ep, &tm, TM_MODIFY);
-+	info->ModifyTimestamp.Year = tm.year;
-+	info->ModifyTimestamp.Month = tm.mon;
-+	info->ModifyTimestamp.Day = tm.day;
-+	info->ModifyTimestamp.Hour = tm.hour;
-+	info->ModifyTimestamp.Minute = tm.min;
-+	info->ModifyTimestamp.Second = tm.sec;
-+	info->ModifyTimestamp.MilliSecond = 0;
-+
-+	memset((char *) &info->AccessTimestamp, 0, sizeof(struct date_time_t));
-+
-+	*(uni_name.name) = 0x0;
-+	/* XXX this is very bad for exfat cuz name is already included in es.
-+	 * API should be revised
-+	 */
-+	p_fs->fs_func->get_uni_name_from_ext_entry(sb, &(fid->dir), fid->entry,
-+						   uni_name.name);
-+	if (*uni_name.name == 0x0 && p_fs->vol_type != EXFAT)
-+		get_uni_name_from_dos_entry(sb, (struct dos_dentry_t *)ep,
-+					    &uni_name, 0x1);
-+	nls_uniname_to_cstring(sb, info->Name, &uni_name);
-+
-+	if (p_fs->vol_type == EXFAT) {
-+		info->NumSubdirs = 2;
-+	} else {
-+		buf_unlock(sb, sector);
-+		get_uni_name_from_dos_entry(sb, (struct dos_dentry_t *)ep,
-+					    &uni_name, 0x0);
-+		nls_uniname_to_cstring(sb, info->ShortName, &uni_name);
-+		info->NumSubdirs = 0;
-+	}
-+
-+	info->Size = p_fs->fs_func->get_entry_size(ep2);
-+
-+	if (p_fs->vol_type == EXFAT)
-+		release_entry_set(es);
-+
-+	if (is_dir) {
-+		dir.dir = fid->start_clu;
-+		dir.flags = 0x01;
-+
-+		if (info->Size == 0)
-+			info->Size = (u64)count_num_clusters(sb, &dir) <<
-+					p_fs->cluster_size_bits;
-+
-+		count = count_dos_name_entries(sb, &dir, TYPE_DIR);
-+		if (count < 0) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+		info->NumSubdirs += count;
-+	}
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	pr_debug("%s exited successfully\n", __func__);
-+	return ret;
-+}
-+
-+static int ffsWriteStat(struct inode *inode, struct dir_entry_t *info)
-+{
-+	sector_t sector = 0;
-+	int ret = FFS_SUCCESS;
-+	struct timestamp_t tm;
-+	struct dentry_t *ep, *ep2;
-+	struct entry_set_cache_t *es = NULL;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+	u8 is_dir = (fid->type == TYPE_DIR) ? 1 : 0;
-+
-+	pr_debug("%s entered (inode %p info %p\n", __func__, inode, info);
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	if (is_dir) {
-+		if ((fid->dir.dir == p_fs->root_dir) &&
-+		    (fid->entry == -1)) {
-+			if (p_fs->dev_ejected)
-+				ret = FFS_MEDIAERR;
-+			ret = FFS_SUCCESS;
-+			goto out;
-+		}
-+	}
-+
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	/* get the directory entry of given file or directory */
-+	if (p_fs->vol_type == EXFAT) {
-+		es = get_entry_set_in_dir(sb, &(fid->dir), fid->entry,
-+					  ES_ALL_ENTRIES, &ep);
-+		if (es == NULL) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+		ep2 = ep+1;
-+	} else {
-+		/* for other than exfat */
-+		ep = get_entry_in_dir(sb, &(fid->dir), fid->entry, &sector);
-+		if (!ep) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+		ep2 = ep;
-+	}
-+
-+	p_fs->fs_func->set_entry_attr(ep, info->Attr);
-+
-+	/* set FILE_INFO structure using the acquired struct dentry_t */
-+	tm.sec  = info->CreateTimestamp.Second;
-+	tm.min  = info->CreateTimestamp.Minute;
-+	tm.hour = info->CreateTimestamp.Hour;
-+	tm.day  = info->CreateTimestamp.Day;
-+	tm.mon  = info->CreateTimestamp.Month;
-+	tm.year = info->CreateTimestamp.Year;
-+	p_fs->fs_func->set_entry_time(ep, &tm, TM_CREATE);
-+
-+	tm.sec  = info->ModifyTimestamp.Second;
-+	tm.min  = info->ModifyTimestamp.Minute;
-+	tm.hour = info->ModifyTimestamp.Hour;
-+	tm.day  = info->ModifyTimestamp.Day;
-+	tm.mon  = info->ModifyTimestamp.Month;
-+	tm.year = info->ModifyTimestamp.Year;
-+	p_fs->fs_func->set_entry_time(ep, &tm, TM_MODIFY);
-+
-+	p_fs->fs_func->set_entry_size(ep2, info->Size);
-+
-+	if (p_fs->vol_type != EXFAT) {
-+		buf_modify(sb, sector);
-+	} else {
-+		update_dir_checksum_with_entry_set(sb, es);
-+		release_entry_set(es);
-+	}
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	pr_debug("%s exited (%d)\n", __func__, ret);
-+
-+	return ret;
-+}
-+
-+static int ffsMapCluster(struct inode *inode, s32 clu_offset, u32 *clu)
-+{
-+	s32 num_clusters, num_alloced, modified = FALSE;
-+	u32 last_clu;
-+	int ret = FFS_SUCCESS;
-+	sector_t sector = 0;
-+	struct chain_t new_clu;
-+	struct dentry_t *ep;
-+	struct entry_set_cache_t *es = NULL;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+
-+	/* check the validity of pointer parameters */
-+	if (clu == NULL)
-+		return FFS_ERROR;
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	fid->rwoffset = (s64)(clu_offset) << p_fs->cluster_size_bits;
-+
-+	if (EXFAT_I(inode)->mmu_private == 0)
-+		num_clusters = 0;
-+	else
-+		num_clusters = (s32)((EXFAT_I(inode)->mmu_private - 1) >>
-+				     p_fs->cluster_size_bits) + 1;
-+
-+	*clu = last_clu = fid->start_clu;
-+
-+	if (fid->flags == 0x03) {
-+		if ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) {
-+			last_clu += clu_offset - 1;
-+
-+			if (clu_offset == num_clusters)
-+				*clu = CLUSTER_32(~0);
-+			else
-+				*clu += clu_offset;
-+		}
-+	} else {
-+		/* hint information */
-+		if ((clu_offset > 0) && (fid->hint_last_off > 0) &&
-+		    (clu_offset >= fid->hint_last_off)) {
-+			clu_offset -= fid->hint_last_off;
-+			*clu = fid->hint_last_clu;
-+		}
-+
-+		while ((clu_offset > 0) && (*clu != CLUSTER_32(~0))) {
-+			last_clu = *clu;
-+			if (FAT_read(sb, *clu, clu) == -1) {
-+				ret = FFS_MEDIAERR;
-+				goto out;
-+			}
-+			clu_offset--;
-+		}
-+	}
-+
-+	if (*clu == CLUSTER_32(~0)) {
-+		fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+		new_clu.dir = (last_clu == CLUSTER_32(~0)) ? CLUSTER_32(~0) :
-+					last_clu + 1;
-+		new_clu.size = 0;
-+		new_clu.flags = fid->flags;
-+
-+		/* (1) allocate a cluster */
-+		num_alloced = p_fs->fs_func->alloc_cluster(sb, 1, &new_clu);
-+		if (num_alloced < 0) {
-+			ret = FFS_MEDIAERR;
-+			goto out;
-+		} else if (num_alloced == 0) {
-+			ret = FFS_FULL;
-+			goto out;
-+		}
-+
-+		/* (2) append to the FAT chain */
-+		if (last_clu == CLUSTER_32(~0)) {
-+			if (new_clu.flags == 0x01)
-+				fid->flags = 0x01;
-+			fid->start_clu = new_clu.dir;
-+			modified = TRUE;
-+		} else {
-+			if (new_clu.flags != fid->flags) {
-+				exfat_chain_cont_cluster(sb, fid->start_clu,
-+							 num_clusters);
-+				fid->flags = 0x01;
-+				modified = TRUE;
-+			}
-+			if (new_clu.flags == 0x01)
-+				FAT_write(sb, last_clu, new_clu.dir);
-+		}
-+
-+		num_clusters += num_alloced;
-+		*clu = new_clu.dir;
-+
-+		if (p_fs->vol_type == EXFAT) {
-+			es = get_entry_set_in_dir(sb, &fid->dir, fid->entry,
-+						  ES_ALL_ENTRIES, &ep);
-+			if (es == NULL) {
-+				ret = FFS_MEDIAERR;
-+				goto out;
-+			}
-+			/* get stream entry */
-+			ep++;
-+		}
-+
-+		/* (3) update directory entry */
-+		if (modified) {
-+			if (p_fs->vol_type != EXFAT) {
-+				ep = get_entry_in_dir(sb, &(fid->dir),
-+						      fid->entry, &sector);
-+				if (!ep) {
-+					ret = FFS_MEDIAERR;
-+					goto out;
-+				}
-+			}
-+
-+			if (p_fs->fs_func->get_entry_flag(ep) != fid->flags)
-+				p_fs->fs_func->set_entry_flag(ep, fid->flags);
-+
-+			if (p_fs->fs_func->get_entry_clu0(ep) != fid->start_clu)
-+				p_fs->fs_func->set_entry_clu0(ep,
-+							      fid->start_clu);
-+
-+			if (p_fs->vol_type != EXFAT)
-+				buf_modify(sb, sector);
-+		}
-+
-+		if (p_fs->vol_type == EXFAT) {
-+			update_dir_checksum_with_entry_set(sb, es);
-+			release_entry_set(es);
-+		}
-+
-+		/* add number of new blocks to inode */
-+		inode->i_blocks += num_alloced << (p_fs->cluster_size_bits - 9);
-+	}
-+
-+	/* hint information */
-+	fid->hint_last_off = (s32)(fid->rwoffset >> p_fs->cluster_size_bits);
-+	fid->hint_last_clu = *clu;
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+/*----------------------------------------------------------------------*/
-+/*  Directory Operation Functions                                       */
-+/*----------------------------------------------------------------------*/
-+
-+static int ffsCreateDir(struct inode *inode, char *path, struct file_id_t *fid)
-+{
-+	int ret = FFS_SUCCESS;
-+	struct chain_t dir;
-+	struct uni_name_t uni_name;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	/* check the validity of pointer parameters */
-+	if ((fid == NULL) || (path == NULL) || (*path == '\0'))
-+		return FFS_ERROR;
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	/* check the validity of directory name in the given old pathname */
-+	ret = resolve_path(inode, path, &dir, &uni_name);
-+	if (ret)
-+		goto out;
-+
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	ret = create_dir(inode, &dir, &uni_name, fid);
-+
-+#ifdef CONFIG_EXFAT_DELAYED_SYNC
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+#endif
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+static int ffsReadDir(struct inode *inode, struct dir_entry_t *dir_entry)
-+{
-+	int i, dentry, clu_offset;
-+	int ret = FFS_SUCCESS;
-+	s32 dentries_per_clu, dentries_per_clu_bits = 0;
-+	u32 type;
-+	sector_t sector;
-+	struct chain_t dir, clu;
-+	struct uni_name_t uni_name;
-+	struct timestamp_t tm;
-+	struct dentry_t *ep;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct fs_func *fs_func = p_fs->fs_func;
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+
-+	/* check the validity of pointer parameters */
-+	if (dir_entry == NULL)
-+		return FFS_ERROR;
-+
-+	/* check if the given file ID is opened */
-+	if (fid->type != TYPE_DIR)
-+		return FFS_PERMISSIONERR;
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	if (fid->entry == -1) {
-+		dir.dir = p_fs->root_dir;
-+		dir.flags = 0x01;
-+	} else {
-+		dir.dir = fid->start_clu;
-+		dir.size = (s32)(fid->size >> p_fs->cluster_size_bits);
-+		dir.flags = fid->flags;
-+	}
-+
-+	dentry = (s32)fid->rwoffset;
-+
-+	if (dir.dir == CLUSTER_32(0)) {
-+		/* FAT16 root_dir */
-+		dentries_per_clu = p_fs->dentries_in_root;
-+
-+		if (dentry == dentries_per_clu) {
-+			clu.dir = CLUSTER_32(~0);
-+		} else {
-+			clu.dir = dir.dir;
-+			clu.size = dir.size;
-+			clu.flags = dir.flags;
-+		}
-+	} else {
-+		dentries_per_clu = p_fs->dentries_per_clu;
-+		dentries_per_clu_bits = ilog2(dentries_per_clu);
-+
-+		clu_offset = dentry >> dentries_per_clu_bits;
-+		clu.dir = dir.dir;
-+		clu.size = dir.size;
-+		clu.flags = dir.flags;
-+
-+		if (clu.flags == 0x03) {
-+			clu.dir += clu_offset;
-+			clu.size -= clu_offset;
-+		} else {
-+			/* hint_information */
-+			if ((clu_offset > 0) && (fid->hint_last_off > 0) &&
-+			    (clu_offset >= fid->hint_last_off)) {
-+				clu_offset -= fid->hint_last_off;
-+				clu.dir = fid->hint_last_clu;
-+			}
-+
-+			while (clu_offset > 0) {
-+				/* clu.dir = FAT_read(sb, clu.dir); */
-+				if (FAT_read(sb, clu.dir, &clu.dir) == -1) {
-+					ret = FFS_MEDIAERR;
-+					goto out;
-+				}
-+				clu_offset--;
-+			}
-+		}
-+	}
-+
-+	while (clu.dir != CLUSTER_32(~0)) {
-+		if (p_fs->dev_ejected)
-+			break;
-+
-+		if (dir.dir == CLUSTER_32(0)) /* FAT16 root_dir */
-+			i = dentry % dentries_per_clu;
-+		else
-+			i = dentry & (dentries_per_clu-1);
-+
-+		for ( ; i < dentries_per_clu; i++, dentry++) {
-+			ep = get_entry_in_dir(sb, &clu, i, &sector);
-+			if (!ep) {
-+				ret = FFS_MEDIAERR;
-+				goto out;
-+			}
-+			type = fs_func->get_entry_type(ep);
-+
-+			if (type == TYPE_UNUSED)
-+				break;
-+
-+			if ((type != TYPE_FILE) && (type != TYPE_DIR))
-+				continue;
-+
-+			buf_lock(sb, sector);
-+			dir_entry->Attr = fs_func->get_entry_attr(ep);
-+
-+			fs_func->get_entry_time(ep, &tm, TM_CREATE);
-+			dir_entry->CreateTimestamp.Year = tm.year;
-+			dir_entry->CreateTimestamp.Month = tm.mon;
-+			dir_entry->CreateTimestamp.Day = tm.day;
-+			dir_entry->CreateTimestamp.Hour = tm.hour;
-+			dir_entry->CreateTimestamp.Minute = tm.min;
-+			dir_entry->CreateTimestamp.Second = tm.sec;
-+			dir_entry->CreateTimestamp.MilliSecond = 0;
-+
-+			fs_func->get_entry_time(ep, &tm, TM_MODIFY);
-+			dir_entry->ModifyTimestamp.Year = tm.year;
-+			dir_entry->ModifyTimestamp.Month = tm.mon;
-+			dir_entry->ModifyTimestamp.Day = tm.day;
-+			dir_entry->ModifyTimestamp.Hour = tm.hour;
-+			dir_entry->ModifyTimestamp.Minute = tm.min;
-+			dir_entry->ModifyTimestamp.Second = tm.sec;
-+			dir_entry->ModifyTimestamp.MilliSecond = 0;
-+
-+			memset((char *)&dir_entry->AccessTimestamp, 0,
-+			       sizeof(struct date_time_t));
-+
-+			*(uni_name.name) = 0x0;
-+			fs_func->get_uni_name_from_ext_entry(sb, &dir, dentry,
-+							     uni_name.name);
-+			if (*uni_name.name == 0x0 && p_fs->vol_type != EXFAT)
-+				get_uni_name_from_dos_entry(sb,
-+						(struct dos_dentry_t *)ep,
-+						&uni_name, 0x1);
-+			nls_uniname_to_cstring(sb, dir_entry->Name, &uni_name);
-+			buf_unlock(sb, sector);
-+
-+			if (p_fs->vol_type == EXFAT) {
-+				ep = get_entry_in_dir(sb, &clu, i+1, NULL);
-+				if (!ep) {
-+					ret = FFS_MEDIAERR;
-+					goto out;
-+				}
-+			} else {
-+				get_uni_name_from_dos_entry(sb,
-+						(struct dos_dentry_t *)ep,
-+						&uni_name, 0x0);
-+				nls_uniname_to_cstring(sb, dir_entry->ShortName,
-+						       &uni_name);
-+			}
-+
-+			dir_entry->Size = fs_func->get_entry_size(ep);
-+
-+			/* hint information */
-+			if (dir.dir == CLUSTER_32(0)) { /* FAT16 root_dir */
-+			} else {
-+				fid->hint_last_off = dentry >>
-+							dentries_per_clu_bits;
-+				fid->hint_last_clu = clu.dir;
-+			}
-+
-+			fid->rwoffset = (s64) ++dentry;
-+
-+			if (p_fs->dev_ejected)
-+				ret = FFS_MEDIAERR;
-+			goto out;
-+		}
-+
-+		if (dir.dir == CLUSTER_32(0))
-+			break; /* FAT16 root_dir */
-+
-+		if (clu.flags == 0x03) {
-+			if ((--clu.size) > 0)
-+				clu.dir++;
-+			else
-+				clu.dir = CLUSTER_32(~0);
-+		} else {
-+			/* clu.dir = FAT_read(sb, clu.dir); */
-+			if (FAT_read(sb, clu.dir, &clu.dir) == -1) {
-+				ret = FFS_MEDIAERR;
-+				goto out;
-+			}
-+		}
-+	}
-+
-+	*(dir_entry->Name) = '\0';
-+
-+	fid->rwoffset = (s64) ++dentry;
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+static int ffsRemoveDir(struct inode *inode, struct file_id_t *fid)
-+{
-+	s32 dentry;
-+	int ret = FFS_SUCCESS;
-+	struct chain_t dir, clu_to_free;
-+	struct super_block *sb = inode->i_sb;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	/* check the validity of the given file id */
-+	if (fid == NULL)
-+		return FFS_INVALIDFID;
-+
-+	dir.dir = fid->dir.dir;
-+	dir.size = fid->dir.size;
-+	dir.flags = fid->dir.flags;
-+
-+	dentry = fid->entry;
-+
-+	/* check if the file is "." or ".." */
-+	if (p_fs->vol_type != EXFAT) {
-+		if ((dir.dir != p_fs->root_dir) && (dentry < 2))
-+			return FFS_PERMISSIONERR;
-+	}
-+
-+	/* acquire the lock for file system critical section */
-+	down(&p_fs->v_sem);
-+
-+	clu_to_free.dir = fid->start_clu;
-+	clu_to_free.size = (s32)((fid->size-1) >> p_fs->cluster_size_bits) + 1;
-+	clu_to_free.flags = fid->flags;
-+
-+	if (!is_dir_empty(sb, &clu_to_free)) {
-+		ret = FFS_FILEEXIST;
-+		goto out;
-+	}
-+
-+	fs_set_vol_flags(sb, VOL_DIRTY);
-+
-+	/* (1) update the directory entry */
-+	remove_file(inode, &dir, dentry);
-+
-+	/* (2) free the clusters */
-+	p_fs->fs_func->free_cluster(sb, &clu_to_free, 1);
-+
-+	fid->size = 0;
-+	fid->start_clu = CLUSTER_32(~0);
-+	fid->flags = (p_fs->vol_type == EXFAT) ? 0x03 : 0x01;
-+
-+#ifdef CONFIG_EXFAT_DELAYED_SYNC
-+	fs_sync(sb, false);
-+	fs_set_vol_flags(sb, VOL_CLEAN);
-+#endif
-+
-+	if (p_fs->dev_ejected)
-+		ret = FFS_MEDIAERR;
-+
-+out:
-+	/* release the lock for file system critical section */
-+	up(&p_fs->v_sem);
-+
-+	return ret;
-+}
-+
-+/*======================================================================*/
-+/*  Directory Entry Operations                                          */
-+/*======================================================================*/
-+
-+static int exfat_readdir(struct file *filp, struct dir_context *ctx)
-+{
-+	struct inode *inode = file_inode(filp);
-+	struct super_block *sb = inode->i_sb;
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct fs_info_t *p_fs = &(sbi->fs_info);
-+	struct bd_info_t *p_bd = &(EXFAT_SB(sb)->bd_info);
-+	struct dir_entry_t de;
-+	unsigned long inum;
-+	loff_t cpos;
-+	int err = 0;
-+
-+	__lock_super(sb);
-+
-+	cpos = ctx->pos;
-+	/* Fake . and .. for the root directory. */
-+	if ((p_fs->vol_type == EXFAT) || (inode->i_ino == EXFAT_ROOT_INO)) {
-+		while (cpos < 2) {
-+			if (inode->i_ino == EXFAT_ROOT_INO)
-+				inum = EXFAT_ROOT_INO;
-+			else if (cpos == 0)
-+				inum = inode->i_ino;
-+			else /* (cpos == 1) */
-+				inum = parent_ino(filp->f_path.dentry);
-+
-+			if (!dir_emit_dots(filp, ctx))
-+				goto out;
-+			cpos++;
-+			ctx->pos++;
-+		}
-+		if (cpos == 2)
-+			cpos = 0;
-+	}
-+	if (cpos & (DENTRY_SIZE - 1)) {
-+		err = -ENOENT;
-+		goto out;
-+	}
-+
-+get_new:
-+	EXFAT_I(inode)->fid.size = i_size_read(inode);
-+	EXFAT_I(inode)->fid.rwoffset = cpos >> DENTRY_SIZE_BITS;
-+
-+	err = ffsReadDir(inode, &de);
-+	if (err) {
-+		/* at least we tried to read a sector
-+		 * move cpos to next sector position (should be aligned)
-+		 */
-+		if (err == FFS_MEDIAERR) {
-+			cpos += 1 << p_bd->sector_size_bits;
-+			cpos &= ~((1 << p_bd->sector_size_bits)-1);
-+		}
-+
-+		err = -EIO;
-+		goto end_of_dir;
-+	}
-+
-+	cpos = EXFAT_I(inode)->fid.rwoffset << DENTRY_SIZE_BITS;
-+
-+	if (!de.Name[0])
-+		goto end_of_dir;
-+
-+	if (!memcmp(de.ShortName, DOS_CUR_DIR_NAME, DOS_NAME_LENGTH)) {
-+		inum = inode->i_ino;
-+	} else if (!memcmp(de.ShortName, DOS_PAR_DIR_NAME, DOS_NAME_LENGTH)) {
-+		inum = parent_ino(filp->f_path.dentry);
-+	} else {
-+		loff_t i_pos = ((loff_t) EXFAT_I(inode)->fid.start_clu << 32) |
-+				((EXFAT_I(inode)->fid.rwoffset-1) & 0xffffffff);
-+		struct inode *tmp = exfat_iget(sb, i_pos);
-+
-+		if (tmp) {
-+			inum = tmp->i_ino;
-+			iput(tmp);
-+		} else {
-+			inum = iunique(sb, EXFAT_ROOT_INO);
-+		}
-+	}
-+
-+	if (!dir_emit(ctx, de.Name, strlen(de.Name), inum,
-+		      (de.Attr & ATTR_SUBDIR) ? DT_DIR : DT_REG))
-+		goto out;
-+
-+	ctx->pos = cpos;
-+	goto get_new;
-+
-+end_of_dir:
-+	ctx->pos = cpos;
-+out:
-+	__unlock_super(sb);
-+	return err;
-+}
-+
-+static int exfat_ioctl_volume_id(struct inode *dir)
-+{
-+	struct super_block *sb = dir->i_sb;
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct fs_info_t *p_fs = &(sbi->fs_info);
-+
-+	return p_fs->vol_id;
-+}
-+
-+static long exfat_generic_ioctl(struct file *filp, unsigned int cmd,
-+				unsigned long arg)
-+{
-+struct inode *inode = filp->f_path.dentry->d_inode;
-+#ifdef CONFIG_EXFAT_KERNEL_DEBUG
-+	unsigned int flags;
-+#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
-+
-+	switch (cmd) {
-+	case EXFAT_IOCTL_GET_VOLUME_ID:
-+		return exfat_ioctl_volume_id(inode);
-+#ifdef CONFIG_EXFAT_KERNEL_DEBUG
-+	case EXFAT_IOC_GET_DEBUGFLAGS: {
-+		struct super_block *sb = inode->i_sb;
-+		struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+
-+		flags = sbi->debug_flags;
-+		return put_user(flags, (int __user *)arg);
-+	}
-+	case EXFAT_IOC_SET_DEBUGFLAGS: {
-+		struct super_block *sb = inode->i_sb;
-+		struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+
-+		if (!capable(CAP_SYS_ADMIN))
-+			return -EPERM;
-+
-+		if (get_user(flags, (int __user *) arg))
-+			return -EFAULT;
-+
-+		__lock_super(sb);
-+		sbi->debug_flags = flags;
-+		__unlock_super(sb);
-+
-+		return 0;
-+	}
-+#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
-+	default:
-+		return -ENOTTY; /* Inappropriate ioctl for device */
-+	}
-+}
-+
-+static const struct file_operations exfat_dir_operations = {
-+	.llseek     = generic_file_llseek,
-+	.read       = generic_read_dir,
-+	.iterate    = exfat_readdir,
-+	.unlocked_ioctl = exfat_generic_ioctl,
-+	.fsync      = generic_file_fsync,
-+};
-+
-+static int exfat_create(struct inode *dir, struct dentry *dentry, umode_t mode,
-+			bool excl)
-+{
-+	struct super_block *sb = dir->i_sb;
-+	struct inode *inode;
-+	struct file_id_t fid;
-+	loff_t i_pos;
-+	int err;
-+
-+	__lock_super(sb);
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	err = ffsCreateFile(dir, (u8 *) dentry->d_name.name, FM_REGULAR, &fid);
-+	if (err) {
-+		if (err == FFS_INVALIDPATH)
-+			err = -EINVAL;
-+		else if (err == FFS_FILEEXIST)
-+			err = -EEXIST;
-+		else if (err == FFS_FULL)
-+			err = -ENOSPC;
-+		else if (err == FFS_NAMETOOLONG)
-+			err = -ENAMETOOLONG;
-+		else
-+			err = -EIO;
-+		goto out;
-+	}
-+	INC_IVERSION(dir);
-+	dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
-+	if (IS_DIRSYNC(dir))
-+		(void) exfat_sync_inode(dir);
-+	else
-+		mark_inode_dirty(dir);
-+
-+	i_pos = ((loff_t) fid.dir.dir << 32) | (fid.entry & 0xffffffff);
-+
-+	inode = exfat_build_inode(sb, &fid, i_pos);
-+	if (IS_ERR(inode)) {
-+		err = PTR_ERR(inode);
-+		goto out;
-+	}
-+	INC_IVERSION(inode);
-+	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
-+	/*
-+	 * timestamp is already written, so mark_inode_dirty() is unnecessary.
-+	 */
-+
-+	dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode);
-+	d_instantiate(dentry, inode);
-+
-+out:
-+	__unlock_super(sb);
-+	pr_debug("%s exited\n", __func__);
-+	return err;
-+}
-+
-+static int exfat_find(struct inode *dir, struct qstr *qname,
-+		      struct file_id_t *fid)
-+{
-+	int err;
-+
-+	if (qname->len == 0)
-+		return -ENOENT;
-+
-+	err = ffsLookupFile(dir, (u8 *) qname->name, fid);
-+	if (err)
-+		return -ENOENT;
-+
-+	return 0;
-+}
-+
-+static int exfat_d_anon_disconn(struct dentry *dentry)
-+{
-+	return IS_ROOT(dentry) && (dentry->d_flags & DCACHE_DISCONNECTED);
-+}
-+
-+static struct dentry *exfat_lookup(struct inode *dir, struct dentry *dentry,
-+				   unsigned int flags)
-+{
-+	struct super_block *sb = dir->i_sb;
-+	struct inode *inode;
-+	struct dentry *alias;
-+	int err;
-+	struct file_id_t fid;
-+	loff_t i_pos;
-+	u64 ret;
-+	mode_t i_mode;
-+
-+	__lock_super(sb);
-+	pr_debug("%s entered\n", __func__);
-+	err = exfat_find(dir, &dentry->d_name, &fid);
-+	if (err) {
-+		if (err == -ENOENT) {
-+			inode = NULL;
-+			goto out;
-+		}
-+		goto error;
-+	}
-+
-+	i_pos = ((loff_t) fid.dir.dir << 32) | (fid.entry & 0xffffffff);
-+	inode = exfat_build_inode(sb, &fid, i_pos);
-+	if (IS_ERR(inode)) {
-+		err = PTR_ERR(inode);
-+		goto error;
-+	}
-+
-+	i_mode = inode->i_mode;
-+	if (S_ISLNK(i_mode) && !EXFAT_I(inode)->target) {
-+		EXFAT_I(inode)->target = kmalloc(i_size_read(inode) + 1,
-+						 GFP_KERNEL);
-+		if (!EXFAT_I(inode)->target) {
-+			err = -ENOMEM;
-+			goto error;
-+		}
-+		ffsReadFile(dir, &fid, EXFAT_I(inode)->target,
-+			    i_size_read(inode), &ret);
-+		*(EXFAT_I(inode)->target + i_size_read(inode)) = '\0';
-+	}
-+
-+	alias = d_find_alias(inode);
-+	if (alias && !exfat_d_anon_disconn(alias)) {
-+		BUG_ON(d_unhashed(alias));
-+		if (!S_ISDIR(i_mode))
-+			d_move(alias, dentry);
-+		iput(inode);
-+		__unlock_super(sb);
-+		pr_debug("%s exited 1\n", __func__);
-+		return alias;
-+	}
-+	dput(alias);
-+out:
-+	__unlock_super(sb);
-+	dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode);
-+	dentry = d_splice_alias(inode, dentry);
-+	if (dentry)
-+		dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode);
-+	pr_debug("%s exited 2\n", __func__);
-+	return dentry;
-+
-+error:
-+	__unlock_super(sb);
-+	pr_debug("%s exited 3\n", __func__);
-+	return ERR_PTR(err);
-+}
-+
-+static inline unsigned long exfat_hash(loff_t i_pos)
-+{
-+	return hash_32(i_pos, EXFAT_HASH_BITS);
-+}
-+
-+static void exfat_attach(struct inode *inode, loff_t i_pos)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
-+	struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos);
-+
-+	spin_lock(&sbi->inode_hash_lock);
-+	EXFAT_I(inode)->i_pos = i_pos;
-+	hlist_add_head(&EXFAT_I(inode)->i_hash_fat, head);
-+	spin_unlock(&sbi->inode_hash_lock);
-+}
-+
-+static void exfat_detach(struct inode *inode)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
-+
-+	spin_lock(&sbi->inode_hash_lock);
-+	hlist_del_init(&EXFAT_I(inode)->i_hash_fat);
-+	EXFAT_I(inode)->i_pos = 0;
-+	spin_unlock(&sbi->inode_hash_lock);
-+}
-+
-+static int exfat_unlink(struct inode *dir, struct dentry *dentry)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	struct super_block *sb = dir->i_sb;
-+	int err;
-+
-+	__lock_super(sb);
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	EXFAT_I(inode)->fid.size = i_size_read(inode);
-+
-+	err = ffsRemoveFile(dir, &(EXFAT_I(inode)->fid));
-+	if (err) {
-+		if (err == FFS_PERMISSIONERR)
-+			err = -EPERM;
-+		else
-+			err = -EIO;
-+		goto out;
-+	}
-+	INC_IVERSION(dir);
-+	dir->i_mtime = dir->i_atime = current_time(dir);
-+	if (IS_DIRSYNC(dir))
-+		(void) exfat_sync_inode(dir);
-+	else
-+		mark_inode_dirty(dir);
-+
-+	clear_nlink(inode);
-+	inode->i_mtime = inode->i_atime = current_time(inode);
-+	exfat_detach(inode);
-+	remove_inode_hash(inode);
-+
-+out:
-+	__unlock_super(sb);
-+	pr_debug("%s exited\n", __func__);
-+	return err;
-+}
-+
-+static int exfat_symlink(struct inode *dir, struct dentry *dentry,
-+			 const char *target)
-+{
-+	struct super_block *sb = dir->i_sb;
-+	struct inode *inode;
-+	struct file_id_t fid;
-+	loff_t i_pos;
-+	int err;
-+	u64 len = (u64) strlen(target);
-+	u64 ret;
-+
-+	__lock_super(sb);
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	err = ffsCreateFile(dir, (u8 *) dentry->d_name.name, FM_SYMLINK, &fid);
-+	if (err) {
-+		if (err == FFS_INVALIDPATH)
-+			err = -EINVAL;
-+		else if (err == FFS_FILEEXIST)
-+			err = -EEXIST;
-+		else if (err == FFS_FULL)
-+			err = -ENOSPC;
-+		else
-+			err = -EIO;
-+		goto out;
-+	}
-+
-+	err = ffsWriteFile(dir, &fid, (char *) target, len, &ret);
-+
-+	if (err) {
-+		ffsRemoveFile(dir, &fid);
-+
-+		if (err == FFS_FULL)
-+			err = -ENOSPC;
-+		else
-+			err = -EIO;
-+		goto out;
-+	}
-+
-+	INC_IVERSION(dir);
-+	dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
-+	if (IS_DIRSYNC(dir))
-+		(void) exfat_sync_inode(dir);
-+	else
-+		mark_inode_dirty(dir);
-+
-+	i_pos = ((loff_t) fid.dir.dir << 32) | (fid.entry & 0xffffffff);
-+
-+	inode = exfat_build_inode(sb, &fid, i_pos);
-+	if (IS_ERR(inode)) {
-+		err = PTR_ERR(inode);
-+		goto out;
-+	}
-+	INC_IVERSION(inode);
-+	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
-+	/* timestamp is already written, so mark_inode_dirty() is unneeded. */
-+
-+	EXFAT_I(inode)->target = kmalloc(len+1, GFP_KERNEL);
-+	if (!EXFAT_I(inode)->target) {
-+		err = -ENOMEM;
-+		goto out;
-+	}
-+	memcpy(EXFAT_I(inode)->target, target, len+1);
-+
-+	dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode);
-+	d_instantiate(dentry, inode);
-+
-+out:
-+	__unlock_super(sb);
-+	pr_debug("%s exited\n", __func__);
-+	return err;
-+}
-+
-+static int exfat_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
-+{
-+	struct super_block *sb = dir->i_sb;
-+	struct inode *inode;
-+	struct file_id_t fid;
-+	loff_t i_pos;
-+	int err;
-+
-+	__lock_super(sb);
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	err = ffsCreateDir(dir, (u8 *) dentry->d_name.name, &fid);
-+	if (err) {
-+		if (err == FFS_INVALIDPATH)
-+			err = -EINVAL;
-+		else if (err == FFS_FILEEXIST)
-+			err = -EEXIST;
-+		else if (err == FFS_FULL)
-+			err = -ENOSPC;
-+		else if (err == FFS_NAMETOOLONG)
-+			err = -ENAMETOOLONG;
-+		else
-+			err = -EIO;
-+		goto out;
-+	}
-+	INC_IVERSION(dir);
-+	dir->i_ctime = dir->i_mtime = dir->i_atime = current_time(dir);
-+	if (IS_DIRSYNC(dir))
-+		(void) exfat_sync_inode(dir);
-+	else
-+		mark_inode_dirty(dir);
-+	inc_nlink(dir);
-+
-+	i_pos = ((loff_t) fid.dir.dir << 32) | (fid.entry & 0xffffffff);
-+
-+	inode = exfat_build_inode(sb, &fid, i_pos);
-+	if (IS_ERR(inode)) {
-+		err = PTR_ERR(inode);
-+		goto out;
-+	}
-+	INC_IVERSION(inode);
-+	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
-+	/* timestamp is already written, so mark_inode_dirty() is unneeded. */
-+
-+	dentry->d_time = GET_IVERSION(dentry->d_parent->d_inode);
-+	d_instantiate(dentry, inode);
-+
-+out:
-+	__unlock_super(sb);
-+	pr_debug("%s exited\n", __func__);
-+	return err;
-+}
-+
-+static int exfat_rmdir(struct inode *dir, struct dentry *dentry)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	struct super_block *sb = dir->i_sb;
-+	int err;
-+
-+	__lock_super(sb);
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	EXFAT_I(inode)->fid.size = i_size_read(inode);
-+
-+	err = ffsRemoveDir(dir, &(EXFAT_I(inode)->fid));
-+	if (err) {
-+		if (err == FFS_INVALIDPATH)
-+			err = -EINVAL;
-+		else if (err == FFS_FILEEXIST)
-+			err = -ENOTEMPTY;
-+		else if (err == FFS_NOTFOUND)
-+			err = -ENOENT;
-+		else if (err == FFS_DIRBUSY)
-+			err = -EBUSY;
-+		else
-+			err = -EIO;
-+		goto out;
-+	}
-+	INC_IVERSION(dir);
-+	dir->i_mtime = dir->i_atime = current_time(dir);
-+	if (IS_DIRSYNC(dir))
-+		(void) exfat_sync_inode(dir);
-+	else
-+		mark_inode_dirty(dir);
-+	drop_nlink(dir);
-+
-+	clear_nlink(inode);
-+	inode->i_mtime = inode->i_atime = current_time(inode);
-+	exfat_detach(inode);
-+	remove_inode_hash(inode);
-+
-+out:
-+	__unlock_super(sb);
-+	pr_debug("%s exited\n", __func__);
-+	return err;
-+}
-+
-+static int exfat_rename(struct inode *old_dir, struct dentry *old_dentry,
-+			struct inode *new_dir, struct dentry *new_dentry,
-+			unsigned int flags)
-+{
-+	struct inode *old_inode, *new_inode;
-+	struct super_block *sb = old_dir->i_sb;
-+	loff_t i_pos;
-+	int err;
-+
-+	if (flags)
-+		return -EINVAL;
-+
-+	__lock_super(sb);
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	old_inode = old_dentry->d_inode;
-+	new_inode = new_dentry->d_inode;
-+
-+	EXFAT_I(old_inode)->fid.size = i_size_read(old_inode);
-+
-+	err = ffsMoveFile(old_dir, &(EXFAT_I(old_inode)->fid), new_dir,
-+			  new_dentry);
-+	if (err) {
-+		if (err == FFS_PERMISSIONERR)
-+			err = -EPERM;
-+		else if (err == FFS_INVALIDPATH)
-+			err = -EINVAL;
-+		else if (err == FFS_FILEEXIST)
-+			err = -EEXIST;
-+		else if (err == FFS_NOTFOUND)
-+			err = -ENOENT;
-+		else if (err == FFS_FULL)
-+			err = -ENOSPC;
-+		else
-+			err = -EIO;
-+		goto out;
-+	}
-+	INC_IVERSION(new_dir);
-+	new_dir->i_ctime = new_dir->i_mtime = new_dir->i_atime =
-+				current_time(new_dir);
-+	if (IS_DIRSYNC(new_dir))
-+		(void) exfat_sync_inode(new_dir);
-+	else
-+		mark_inode_dirty(new_dir);
-+
-+	i_pos = ((loff_t) EXFAT_I(old_inode)->fid.dir.dir << 32) |
-+			(EXFAT_I(old_inode)->fid.entry & 0xffffffff);
-+
-+	exfat_detach(old_inode);
-+	exfat_attach(old_inode, i_pos);
-+	if (IS_DIRSYNC(new_dir))
-+		(void) exfat_sync_inode(old_inode);
-+	else
-+		mark_inode_dirty(old_inode);
-+
-+	if ((S_ISDIR(old_inode->i_mode)) && (old_dir != new_dir)) {
-+		drop_nlink(old_dir);
-+		if (!new_inode)
-+			inc_nlink(new_dir);
-+	}
-+	INC_IVERSION(old_dir);
-+	old_dir->i_ctime = old_dir->i_mtime = current_time(old_dir);
-+	if (IS_DIRSYNC(old_dir))
-+		(void) exfat_sync_inode(old_dir);
-+	else
-+		mark_inode_dirty(old_dir);
-+
-+	if (new_inode) {
-+		exfat_detach(new_inode);
-+		drop_nlink(new_inode);
-+		if (S_ISDIR(new_inode->i_mode))
-+			drop_nlink(new_inode);
-+		new_inode->i_ctime = current_time(new_inode);
-+	}
-+
-+out:
-+	__unlock_super(sb);
-+	pr_debug("%s exited\n", __func__);
-+	return err;
-+}
-+
-+static int exfat_cont_expand(struct inode *inode, loff_t size)
-+{
-+	struct address_space *mapping = inode->i_mapping;
-+	loff_t start = i_size_read(inode), count = size - i_size_read(inode);
-+	int err, err2;
-+
-+	err = generic_cont_expand_simple(inode, size);
-+	if (err != 0)
-+		return err;
-+
-+	inode->i_ctime = inode->i_mtime = current_time(inode);
-+	mark_inode_dirty(inode);
-+
-+	if (IS_SYNC(inode)) {
-+		err = filemap_fdatawrite_range(mapping, start,
-+					       start + count - 1);
-+		err2 = sync_mapping_buffers(mapping);
-+		err = (err) ? (err) : (err2);
-+		err2 = write_inode_now(inode, 1);
-+		err = (err) ? (err) : (err2);
-+		if (!err)
-+			err =  filemap_fdatawait_range(mapping, start,
-+						       start + count - 1);
-+	}
-+	return err;
-+}
-+
-+static int exfat_allow_set_time(struct exfat_sb_info *sbi, struct inode *inode)
-+{
-+	mode_t allow_utime = sbi->options.allow_utime;
-+
-+	if (!uid_eq(current_fsuid(), inode->i_uid)) {
-+		if (in_group_p(inode->i_gid))
-+			allow_utime >>= 3;
-+		if (allow_utime & MAY_WRITE)
-+			return 1;
-+	}
-+
-+	/* use a default check */
-+	return 0;
-+}
-+
-+static int exfat_sanitize_mode(const struct exfat_sb_info *sbi,
-+			       struct inode *inode, umode_t *mode_ptr)
-+{
-+	mode_t i_mode, mask, perm;
-+
-+	i_mode = inode->i_mode;
-+
-+	if (S_ISREG(i_mode) || S_ISLNK(i_mode))
-+		mask = sbi->options.fs_fmask;
-+	else
-+		mask = sbi->options.fs_dmask;
-+
-+	perm = *mode_ptr & ~(S_IFMT | mask);
-+
-+	/* Of the r and x bits, all (subject to umask) must be present.*/
-+	if ((perm & 0555) != (i_mode & 0555))
-+		return -EPERM;
-+
-+	if (exfat_mode_can_hold_ro(inode)) {
-+		/*
-+		 * Of the w bits, either all (subject to umask) or none must be
-+		 * present.
-+		 */
-+		if ((perm & 0222) && ((perm & 0222) != (0222 & ~mask)))
-+			return -EPERM;
-+	} else {
-+		/*
-+		 * If exfat_mode_can_hold_ro(inode) is false, can't change w
-+		 * bits.
-+		 */
-+		if ((perm & 0222) != (0222 & ~mask))
-+			return -EPERM;
-+	}
-+
-+	*mode_ptr &= S_IFMT | perm;
-+
-+	return 0;
-+}
-+
-+static void exfat_truncate(struct inode *inode, loff_t old_size)
-+{
-+	struct super_block *sb = inode->i_sb;
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct fs_info_t *p_fs = &(sbi->fs_info);
-+	int err;
-+
-+	__lock_super(sb);
-+
-+	/*
-+	 * This protects against truncating a file bigger than it was then
-+	 * trying to write into the hole.
-+	 */
-+	if (EXFAT_I(inode)->mmu_private > i_size_read(inode))
-+		EXFAT_I(inode)->mmu_private = i_size_read(inode);
-+
-+	if (EXFAT_I(inode)->fid.start_clu == 0)
-+		goto out;
-+
-+	err = ffsTruncateFile(inode, old_size, i_size_read(inode));
-+	if (err)
-+		goto out;
-+
-+	inode->i_ctime = inode->i_mtime = current_time(inode);
-+	if (IS_DIRSYNC(inode))
-+		(void) exfat_sync_inode(inode);
-+	else
-+		mark_inode_dirty(inode);
-+
-+	inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1)) &
-+			   ~((loff_t)p_fs->cluster_size - 1)) >> 9;
-+out:
-+	__unlock_super(sb);
-+}
-+
-+static int exfat_setattr(struct dentry *dentry, struct iattr *attr)
-+{
-+
-+	struct exfat_sb_info *sbi = EXFAT_SB(dentry->d_sb);
-+	struct inode *inode = dentry->d_inode;
-+	unsigned int ia_valid;
-+	int error;
-+	loff_t old_size;
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	if ((attr->ia_valid & ATTR_SIZE)
-+		&& (attr->ia_size > i_size_read(inode))) {
-+		error = exfat_cont_expand(inode, attr->ia_size);
-+		if (error || attr->ia_valid == ATTR_SIZE)
-+			return error;
-+		attr->ia_valid &= ~ATTR_SIZE;
-+	}
-+
-+	ia_valid = attr->ia_valid;
-+
-+	if ((ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET))
-+		&& exfat_allow_set_time(sbi, inode)) {
-+		attr->ia_valid &= ~(ATTR_MTIME_SET |
-+				    ATTR_ATIME_SET |
-+				    ATTR_TIMES_SET);
-+	}
-+
-+	error = setattr_prepare(dentry, attr);
-+	attr->ia_valid = ia_valid;
-+	if (error)
-+		return error;
-+
-+	if (((attr->ia_valid & ATTR_UID) &&
-+	     (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) ||
-+	    ((attr->ia_valid & ATTR_GID) &&
-+	     (!gid_eq(attr->ia_gid, sbi->options.fs_gid))) ||
-+	    ((attr->ia_valid & ATTR_MODE) &&
-+	     (attr->ia_mode & ~(S_IFREG | S_IFLNK | S_IFDIR | 0777)))) {
-+		return -EPERM;
-+	}
-+
-+	/*
-+	 * We don't return -EPERM here. Yes, strange, but this is too
-+	 * old behavior.
-+	 */
-+	if (attr->ia_valid & ATTR_MODE) {
-+		if (exfat_sanitize_mode(sbi, inode, &attr->ia_mode) < 0)
-+			attr->ia_valid &= ~ATTR_MODE;
-+	}
-+
-+	EXFAT_I(inode)->fid.size = i_size_read(inode);
-+
-+	if (attr->ia_valid & ATTR_SIZE) {
-+		old_size = i_size_read(inode);
-+		down_write(&EXFAT_I(inode)->truncate_lock);
-+		truncate_setsize(inode, attr->ia_size);
-+		exfat_truncate(inode, old_size);
-+		up_write(&EXFAT_I(inode)->truncate_lock);
-+	}
-+	setattr_copy(inode, attr);
-+	mark_inode_dirty(inode);
-+
-+	pr_debug("%s exited\n", __func__);
-+	return error;
-+}
-+
-+static int exfat_getattr(const struct path *path, struct kstat *stat,
-+			 u32 request_mask, unsigned int flags)
-+{
-+	struct inode *inode = path->dentry->d_inode;
-+
-+	pr_debug("%s entered\n", __func__);
-+
-+	generic_fillattr(inode, stat);
-+	stat->blksize = EXFAT_SB(inode->i_sb)->fs_info.cluster_size;
-+
-+	pr_debug("%s exited\n", __func__);
-+	return 0;
-+}
-+
-+static const struct inode_operations exfat_dir_inode_operations = {
-+	.create        = exfat_create,
-+	.lookup        = exfat_lookup,
-+	.unlink        = exfat_unlink,
-+	.symlink       = exfat_symlink,
-+	.mkdir         = exfat_mkdir,
-+	.rmdir         = exfat_rmdir,
-+	.rename        = exfat_rename,
-+	.setattr       = exfat_setattr,
-+	.getattr       = exfat_getattr,
-+};
-+
-+/*======================================================================*/
-+/*  File Operations                                                     */
-+/*======================================================================*/
-+static const char *exfat_get_link(struct dentry *dentry, struct inode *inode,
-+				  struct delayed_call *done)
-+{
-+	struct exfat_inode_info *ei = EXFAT_I(inode);
-+
-+	if (ei->target != NULL) {
-+		char *cookie = ei->target;
-+
-+		if (cookie != NULL)
-+			return (char *)(ei->target);
-+	}
-+	return NULL;
-+}
-+
-+static const struct inode_operations exfat_symlink_inode_operations = {
-+		.get_link = exfat_get_link,
-+};
-+
-+static int exfat_file_release(struct inode *inode, struct file *filp)
-+{
-+	struct super_block *sb = inode->i_sb;
-+
-+	EXFAT_I(inode)->fid.size = i_size_read(inode);
-+	ffsSyncVol(sb, false);
-+	return 0;
-+}
-+
-+static const struct file_operations exfat_file_operations = {
-+	.llseek      = generic_file_llseek,
-+	.read_iter   = generic_file_read_iter,
-+	.write_iter  = generic_file_write_iter,
-+	.mmap        = generic_file_mmap,
-+	.release     = exfat_file_release,
-+	.unlocked_ioctl  = exfat_generic_ioctl,
-+	.fsync       = generic_file_fsync,
-+	.splice_read = generic_file_splice_read,
-+};
-+
-+static const struct inode_operations exfat_file_inode_operations = {
-+	.setattr     = exfat_setattr,
-+	.getattr     = exfat_getattr,
-+};
-+
-+/*======================================================================*/
-+/*  Address Space Operations                                            */
-+/*======================================================================*/
-+
-+static int exfat_bmap(struct inode *inode, sector_t sector, sector_t *phys,
-+		      unsigned long *mapped_blocks, int *create)
-+{
-+	struct super_block *sb = inode->i_sb;
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct fs_info_t *p_fs = &(sbi->fs_info);
-+	struct bd_info_t *p_bd = &(sbi->bd_info);
-+	const unsigned long blocksize = sb->s_blocksize;
-+	const unsigned char blocksize_bits = sb->s_blocksize_bits;
-+	sector_t last_block;
-+	int err, clu_offset, sec_offset;
-+	unsigned int cluster;
-+
-+	*phys = 0;
-+	*mapped_blocks = 0;
-+
-+	if ((p_fs->vol_type == FAT12) || (p_fs->vol_type == FAT16)) {
-+		if (inode->i_ino == EXFAT_ROOT_INO) {
-+			if (sector <
-+			    (p_fs->dentries_in_root >>
-+			     (p_bd->sector_size_bits-DENTRY_SIZE_BITS))) {
-+				*phys = sector + p_fs->root_start_sector;
-+				*mapped_blocks = 1;
-+			}
-+			return 0;
-+		}
-+	}
-+
-+	last_block = (i_size_read(inode) + (blocksize - 1)) >> blocksize_bits;
-+	if (sector >= last_block) {
-+		if (*create == 0)
-+			return 0;
-+	} else {
-+		*create = 0;
-+	}
-+
-+	/* cluster offset */
-+	clu_offset = sector >> p_fs->sectors_per_clu_bits;
-+
-+	/* sector offset in cluster */
-+	sec_offset = sector & (p_fs->sectors_per_clu - 1);
-+
-+	EXFAT_I(inode)->fid.size = i_size_read(inode);
-+
-+	err = ffsMapCluster(inode, clu_offset, &cluster);
-+
-+	if (err) {
-+		if (err == FFS_FULL)
-+			return -ENOSPC;
-+		else
-+			return -EIO;
-+	} else if (cluster != CLUSTER_32(~0)) {
-+		*phys = START_SECTOR(cluster) + sec_offset;
-+		*mapped_blocks = p_fs->sectors_per_clu - sec_offset;
-+	}
-+
-+	return 0;
-+}
-+
-+static int exfat_get_block(struct inode *inode, sector_t iblock,
-+			   struct buffer_head *bh_result, int create)
-+{
-+	struct super_block *sb = inode->i_sb;
-+	unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
-+	int err;
-+	unsigned long mapped_blocks;
-+	sector_t phys;
-+
-+	__lock_super(sb);
-+
-+	err = exfat_bmap(inode, iblock, &phys, &mapped_blocks, &create);
-+	if (err) {
-+		__unlock_super(sb);
-+		return err;
-+	}
-+
-+	if (phys) {
-+		max_blocks = min(mapped_blocks, max_blocks);
-+		if (create) {
-+			EXFAT_I(inode)->mmu_private += max_blocks <<
-+							sb->s_blocksize_bits;
-+			set_buffer_new(bh_result);
-+		}
-+		map_bh(bh_result, sb, phys);
-+	}
-+
-+	bh_result->b_size = max_blocks << sb->s_blocksize_bits;
-+	__unlock_super(sb);
-+
-+	return 0;
-+}
-+
-+static int exfat_readpage(struct file *file, struct page *page)
-+{
-+	return  mpage_readpage(page, exfat_get_block);
-+}
-+
-+static int exfat_readpages(struct file *file, struct address_space *mapping,
-+			   struct list_head *pages, unsigned int nr_pages)
-+{
-+	return  mpage_readpages(mapping, pages, nr_pages, exfat_get_block);
-+}
-+
-+static int exfat_writepage(struct page *page, struct writeback_control *wbc)
-+{
-+	return block_write_full_page(page, exfat_get_block, wbc);
-+}
-+
-+static int exfat_writepages(struct address_space *mapping,
-+			    struct writeback_control *wbc)
-+{
-+	return mpage_writepages(mapping, wbc, exfat_get_block);
-+}
-+
-+static void exfat_write_failed(struct address_space *mapping, loff_t to)
-+{
-+	struct inode *inode = mapping->host;
-+
-+	if (to > i_size_read(inode)) {
-+		truncate_pagecache(inode, i_size_read(inode));
-+		EXFAT_I(inode)->fid.size = i_size_read(inode);
-+		exfat_truncate(inode, i_size_read(inode));
-+	}
-+}
-+
-+static int exfat_write_begin(struct file *file, struct address_space *mapping,
-+			     loff_t pos, unsigned int len, unsigned int flags,
-+			     struct page **pagep, void **fsdata)
-+{
-+	int ret;
-+
-+	*pagep = NULL;
-+	ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
-+			       exfat_get_block,
-+			       &EXFAT_I(mapping->host)->mmu_private);
-+
-+	if (ret < 0)
-+		exfat_write_failed(mapping, pos+len);
-+	return ret;
-+}
-+
-+static int exfat_write_end(struct file *file, struct address_space *mapping,
-+			   loff_t pos, unsigned int len, unsigned int copied,
-+			   struct page *pagep, void *fsdata)
-+{
-+	struct inode *inode = mapping->host;
-+	struct file_id_t *fid = &(EXFAT_I(inode)->fid);
-+	int err;
-+
-+	err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);
-+
-+	if (err < len)
-+		exfat_write_failed(mapping, pos+len);
-+
-+	if (!(err < 0) && !(fid->attr & ATTR_ARCHIVE)) {
-+		inode->i_mtime = inode->i_ctime = current_time(inode);
-+		fid->attr |= ATTR_ARCHIVE;
-+		mark_inode_dirty(inode);
-+	}
-+	return err;
-+}
-+
-+static ssize_t exfat_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
-+{
-+	struct inode *inode = iocb->ki_filp->f_mapping->host;
-+	struct address_space *mapping = iocb->ki_filp->f_mapping;
-+	ssize_t ret;
-+	int rw;
-+
-+	rw = iov_iter_rw(iter);
-+
-+	if (rw == WRITE) {
-+		if (EXFAT_I(inode)->mmu_private < iov_iter_count(iter))
-+			return 0;
-+	}
-+	ret = blockdev_direct_IO(iocb, inode, iter, exfat_get_block);
-+
-+	if ((ret < 0) && (rw & WRITE))
-+		exfat_write_failed(mapping, iov_iter_count(iter));
-+	return ret;
-+}
-+
-+static sector_t _exfat_bmap(struct address_space *mapping, sector_t block)
-+{
-+	sector_t blocknr;
-+
-+	/* exfat_get_cluster() assumes the requested blocknr isn't truncated. */
-+	down_read(&EXFAT_I(mapping->host)->truncate_lock);
-+	blocknr = generic_block_bmap(mapping, block, exfat_get_block);
-+	up_read(&EXFAT_I(mapping->host)->truncate_lock);
-+
-+	return blocknr;
-+}
-+
-+static const struct address_space_operations exfat_aops = {
-+	.readpage    = exfat_readpage,
-+	.readpages   = exfat_readpages,
-+	.writepage   = exfat_writepage,
-+	.writepages  = exfat_writepages,
-+	.write_begin = exfat_write_begin,
-+	.write_end   = exfat_write_end,
-+	.direct_IO   = exfat_direct_IO,
-+	.bmap        = _exfat_bmap
-+};
-+
-+/*======================================================================*/
-+/*  Super Operations                                                    */
-+/*======================================================================*/
-+
-+static struct inode *exfat_iget(struct super_block *sb, loff_t i_pos)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct exfat_inode_info *info;
-+	struct hlist_head *head = sbi->inode_hashtable + exfat_hash(i_pos);
-+	struct inode *inode = NULL;
-+
-+	spin_lock(&sbi->inode_hash_lock);
-+	hlist_for_each_entry(info, head, i_hash_fat) {
-+		BUG_ON(info->vfs_inode.i_sb != sb);
-+
-+		if (i_pos != info->i_pos)
-+			continue;
-+		inode = igrab(&info->vfs_inode);
-+		if (inode)
-+			break;
-+	}
-+	spin_unlock(&sbi->inode_hash_lock);
-+	return inode;
-+}
-+
-+/* doesn't deal with root inode */
-+static int exfat_fill_inode(struct inode *inode, struct file_id_t *fid)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(inode->i_sb);
-+	struct fs_info_t *p_fs = &(sbi->fs_info);
-+	struct dir_entry_t info;
-+
-+	memcpy(&(EXFAT_I(inode)->fid), fid, sizeof(struct file_id_t));
-+
-+	ffsReadStat(inode, &info);
-+
-+	EXFAT_I(inode)->i_pos = 0;
-+	EXFAT_I(inode)->target = NULL;
-+	inode->i_uid = sbi->options.fs_uid;
-+	inode->i_gid = sbi->options.fs_gid;
-+	INC_IVERSION(inode);
-+	inode->i_generation = get_seconds();
-+
-+	if (info.Attr & ATTR_SUBDIR) { /* directory */
-+		inode->i_generation &= ~1;
-+		inode->i_mode = exfat_make_mode(sbi, info.Attr, 0777);
-+		inode->i_op = &exfat_dir_inode_operations;
-+		inode->i_fop = &exfat_dir_operations;
-+
-+		i_size_write(inode, info.Size);
-+		EXFAT_I(inode)->mmu_private = i_size_read(inode);
-+		set_nlink(inode, info.NumSubdirs);
-+	} else if (info.Attr & ATTR_SYMLINK) { /* symbolic link */
-+		inode->i_generation |= 1;
-+		inode->i_mode = exfat_make_mode(sbi, info.Attr, 0777);
-+		inode->i_op = &exfat_symlink_inode_operations;
-+
-+		i_size_write(inode, info.Size);
-+		EXFAT_I(inode)->mmu_private = i_size_read(inode);
-+	} else { /* regular file */
-+		inode->i_generation |= 1;
-+		inode->i_mode = exfat_make_mode(sbi, info.Attr, 0777);
-+		inode->i_op = &exfat_file_inode_operations;
-+		inode->i_fop = &exfat_file_operations;
-+		inode->i_mapping->a_ops = &exfat_aops;
-+		inode->i_mapping->nrpages = 0;
-+
-+		i_size_write(inode, info.Size);
-+		EXFAT_I(inode)->mmu_private = i_size_read(inode);
-+	}
-+	exfat_save_attr(inode, info.Attr);
-+
-+	inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1))
-+				& ~((loff_t)p_fs->cluster_size - 1)) >> 9;
-+
-+	exfat_time_fat2unix(sbi, &inode->i_mtime, &info.ModifyTimestamp);
-+	exfat_time_fat2unix(sbi, &inode->i_ctime, &info.CreateTimestamp);
-+	exfat_time_fat2unix(sbi, &inode->i_atime, &info.AccessTimestamp);
-+
-+	return 0;
-+}
-+
-+static struct inode *exfat_build_inode(struct super_block *sb,
-+				       struct file_id_t *fid, loff_t i_pos)
-+{
-+	struct inode *inode;
-+	int err;
-+
-+	inode = exfat_iget(sb, i_pos);
-+	if (inode)
-+		goto out;
-+	inode = new_inode(sb);
-+	if (!inode) {
-+		inode = ERR_PTR(-ENOMEM);
-+		goto out;
-+	}
-+	inode->i_ino = iunique(sb, EXFAT_ROOT_INO);
-+	SET_IVERSION(inode, 1);
-+	err = exfat_fill_inode(inode, fid);
-+	if (err) {
-+		iput(inode);
-+		inode = ERR_PTR(err);
-+		goto out;
-+	}
-+	exfat_attach(inode, i_pos);
-+	insert_inode_hash(inode);
-+out:
-+	return inode;
-+}
-+
-+static int exfat_sync_inode(struct inode *inode)
-+{
-+	return exfat_write_inode(inode, NULL);
-+}
-+
-+static struct inode *exfat_alloc_inode(struct super_block *sb)
-+{
-+	struct exfat_inode_info *ei;
-+
-+	ei = kmem_cache_alloc(exfat_inode_cachep, GFP_NOFS);
-+	if (!ei)
-+		return NULL;
-+
-+	init_rwsem(&ei->truncate_lock);
-+
-+	return &ei->vfs_inode;
-+}
-+
-+static void exfat_destroy_inode(struct inode *inode)
-+{
-+	if (EXFAT_I(inode)->target)
-+		kfree(EXFAT_I(inode)->target);
-+	EXFAT_I(inode)->target = NULL;
-+
-+	kmem_cache_free(exfat_inode_cachep, EXFAT_I(inode));
-+}
-+
-+static int exfat_write_inode(struct inode *inode, struct writeback_control *wbc)
-+{
-+	struct super_block *sb = inode->i_sb;
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct dir_entry_t info;
-+
-+	if (inode->i_ino == EXFAT_ROOT_INO)
-+		return 0;
-+
-+	info.Attr = exfat_make_attr(inode);
-+	info.Size = i_size_read(inode);
-+
-+	exfat_time_unix2fat(sbi, &inode->i_mtime, &info.ModifyTimestamp);
-+	exfat_time_unix2fat(sbi, &inode->i_ctime, &info.CreateTimestamp);
-+	exfat_time_unix2fat(sbi, &inode->i_atime, &info.AccessTimestamp);
-+
-+	ffsWriteStat(inode, &info);
-+
-+	return 0;
-+}
-+
-+static void exfat_evict_inode(struct inode *inode)
-+{
-+	truncate_inode_pages(&inode->i_data, 0);
-+
-+	if (!inode->i_nlink)
-+		i_size_write(inode, 0);
-+	invalidate_inode_buffers(inode);
-+	clear_inode(inode);
-+	exfat_detach(inode);
-+
-+	remove_inode_hash(inode);
-+}
-+
-+static void exfat_free_super(struct exfat_sb_info *sbi)
-+{
-+	if (sbi->nls_disk)
-+		unload_nls(sbi->nls_disk);
-+	if (sbi->nls_io)
-+		unload_nls(sbi->nls_io);
-+	if (sbi->options.iocharset != exfat_default_iocharset)
-+		kfree(sbi->options.iocharset);
-+	/* mutex_init is in exfat_fill_super function. only for 3.7+ */
-+	mutex_destroy(&sbi->s_lock);
-+	kfree(sbi);
-+}
-+
-+static void exfat_put_super(struct super_block *sb)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+
-+	if (__is_sb_dirty(sb))
-+		exfat_write_super(sb);
-+
-+	ffsUmountVol(sb);
-+
-+	sb->s_fs_info = NULL;
-+	exfat_free_super(sbi);
-+}
-+
-+static void exfat_write_super(struct super_block *sb)
-+{
-+	__lock_super(sb);
-+
-+	__set_sb_clean(sb);
-+
-+	if (!sb_rdonly(sb))
-+		ffsSyncVol(sb, true);
-+
-+	__unlock_super(sb);
-+}
-+
-+static int exfat_sync_fs(struct super_block *sb, int wait)
-+{
-+	int err = 0;
-+
-+	if (__is_sb_dirty(sb)) {
-+		__lock_super(sb);
-+		__set_sb_clean(sb);
-+		err = ffsSyncVol(sb, true);
-+		__unlock_super(sb);
-+	}
-+
-+	return err;
-+}
-+
-+static int exfat_statfs(struct dentry *dentry, struct kstatfs *buf)
-+{
-+	struct super_block *sb = dentry->d_sb;
-+	u64 id = huge_encode_dev(sb->s_bdev->bd_dev);
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+	struct vol_info_t info;
-+
-+	if (p_fs->used_clusters == (u32) ~0) {
-+		if (ffsGetVolInfo(sb, &info) == FFS_MEDIAERR)
-+			return -EIO;
-+
-+	} else {
-+		info.FatType = p_fs->vol_type;
-+		info.ClusterSize = p_fs->cluster_size;
-+		info.NumClusters = p_fs->num_clusters - 2;
-+		info.UsedClusters = p_fs->used_clusters;
-+		info.FreeClusters = info.NumClusters - info.UsedClusters;
-+
-+		if (p_fs->dev_ejected)
-+			pr_info("[EXFAT] statfs on device that is ejected\n");
-+	}
-+
-+	buf->f_type = sb->s_magic;
-+	buf->f_bsize = info.ClusterSize;
-+	buf->f_blocks = info.NumClusters;
-+	buf->f_bfree = info.FreeClusters;
-+	buf->f_bavail = info.FreeClusters;
-+	buf->f_fsid.val[0] = (u32)id;
-+	buf->f_fsid.val[1] = (u32)(id >> 32);
-+	buf->f_namelen = 260;
-+
-+	return 0;
-+}
-+
-+static int exfat_remount(struct super_block *sb, int *flags, char *data)
-+{
-+	*flags |= SB_NODIRATIME;
-+	return 0;
-+}
-+
-+static int exfat_show_options(struct seq_file *m, struct dentry *root)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(root->d_sb);
-+	struct exfat_mount_options *opts = &sbi->options;
-+
-+	if (__kuid_val(opts->fs_uid))
-+		seq_printf(m, ",uid=%u", __kuid_val(opts->fs_uid));
-+	if (__kgid_val(opts->fs_gid))
-+		seq_printf(m, ",gid=%u", __kgid_val(opts->fs_gid));
-+	seq_printf(m, ",fmask=%04o", opts->fs_fmask);
-+	seq_printf(m, ",dmask=%04o", opts->fs_dmask);
-+	if (opts->allow_utime)
-+		seq_printf(m, ",allow_utime=%04o", opts->allow_utime);
-+	if (sbi->nls_disk)
-+		seq_printf(m, ",codepage=%s", sbi->nls_disk->charset);
-+	if (sbi->nls_io)
-+		seq_printf(m, ",iocharset=%s", sbi->nls_io->charset);
-+	seq_printf(m, ",namecase=%u", opts->casesensitive);
-+	if (opts->errors == EXFAT_ERRORS_CONT)
-+		seq_puts(m, ",errors=continue");
-+	else if (opts->errors == EXFAT_ERRORS_PANIC)
-+		seq_puts(m, ",errors=panic");
-+	else
-+		seq_puts(m, ",errors=remount-ro");
-+#ifdef CONFIG_EXFAT_DISCARD
-+	if (opts->discard)
-+		seq_puts(m, ",discard");
-+#endif
-+	return 0;
-+}
-+
-+static const struct super_operations exfat_sops = {
-+	.alloc_inode   = exfat_alloc_inode,
-+	.destroy_inode = exfat_destroy_inode,
-+	.write_inode   = exfat_write_inode,
-+	.evict_inode  = exfat_evict_inode,
-+	.put_super     = exfat_put_super,
-+	.sync_fs       = exfat_sync_fs,
-+	.statfs        = exfat_statfs,
-+	.remount_fs    = exfat_remount,
-+	.show_options  = exfat_show_options,
-+};
-+
-+/*======================================================================*/
-+/*  Export Operations                                                   */
-+/*======================================================================*/
-+
-+static struct inode *exfat_nfs_get_inode(struct super_block *sb, u64 ino,
-+					 u32 generation)
-+{
-+	struct inode *inode = NULL;
-+
-+	if (ino < EXFAT_ROOT_INO)
-+		return inode;
-+	inode = ilookup(sb, ino);
-+
-+	if (inode && generation && (inode->i_generation != generation)) {
-+		iput(inode);
-+		inode = NULL;
-+	}
-+
-+	return inode;
-+}
-+
-+static struct dentry *exfat_fh_to_dentry(struct super_block *sb,
-+					 struct fid *fid, int fh_len,
-+					 int fh_type)
-+{
-+	return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
-+				exfat_nfs_get_inode);
-+}
-+
-+static struct dentry *exfat_fh_to_parent(struct super_block *sb,
-+					 struct fid *fid, int fh_len,
-+					 int fh_type)
-+{
-+	return generic_fh_to_parent(sb, fid, fh_len, fh_type,
-+				exfat_nfs_get_inode);
-+}
-+
-+static const struct export_operations exfat_export_ops = {
-+	.fh_to_dentry   = exfat_fh_to_dentry,
-+	.fh_to_parent   = exfat_fh_to_parent,
-+};
-+
-+/*======================================================================*/
-+/*  Super Block Read Operations                                         */
-+/*======================================================================*/
-+
-+enum {
-+	Opt_uid,
-+	Opt_gid,
-+	Opt_umask,
-+	Opt_dmask,
-+	Opt_fmask,
-+	Opt_allow_utime,
-+	Opt_codepage,
-+	Opt_charset,
-+	Opt_namecase,
-+	Opt_debug,
-+	Opt_err_cont,
-+	Opt_err_panic,
-+	Opt_err_ro,
-+	Opt_utf8_hack,
-+	Opt_err,
-+#ifdef CONFIG_EXFAT_DISCARD
-+	Opt_discard,
-+#endif /* EXFAT_CONFIG_DISCARD */
-+};
-+
-+static const match_table_t exfat_tokens = {
-+	{Opt_uid, "uid=%u"},
-+	{Opt_gid, "gid=%u"},
-+	{Opt_umask, "umask=%o"},
-+	{Opt_dmask, "dmask=%o"},
-+	{Opt_fmask, "fmask=%o"},
-+	{Opt_allow_utime, "allow_utime=%o"},
-+	{Opt_codepage, "codepage=%u"},
-+	{Opt_charset, "iocharset=%s"},
-+	{Opt_namecase, "namecase=%u"},
-+	{Opt_debug, "debug"},
-+	{Opt_err_cont, "errors=continue"},
-+	{Opt_err_panic, "errors=panic"},
-+	{Opt_err_ro, "errors=remount-ro"},
-+	{Opt_utf8_hack, "utf8"},
-+#ifdef CONFIG_EXFAT_DISCARD
-+	{Opt_discard, "discard"},
-+#endif /* CONFIG_EXFAT_DISCARD */
-+	{Opt_err, NULL}
-+};
-+
-+static int parse_options(char *options, int silent, int *debug,
-+			 struct exfat_mount_options *opts)
-+{
-+	char *p;
-+	substring_t args[MAX_OPT_ARGS];
-+	int option;
-+	char *iocharset;
-+
-+	opts->fs_uid = current_uid();
-+	opts->fs_gid = current_gid();
-+	opts->fs_fmask = opts->fs_dmask = current->fs->umask;
-+	opts->allow_utime = (unsigned short) -1;
-+	opts->codepage = exfat_default_codepage;
-+	opts->iocharset = exfat_default_iocharset;
-+	opts->casesensitive = 0;
-+	opts->errors = EXFAT_ERRORS_RO;
-+#ifdef CONFIG_EXFAT_DISCARD
-+	opts->discard = 0;
-+#endif
-+	*debug = 0;
-+
-+	if (!options)
-+		goto out;
-+
-+	while ((p = strsep(&options, ",")) != NULL) {
-+		int token;
-+
-+		if (!*p)
-+			continue;
-+
-+		token = match_token(p, exfat_tokens, args);
-+		switch (token) {
-+		case Opt_uid:
-+			if (match_int(&args[0], &option))
-+				return 0;
-+			opts->fs_uid = KUIDT_INIT(option);
-+			break;
-+		case Opt_gid:
-+			if (match_int(&args[0], &option))
-+				return 0;
-+			opts->fs_gid = KGIDT_INIT(option);
-+			break;
-+		case Opt_umask:
-+		case Opt_dmask:
-+		case Opt_fmask:
-+			if (match_octal(&args[0], &option))
-+				return 0;
-+			if (token != Opt_dmask)
-+				opts->fs_fmask = option;
-+			if (token != Opt_fmask)
-+				opts->fs_dmask = option;
-+			break;
-+		case Opt_allow_utime:
-+			if (match_octal(&args[0], &option))
-+				return 0;
-+			opts->allow_utime = option & 0022;
-+			break;
-+		case Opt_codepage:
-+			if (match_int(&args[0], &option))
-+				return 0;
-+			opts->codepage = option;
-+			break;
-+		case Opt_charset:
-+			if (opts->iocharset != exfat_default_iocharset)
-+				kfree(opts->iocharset);
-+			iocharset = match_strdup(&args[0]);
-+			if (!iocharset)
-+				return -ENOMEM;
-+			opts->iocharset = iocharset;
-+			break;
-+		case Opt_namecase:
-+			if (match_int(&args[0], &option))
-+				return 0;
-+			opts->casesensitive = option;
-+			break;
-+		case Opt_err_cont:
-+			opts->errors = EXFAT_ERRORS_CONT;
-+			break;
-+		case Opt_err_panic:
-+			opts->errors = EXFAT_ERRORS_PANIC;
-+			break;
-+		case Opt_err_ro:
-+			opts->errors = EXFAT_ERRORS_RO;
-+			break;
-+		case Opt_debug:
-+			*debug = 1;
-+			break;
-+#ifdef CONFIG_EXFAT_DISCARD
-+		case Opt_discard:
-+			opts->discard = 1;
-+			break;
-+#endif /* CONFIG_EXFAT_DISCARD */
-+		case Opt_utf8_hack:
-+			break;
-+		default:
-+			if (!silent)
-+				pr_err("[EXFAT] Unrecognized mount option %s or missing value\n",
-+				       p);
-+			return -EINVAL;
-+		}
-+	}
-+
-+out:
-+	if (opts->allow_utime == (unsigned short) -1)
-+		opts->allow_utime = ~opts->fs_dmask & 0022;
-+
-+	return 0;
-+}
-+
-+static void exfat_hash_init(struct super_block *sb)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	int i;
-+
-+	spin_lock_init(&sbi->inode_hash_lock);
-+	for (i = 0; i < EXFAT_HASH_SIZE; i++)
-+		INIT_HLIST_HEAD(&sbi->inode_hashtable[i]);
-+}
-+
-+static int exfat_read_root(struct inode *inode)
-+{
-+	struct super_block *sb = inode->i_sb;
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct fs_info_t *p_fs = &(sbi->fs_info);
-+	struct dir_entry_t info;
-+
-+	EXFAT_I(inode)->fid.dir.dir = p_fs->root_dir;
-+	EXFAT_I(inode)->fid.dir.flags = 0x01;
-+	EXFAT_I(inode)->fid.entry = -1;
-+	EXFAT_I(inode)->fid.start_clu = p_fs->root_dir;
-+	EXFAT_I(inode)->fid.flags = 0x01;
-+	EXFAT_I(inode)->fid.type = TYPE_DIR;
-+	EXFAT_I(inode)->fid.rwoffset = 0;
-+	EXFAT_I(inode)->fid.hint_last_off = -1;
-+
-+	EXFAT_I(inode)->target = NULL;
-+
-+	ffsReadStat(inode, &info);
-+
-+	inode->i_uid = sbi->options.fs_uid;
-+	inode->i_gid = sbi->options.fs_gid;
-+	INC_IVERSION(inode);
-+	inode->i_generation = 0;
-+	inode->i_mode = exfat_make_mode(sbi, ATTR_SUBDIR, 0777);
-+	inode->i_op = &exfat_dir_inode_operations;
-+	inode->i_fop = &exfat_dir_operations;
-+
-+	i_size_write(inode, info.Size);
-+	inode->i_blocks = ((i_size_read(inode) + (p_fs->cluster_size - 1))
-+				& ~((loff_t)p_fs->cluster_size - 1)) >> 9;
-+	EXFAT_I(inode)->i_pos = ((loff_t) p_fs->root_dir << 32) | 0xffffffff;
-+	EXFAT_I(inode)->mmu_private = i_size_read(inode);
-+
-+	exfat_save_attr(inode, ATTR_SUBDIR);
-+	inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
-+	set_nlink(inode, info.NumSubdirs + 2);
-+
-+	return 0;
-+}
-+
-+static void setup_dops(struct super_block *sb)
-+{
-+	if (EXFAT_SB(sb)->options.casesensitive == 0)
-+		sb->s_d_op = &exfat_ci_dentry_ops;
-+	else
-+		sb->s_d_op = &exfat_dentry_ops;
-+}
-+
-+static int exfat_fill_super(struct super_block *sb, void *data, int silent)
-+{
-+	struct inode *root_inode = NULL;
-+	struct exfat_sb_info *sbi;
-+	int debug, ret;
-+	long error;
-+	char buf[50];
-+
-+	/*
-+	 * GFP_KERNEL is ok here, because while we do hold the
-+	 * supeblock lock, memory pressure can't call back into
-+	 * the filesystem, since we're only just about to mount
-+	 * it and have no inodes etc active!
-+	 */
-+	sbi = kzalloc(sizeof(struct exfat_sb_info), GFP_KERNEL);
-+	if (!sbi)
-+		return -ENOMEM;
-+	mutex_init(&sbi->s_lock);
-+	sb->s_fs_info = sbi;
-+	sb->s_flags |= SB_NODIRATIME;
-+	sb->s_magic = EXFAT_SUPER_MAGIC;
-+	sb->s_op = &exfat_sops;
-+	sb->s_export_op = &exfat_export_ops;
-+
-+	error = parse_options(data, silent, &debug, &sbi->options);
-+	if (error)
-+		goto out_fail;
-+
-+	setup_dops(sb);
-+
-+	error = -EIO;
-+	sb_min_blocksize(sb, 512);
-+	sb->s_maxbytes = 0x7fffffffffffffffLL;    /* maximum file size */
-+
-+	ret = ffsMountVol(sb);
-+	if (ret) {
-+		if (!silent)
-+			pr_err("[EXFAT] ffsMountVol failed\n");
-+
-+		goto out_fail;
-+	}
-+
-+	/* set up enough so that it can read an inode */
-+	exfat_hash_init(sb);
-+
-+	/*
-+	 * The low byte of FAT's first entry must have same value with
-+	 * media-field.  But in real world, too many devices is
-+	 * writing wrong value.  So, removed that validity check.
-+	 *
-+	 * if (FAT_FIRST_ENT(sb, media) != first)
-+	 */
-+
-+	/* codepage is not meaningful in exfat */
-+	if (sbi->fs_info.vol_type != EXFAT) {
-+		error = -EINVAL;
-+		sprintf(buf, "cp%d", sbi->options.codepage);
-+		sbi->nls_disk = load_nls(buf);
-+		if (!sbi->nls_disk) {
-+			pr_err("[EXFAT] Codepage %s not found\n", buf);
-+			goto out_fail2;
-+		}
-+	}
-+
-+	sbi->nls_io = load_nls(sbi->options.iocharset);
-+
-+	error = -ENOMEM;
-+	root_inode = new_inode(sb);
-+	if (!root_inode)
-+		goto out_fail2;
-+	root_inode->i_ino = EXFAT_ROOT_INO;
-+	SET_IVERSION(root_inode, 1);
-+
-+	error = exfat_read_root(root_inode);
-+	if (error < 0)
-+		goto out_fail2;
-+	error = -ENOMEM;
-+	exfat_attach(root_inode, EXFAT_I(root_inode)->i_pos);
-+	insert_inode_hash(root_inode);
-+	sb->s_root = d_make_root(root_inode);
-+	if (!sb->s_root) {
-+		pr_err("[EXFAT] Getting the root inode failed\n");
-+		goto out_fail2;
-+	}
-+
-+	return 0;
-+
-+out_fail2:
-+	ffsUmountVol(sb);
-+out_fail:
-+	if (root_inode)
-+		iput(root_inode);
-+	sb->s_fs_info = NULL;
-+	exfat_free_super(sbi);
-+	return error;
-+}
-+
-+static struct dentry *exfat_fs_mount(struct file_system_type *fs_type,
-+				     int flags, const char *dev_name,
-+				     void *data)
-+{
-+	return mount_bdev(fs_type, flags, dev_name, data, exfat_fill_super);
-+}
-+
-+static void init_once(void *foo)
-+{
-+	struct exfat_inode_info *ei = (struct exfat_inode_info *)foo;
-+
-+	INIT_HLIST_NODE(&ei->i_hash_fat);
-+	inode_init_once(&ei->vfs_inode);
-+}
-+
-+static int __init exfat_init_inodecache(void)
-+{
-+	exfat_inode_cachep = kmem_cache_create("exfat_inode_cache",
-+					       sizeof(struct exfat_inode_info),
-+					       0,
-+					       (SLAB_RECLAIM_ACCOUNT |
-+						SLAB_MEM_SPREAD),
-+					       init_once);
-+	if (exfat_inode_cachep == NULL)
-+		return -ENOMEM;
-+	return 0;
-+}
-+
-+static void __exit exfat_destroy_inodecache(void)
-+{
-+	/*
-+	 * Make sure all delayed rcu free inodes are flushed before we
-+	 * destroy cache.
-+	 */
-+	rcu_barrier();
-+	kmem_cache_destroy(exfat_inode_cachep);
-+}
-+
-+#ifdef CONFIG_EXFAT_KERNEL_DEBUG
-+static void exfat_debug_kill_sb(struct super_block *sb)
-+{
-+	struct exfat_sb_info *sbi = EXFAT_SB(sb);
-+	struct block_device *bdev = sb->s_bdev;
-+	struct fs_info_t *p_fs = &(EXFAT_SB(sb)->fs_info);
-+
-+	long flags;
-+
-+	if (sbi) {
-+		flags = sbi->debug_flags;
-+
-+		if (flags & EXFAT_DEBUGFLAGS_INVALID_UMOUNT) {
-+			/*
-+			 * invalidate_bdev drops all device cache include
-+			 * dirty. We use this to simulate device removal.
-+			 */
-+			down(&p_fs->v_sem);
-+			FAT_release_all(sb);
-+			buf_release_all(sb);
-+			up(&p_fs->v_sem);
-+
-+			invalidate_bdev(bdev);
-+		}
-+	}
-+
-+	kill_block_super(sb);
-+}
-+#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
-+
-+static struct file_system_type exfat_fs_type = {
-+	.owner       = THIS_MODULE,
-+	.name        = "exfat",
-+	.mount       = exfat_fs_mount,
-+#ifdef CONFIG_EXFAT_KERNEL_DEBUG
-+	.kill_sb    = exfat_debug_kill_sb,
-+#else
-+	.kill_sb    = kill_block_super,
-+#endif /* CONFIG_EXFAT_KERNEL_DEBUG */
-+	.fs_flags    = FS_REQUIRES_DEV,
-+};
-+
-+static int __init init_exfat(void)
-+{
-+	int err;
-+
-+	BUILD_BUG_ON(sizeof(struct dentry_t) != DENTRY_SIZE);
-+	BUILD_BUG_ON(sizeof(struct dos_dentry_t) != DENTRY_SIZE);
-+	BUILD_BUG_ON(sizeof(struct ext_dentry_t) != DENTRY_SIZE);
-+	BUILD_BUG_ON(sizeof(struct file_dentry_t) != DENTRY_SIZE);
-+	BUILD_BUG_ON(sizeof(struct strm_dentry_t) != DENTRY_SIZE);
-+	BUILD_BUG_ON(sizeof(struct name_dentry_t) != DENTRY_SIZE);
-+	BUILD_BUG_ON(sizeof(struct bmap_dentry_t) != DENTRY_SIZE);
-+	BUILD_BUG_ON(sizeof(struct case_dentry_t) != DENTRY_SIZE);
-+	BUILD_BUG_ON(sizeof(struct volm_dentry_t) != DENTRY_SIZE);
-+
-+	pr_info("exFAT: Version %s\n", EXFAT_VERSION);
-+
-+	err = exfat_init_inodecache();
-+	if (err)
-+		return err;
-+
-+	err = register_filesystem(&exfat_fs_type);
-+	if (err)
-+		return err;
-+
-+	return 0;
-+}
-+
-+static void __exit exit_exfat(void)
-+{
-+	exfat_destroy_inodecache();
-+	unregister_filesystem(&exfat_fs_type);
-+}
-+
-+module_init(init_exfat);
-+module_exit(exit_exfat);
-+
-+MODULE_LICENSE("GPL");
-+MODULE_DESCRIPTION("exFAT Filesystem Driver");
-+MODULE_ALIAS_FS("exfat");
-diff --git a/drivers/staging/exfat/exfat_upcase.c b/drivers/staging/exfat/exfat_upcase.c
-new file mode 100644
-index 000000000000..366082fb3dab
---- /dev/null
-+++ b/drivers/staging/exfat/exfat_upcase.c
-@@ -0,0 +1,740 @@
-+// SPDX-License-Identifier: GPL-2.0
-+/*
-+ *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
-+ */
-+
-+#include <linux/types.h>
-+#include "exfat.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
-+};
--- 
-cgit 1.2-0.3.lf.el7
-
diff --git a/patches/drivers/ti/gpio/0002-hack-gpiolib-yes-we-have-drivers-stomping-on-each-ot.patch b/patches/drivers/ti/gpio/0002-hack-gpiolib-yes-we-have-drivers-stomping-on-each-ot.patch
index 983027d0695d8cd0c46d3f75c14eb379535c3f0c..7cf8ca1ebff4e8f2c7e7fa930bfd27ff52646256 100644
--- a/patches/drivers/ti/gpio/0002-hack-gpiolib-yes-we-have-drivers-stomping-on-each-ot.patch
+++ b/patches/drivers/ti/gpio/0002-hack-gpiolib-yes-we-have-drivers-stomping-on-each-ot.patch
@@ -10,24 +10,24 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
  1 file changed, 4 insertions(+), 4 deletions(-)
 
 diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
-index bca3e7740ef6..71a8af876b4f 100644
+index bdbc1649eafa..4bf866d74e37 100644
 --- a/drivers/gpio/gpiolib.c
 +++ b/drivers/gpio/gpiolib.c
-@@ -2332,10 +2332,10 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
+@@ -2650,10 +2650,10 @@ static int gpiod_request_commit(struct gpio_desc *desc, const char *label)
  	if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
  		desc_set_label(desc, label ? : "?");
- 		status = 0;
+ 		ret = 0;
 -	} else {
 -		kfree_const(label);
--		status = -EBUSY;
+-		ret = -EBUSY;
 -		goto done;
 +//	} else {
 +//		kfree_const(label);
-+//		status = -EBUSY;
++//		ret = -EBUSY;
 +//		goto done;
  	}
  
  	if (chip->request) {
 -- 
-2.20.1
+2.23.0
 
diff --git a/patches/fixes/0001-ARM-don-t-export-unused-return_address.patch b/patches/fixes/0001-ARM-don-t-export-unused-return_address.patch
new file mode 100644
index 0000000000000000000000000000000000000000..3db46d0d31bdbea070bda954a182bab692abeb20
--- /dev/null
+++ b/patches/fixes/0001-ARM-don-t-export-unused-return_address.patch
@@ -0,0 +1,33 @@
+From 8129c011ecdb5287325dfc97a81087134e83dcbe Mon Sep 17 00:00:00 2001
+From: Arnd Bergmann <arnd@arndb.de>
+Date: Fri, 6 Sep 2019 17:46:55 +0200
+Subject: [PATCH] ARM: don't export unused return_address()
+
+Without the frame pointer enabled, return_address() is an inline
+function and does not need to be exported, as shown by this warning:
+
+WARNING: "return_address" [vmlinux] is a static EXPORT_SYMBOL_GPL
+
+Move the EXPORT_SYMBOL_GPL() into the #ifdef as well.
+
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+---
+ arch/arm/kernel/return_address.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/arch/arm/kernel/return_address.c b/arch/arm/kernel/return_address.c
+index b0d2f1fe891d..fb0fc1910102 100644
+--- a/arch/arm/kernel/return_address.c
++++ b/arch/arm/kernel/return_address.c
+@@ -53,6 +53,7 @@ void *return_address(unsigned int level)
+ 		return NULL;
+ }
+ 
++EXPORT_SYMBOL_GPL(return_address);
++
+ #endif /* if defined(CONFIG_FRAME_POINTER) && !defined(CONFIG_ARM_UNWIND) */
+ 
+-EXPORT_SYMBOL_GPL(return_address);
+-- 
+2.23.0
+
diff --git a/patches/ref_omap2plus_defconfig b/patches/ref_omap2plus_defconfig
index 9aaf84a0f82d9e1fdb70665ee10509222f6be6c1..d8580dbb610de413851670e36e1d075528effed5 100644
--- a/patches/ref_omap2plus_defconfig
+++ b/patches/ref_omap2plus_defconfig
@@ -1,6 +1,6 @@
 #
 # Automatically generated file; DO NOT EDIT.
-# Linux/arm 5.3.2 Kernel Configuration
+# Linux/arm 5.4.0-rc1 Kernel Configuration
 #
 
 #
@@ -11,6 +11,7 @@ CONFIG_GCC_VERSION=80300
 CONFIG_CLANG_VERSION=0
 CONFIG_CC_CAN_LINK=y
 CONFIG_CC_HAS_ASM_GOTO=y
+CONFIG_CC_HAS_ASM_INLINE=y
 CONFIG_CC_HAS_WARN_MAYBE_UNINITIALIZED=y
 CONFIG_IRQ_WORK=y
 CONFIG_BUILDTIME_EXTABLE_SORT=y
@@ -256,19 +257,13 @@ CONFIG_ARCH_MULTIPLATFORM=y
 # CONFIG_ARCH_EBSA110 is not set
 # CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_IOP13XX is not set
 # CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_DOVE is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCH_LPC32XX is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
 # CONFIG_ARCH_SA1100 is not set
 # CONFIG_ARCH_S3C24XX is not set
-# CONFIG_ARCH_DAVINCI is not set
 # CONFIG_ARCH_OMAP1 is not set
 
 #
@@ -642,8 +637,6 @@ CONFIG_ARCH_HIBERNATION_POSSIBLE=y
 #
 # Firmware Drivers
 #
-# CONFIG_ARM_SCMI_PROTOCOL is not set
-# CONFIG_ARM_SCPI_PROTOCOL is not set
 # CONFIG_FIRMWARE_MEMMAP is not set
 # CONFIG_FW_CFG_SYSFS is not set
 # CONFIG_TRUSTED_FOUNDATIONS is not set
@@ -723,6 +716,7 @@ CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
 CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
 CONFIG_HAVE_EXIT_THREAD=y
 CONFIG_ARCH_MMAP_RND_BITS=8
+CONFIG_ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT=y
 CONFIG_CLONE_BACKWARDS=y
 CONFIG_OLD_SIGSUSPEND3=y
 CONFIG_OLD_SIGACTION=y
@@ -769,6 +763,8 @@ CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_MODULE_SIG is not set
 # CONFIG_MODULE_COMPRESS is not set
+# CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
 # CONFIG_TRIM_UNUSED_KSYMS is not set
 CONFIG_MODULES_TREE_LOOKUP=y
 CONFIG_BLOCK=y
@@ -781,6 +777,7 @@ CONFIG_BLK_SCSI_REQUEST=y
 # CONFIG_BLK_CMDLINE_PARSER is not set
 # CONFIG_BLK_WBT is not set
 # CONFIG_BLK_CGROUP_IOLATENCY is not set
+# CONFIG_BLK_CGROUP_IOCOST is not set
 CONFIG_BLK_DEBUG_FS=y
 # CONFIG_BLK_SED_OPAL is not set
 
@@ -810,7 +807,6 @@ CONFIG_EFI_PARTITION=y
 # end of Partition Types
 
 CONFIG_BLK_MQ_PCI=y
-CONFIG_BLK_MQ_VIRTIO=y
 CONFIG_BLK_PM=y
 
 #
@@ -1051,6 +1047,7 @@ CONFIG_CAN=m
 CONFIG_CAN_RAW=m
 CONFIG_CAN_BCM=m
 CONFIG_CAN_GW=m
+# CONFIG_CAN_J1939 is not set
 CONFIG_CAN_ISOTP=m
 
 #
@@ -1063,6 +1060,7 @@ CONFIG_CAN_DEV=m
 CONFIG_CAN_CALC_BITTIMING=y
 # CONFIG_CAN_FLEXCAN is not set
 # CONFIG_CAN_GRCAN is not set
+# CONFIG_CAN_KVASER_PCIEFD is not set
 # CONFIG_CAN_TI_HECC is not set
 CONFIG_CAN_C_CAN=m
 CONFIG_CAN_C_CAN_PLATFORM=m
@@ -1246,6 +1244,7 @@ CONFIG_PCI_DRA7XX_EP=y
 # CONFIG_PCIE_DW_PLAT_HOST is not set
 # CONFIG_PCIE_DW_PLAT_EP is not set
 # CONFIG_PCI_LAYERSCAPE is not set
+# CONFIG_PCI_LAYERSCAPE_EP is not set
 # CONFIG_PCI_MESON is not set
 # end of DesignWare PCI Core Support
 # end of PCI controller drivers
@@ -1308,6 +1307,7 @@ CONFIG_GENERIC_ARCH_TOPOLOGY=y
 # Bus devices
 #
 # CONFIG_BRCMSTB_GISB_ARB is not set
+# CONFIG_MOXTET is not set
 CONFIG_OMAP_INTERCONNECT=y
 CONFIG_OMAP_OCP2SCP=y
 # CONFIG_SIMPLE_PM_BUS is not set
@@ -1319,13 +1319,13 @@ CONFIG_CONNECTOR=m
 # CONFIG_GNSS is not set
 CONFIG_MTD=y
 # CONFIG_MTD_TESTS is not set
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_OF_PARTS=y
-# CONFIG_MTD_AR7_PARTS is not set
 
 #
 # Partition parsers
 #
+# CONFIG_MTD_AR7_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_OF_PARTS=y
 # CONFIG_MTD_AFS_PARTS is not set
 # CONFIG_MTD_REDBOOT_PARTS is not set
 # end of Partition parsers
@@ -1384,7 +1384,6 @@ CONFIG_MTD_PHYSMAP_OF=y
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_DATAFLASH is not set
-CONFIG_MTD_M25P80=m
 # CONFIG_MTD_MCHP23K256 is not set
 # CONFIG_MTD_SST25L is not set
 # CONFIG_MTD_SLRAM is not set
@@ -1420,6 +1419,7 @@ CONFIG_MTD_NAND_OMAP_BCH=y
 CONFIG_MTD_NAND_OMAP_BCH_BUILD=y
 # CONFIG_MTD_NAND_CAFE is not set
 # CONFIG_MTD_NAND_BRCMNAND is not set
+# CONFIG_MTD_NAND_MXIC is not set
 # CONFIG_MTD_NAND_GPIO is not set
 # CONFIG_MTD_NAND_PLATFORM is not set
 
@@ -1478,7 +1478,6 @@ CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
-# CONFIG_VIRTIO_BLK is not set
 # CONFIG_BLK_DEV_RBD is not set
 # CONFIG_BLK_DEV_RSXX is not set
 
@@ -1496,7 +1495,6 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
 # CONFIG_AD525X_DPOT is not set
 # CONFIG_DUMMY_IRQ is not set
 # CONFIG_PHANTOM is not set
-# CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
 # CONFIG_ICS932S401 is not set
 # CONFIG_ENCLOSURE_SERVICES is not set
@@ -1673,7 +1671,6 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_DEBUG is not set
 # CONFIG_SCSI_PMCRAID is not set
 # CONFIG_SCSI_PM8001 is not set
-# CONFIG_SCSI_VIRTIO is not set
 # CONFIG_SCSI_DH is not set
 # end of SCSI device support
 
@@ -1798,7 +1795,6 @@ CONFIG_NET_CORE=y
 # CONFIG_TUN is not set
 # CONFIG_TUN_VNET_CROSS_LE is not set
 # CONFIG_VETH is not set
-# CONFIG_VIRTIO_NET is not set
 # CONFIG_NLMON is not set
 # CONFIG_ARCNET is not set
 
@@ -1907,10 +1903,10 @@ CONFIG_NET_VENDOR_OKI=y
 CONFIG_NET_VENDOR_PACKET_ENGINES=y
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
+CONFIG_NET_VENDOR_PENSANDO=y
 CONFIG_NET_VENDOR_QLOGIC=y
 # CONFIG_QLA3XXX is not set
 # CONFIG_QLCNIC is not set
-# CONFIG_QLGE is not set
 # CONFIG_NETXEN_NIC is not set
 # CONFIG_QED is not set
 # CONFIG_NET_VENDOR_QUALCOMM is not set
@@ -1979,6 +1975,7 @@ CONFIG_SWPHY=y
 #
 # MII PHY device drivers
 #
+# CONFIG_ADIN_PHY is not set
 # CONFIG_AMD_PHY is not set
 # CONFIG_AQUANTIA_PHY is not set
 # CONFIG_AX88796B_PHY is not set
@@ -2338,7 +2335,6 @@ CONFIG_INPUT_PWM_VIBRA=m
 # CONFIG_INPUT_ADXL34X is not set
 # CONFIG_INPUT_IMS_PCU is not set
 # CONFIG_INPUT_CMA3000 is not set
-# CONFIG_INPUT_SOC_BUTTON_ARRAY is not set
 # CONFIG_INPUT_DRV260X_HAPTICS is not set
 # CONFIG_INPUT_DRV2665_HAPTICS is not set
 # CONFIG_INPUT_DRV2667_HAPTICS is not set
@@ -2408,7 +2404,6 @@ CONFIG_SERIAL_8250_FSL=y
 # CONFIG_SERIAL_8250_RT288X is not set
 CONFIG_SERIAL_8250_OMAP=y
 CONFIG_SERIAL_8250_OMAP_TTYO_FIXUP=y
-# CONFIG_SERIAL_8250_MOXA is not set
 CONFIG_SERIAL_OF_PLATFORM=y
 
 #
@@ -2434,6 +2429,7 @@ CONFIG_SERIAL_OMAP_CONSOLE=y
 # CONFIG_SERIAL_ARC is not set
 # CONFIG_SERIAL_RP2 is not set
 # CONFIG_SERIAL_FSL_LPUART is not set
+# CONFIG_SERIAL_FSL_LINFLEXUART is not set
 # CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
 # CONFIG_SERIAL_ST_ASC is not set
 # end of Serial drivers
@@ -2443,13 +2439,11 @@ CONFIG_SERIAL_DEV_BUS=y
 CONFIG_SERIAL_DEV_CTRL_TTYPORT=y
 # CONFIG_TTY_PRINTK is not set
 # CONFIG_HVC_DCC is not set
-# CONFIG_VIRTIO_CONSOLE is not set
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=m
 # CONFIG_HW_RANDOM_TIMERIOMEM is not set
 CONFIG_HW_RANDOM_OMAP=m
 CONFIG_HW_RANDOM_OMAP3_ROM=m
-# CONFIG_HW_RANDOM_VIRTIO is not set
 # CONFIG_APPLICOM is not set
 # CONFIG_RAW_DRIVER is not set
 # CONFIG_TCG_TPM is not set
@@ -2457,6 +2451,8 @@ CONFIG_DEVPORT=y
 # CONFIG_XILLYBUS is not set
 # end of Character devices
 
+# CONFIG_RANDOM_TRUST_BOOTLOADER is not set
+
 #
 # I2C support
 #
@@ -2712,6 +2708,7 @@ CONFIG_W1_CON=y
 # CONFIG_W1_MASTER_DS1WM is not set
 # CONFIG_W1_MASTER_GPIO is not set
 CONFIG_HDQ_MASTER_OMAP=m
+# CONFIG_W1_MASTER_SGI is not set
 # end of 1-wire Bus Masters
 
 #
@@ -2728,6 +2725,7 @@ CONFIG_HDQ_MASTER_OMAP=m
 # CONFIG_W1_SLAVE_DS2431 is not set
 # CONFIG_W1_SLAVE_DS2433 is not set
 # CONFIG_W1_SLAVE_DS2438 is not set
+# CONFIG_W1_SLAVE_DS250X is not set
 # CONFIG_W1_SLAVE_DS2780 is not set
 # CONFIG_W1_SLAVE_DS2781 is not set
 # CONFIG_W1_SLAVE_DS28E04 is not set
@@ -2808,6 +2806,7 @@ CONFIG_HWMON=m
 # CONFIG_SENSORS_ADT7462 is not set
 # CONFIG_SENSORS_ADT7470 is not set
 # CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_AS370 is not set
 # CONFIG_SENSORS_ASC7621 is not set
 # CONFIG_SENSORS_ASPEED is not set
 # CONFIG_SENSORS_ATXP1 is not set
@@ -2897,7 +2896,6 @@ CONFIG_SENSORS_LM75=m
 # CONFIG_SENSORS_STTS751 is not set
 # CONFIG_SENSORS_SMM665 is not set
 # CONFIG_SENSORS_ADC128D818 is not set
-# CONFIG_SENSORS_ADS1015 is not set
 # CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_ADS7871 is not set
 # CONFIG_SENSORS_AMC6821 is not set
@@ -3014,7 +3012,6 @@ CONFIG_MFD_CORE=y
 # CONFIG_MFD_BCM590XX is not set
 # CONFIG_MFD_BD9571MWV is not set
 # CONFIG_MFD_AXP20X_I2C is not set
-# CONFIG_MFD_CROS_EC is not set
 # CONFIG_MFD_MADERA is not set
 # CONFIG_MFD_ASIC3 is not set
 # CONFIG_PMIC_DA903X is not set
@@ -3158,6 +3155,7 @@ CONFIG_REGULATOR_PBIAS=y
 # CONFIG_REGULATOR_SLG51000 is not set
 CONFIG_REGULATOR_TI_ABB=y
 # CONFIG_REGULATOR_SY8106A is not set
+# CONFIG_REGULATOR_SY8824X is not set
 # CONFIG_REGULATOR_TPS51632 is not set
 CONFIG_REGULATOR_TPS62360=m
 CONFIG_REGULATOR_TPS65023=y
@@ -3210,6 +3208,7 @@ CONFIG_MEDIA_CONTROLLER=y
 CONFIG_VIDEO_DEV=m
 CONFIG_VIDEO_V4L2_SUBDEV_API=y
 CONFIG_VIDEO_V4L2=m
+CONFIG_VIDEO_V4L2_I2C=y
 # CONFIG_VIDEO_ADV_DEBUG is not set
 # CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
 CONFIG_V4L2_FWNODE=m
@@ -3339,6 +3338,7 @@ CONFIG_VIDEO_TVP5150=m
 # CONFIG_VIDEO_OV5647 is not set
 # CONFIG_VIDEO_OV6650 is not set
 # CONFIG_VIDEO_OV5670 is not set
+# CONFIG_VIDEO_OV5675 is not set
 # CONFIG_VIDEO_OV5695 is not set
 # CONFIG_VIDEO_OV7251 is not set
 # CONFIG_VIDEO_OV772X is not set
@@ -3510,18 +3510,11 @@ CONFIG_DRM_OMAP_ENCODER_TPD12S015=m
 CONFIG_DRM_OMAP_CONNECTOR_HDMI=m
 CONFIG_DRM_OMAP_CONNECTOR_ANALOG_TV=m
 CONFIG_DRM_OMAP_PANEL_DSI_CM=m
-CONFIG_DRM_OMAP_PANEL_SONY_ACX565AKM=m
-CONFIG_DRM_OMAP_PANEL_LGPHILIPS_LB035Q02=m
-CONFIG_DRM_OMAP_PANEL_SHARP_LS037V7DW01=m
-CONFIG_DRM_OMAP_PANEL_TPO_TD028TTEC1=m
-CONFIG_DRM_OMAP_PANEL_TPO_TD043MTEA1=m
-CONFIG_DRM_OMAP_PANEL_NEC_NL8048HL11=m
 # end of OMAPDRM External Display Device Drivers
 
 CONFIG_DRM_TILCDC=m
 # CONFIG_DRM_QXL is not set
 # CONFIG_DRM_BOCHS is not set
-# CONFIG_DRM_VIRTIO_GPU is not set
 # CONFIG_DRM_FSL_DCU is not set
 # CONFIG_DRM_STM is not set
 CONFIG_DRM_PANEL=y
@@ -3531,15 +3524,22 @@ CONFIG_DRM_PANEL=y
 #
 # CONFIG_DRM_PANEL_ARM_VERSATILE is not set
 # CONFIG_DRM_PANEL_LVDS is not set
-# CONFIG_DRM_PANEL_SIMPLE is not set
+CONFIG_DRM_PANEL_SIMPLE=m
 # CONFIG_DRM_PANEL_ILITEK_IL9322 is not set
 # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
+# CONFIG_DRM_PANEL_LG_LB035Q02 is not set
 # CONFIG_DRM_PANEL_LG_LG4573 is not set
+# CONFIG_DRM_PANEL_NEC_NL8048HL11 is not set
+# CONFIG_DRM_PANEL_NOVATEK_NT39016 is not set
 # CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO is not set
 # CONFIG_DRM_PANEL_SAMSUNG_S6E63M0 is not set
 # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
 # CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set
+# CONFIG_DRM_PANEL_SHARP_LS037V7DW01 is not set
 # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set
+# CONFIG_DRM_PANEL_SONY_ACX565AKM is not set
+# CONFIG_DRM_PANEL_TPO_TD028TTEC1 is not set
+# CONFIG_DRM_PANEL_TPO_TD043MTEA1 is not set
 # CONFIG_DRM_PANEL_TPO_TPG110 is not set
 # end of Display Panels
 
@@ -3570,9 +3570,15 @@ CONFIG_DRM_PANEL_BRIDGE=y
 # CONFIG_DRM_STI is not set
 # CONFIG_DRM_ETNAVIV is not set
 # CONFIG_DRM_ARCPGU is not set
-# CONFIG_DRM_HISI_HIBMC is not set
 # CONFIG_DRM_MXSFB is not set
-# CONFIG_DRM_TINYDRM is not set
+# CONFIG_DRM_GM12U320 is not set
+# CONFIG_TINYDRM_HX8357D is not set
+# CONFIG_TINYDRM_ILI9225 is not set
+# CONFIG_TINYDRM_ILI9341 is not set
+# CONFIG_TINYDRM_MI0283QT is not set
+# CONFIG_TINYDRM_REPAPER is not set
+# CONFIG_TINYDRM_ST7586 is not set
+# CONFIG_TINYDRM_ST7735R is not set
 # CONFIG_DRM_PL111 is not set
 # CONFIG_DRM_TVE200 is not set
 # CONFIG_DRM_LIMA is not set
@@ -3970,6 +3976,7 @@ CONFIG_SND_SOC_TLV320AIC3X=m
 # CONFIG_SND_SOC_TSCS454 is not set
 CONFIG_SND_SOC_TWL4030=m
 CONFIG_SND_SOC_TWL6040=m
+# CONFIG_SND_SOC_UDA1334 is not set
 # CONFIG_SND_SOC_WM8510 is not set
 # CONFIG_SND_SOC_WM8523 is not set
 # CONFIG_SND_SOC_WM8524 is not set
@@ -4037,6 +4044,7 @@ CONFIG_HID_GENERIC=m
 # CONFIG_HID_MACALLY is not set
 # CONFIG_HID_PRODIKEYS is not set
 # CONFIG_HID_CMEDIA is not set
+# CONFIG_HID_CREATIVE_SB0540 is not set
 # CONFIG_HID_CYPRESS is not set
 # CONFIG_HID_DRAGONRISE is not set
 # CONFIG_HID_EMS_FF is not set
@@ -4131,6 +4139,9 @@ CONFIG_USB_MOUSE=m
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_SUPPORT=y
 CONFIG_USB_COMMON=m
+# CONFIG_USB_LED_TRIG is not set
+# CONFIG_USB_ULPI_BUS is not set
+# CONFIG_USB_CONN_GPIO is not set
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB=m
 CONFIG_USB_PCI=y
@@ -4147,7 +4158,6 @@ CONFIG_USB_DEFAULT_PERSIST=y
 # CONFIG_USB_LEDS_TRIGGER_USBPORT is not set
 CONFIG_USB_AUTOSUSPEND_DELAY=2
 CONFIG_USB_MON=m
-# CONFIG_USB_WUSB_CBAF is not set
 
 #
 # USB Host Controller Drivers
@@ -4215,6 +4225,7 @@ CONFIG_USB_STORAGE=m
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
 # CONFIG_USBIP_CORE is not set
+# CONFIG_USB_CDNS3 is not set
 CONFIG_USB_MUSB_HDRC=m
 # CONFIG_USB_MUSB_HOST is not set
 # CONFIG_USB_MUSB_GADGET is not set
@@ -4441,9 +4452,6 @@ CONFIG_USB_G_NOKIA=m
 # CONFIG_USB_G_WEBCAM is not set
 # CONFIG_TYPEC is not set
 # CONFIG_USB_ROLE_SWITCH is not set
-# CONFIG_USB_LED_TRIG is not set
-# CONFIG_USB_ULPI_BUS is not set
-# CONFIG_UWB is not set
 CONFIG_MMC=y
 CONFIG_PWRSEQ_EMMC=y
 # CONFIG_PWRSEQ_SD8787 is not set
@@ -4461,6 +4469,7 @@ CONFIG_MMC_SDHCI=y
 # CONFIG_MMC_SDHCI_PCI is not set
 CONFIG_MMC_SDHCI_PLTFM=y
 # CONFIG_MMC_SDHCI_OF_ARASAN is not set
+# CONFIG_MMC_SDHCI_OF_ASPEED is not set
 # CONFIG_MMC_SDHCI_OF_AT91 is not set
 # CONFIG_MMC_SDHCI_OF_DWCMSHC is not set
 # CONFIG_MMC_SDHCI_CADENCE is not set
@@ -4600,7 +4609,6 @@ CONFIG_RTC_DRV_DS1307=m
 # CONFIG_RTC_DRV_PCF8583 is not set
 CONFIG_RTC_DRV_M41T80=m
 # CONFIG_RTC_DRV_M41T80_WDT is not set
-# CONFIG_RTC_DRV_BD70528 is not set
 # CONFIG_RTC_DRV_BQ32K is not set
 CONFIG_RTC_DRV_TWL92330=y
 CONFIG_RTC_DRV_TWL4030=m
@@ -4714,17 +4722,15 @@ CONFIG_TI_DMA_CROSSBAR=y
 CONFIG_SYNC_FILE=y
 # CONFIG_SW_SYNC is not set
 # CONFIG_UDMABUF is not set
+# CONFIG_DMABUF_SELFTESTS is not set
 # end of DMABUF options
 
 # CONFIG_AUXDISPLAY is not set
 # CONFIG_UIO is not set
 # CONFIG_VFIO is not set
 # CONFIG_VIRT_DRIVERS is not set
-CONFIG_VIRTIO=m
 CONFIG_VIRTIO_MENU=y
 # CONFIG_VIRTIO_PCI is not set
-# CONFIG_VIRTIO_BALLOON is not set
-# CONFIG_VIRTIO_INPUT is not set
 # CONFIG_VIRTIO_MMIO is not set
 
 #
@@ -4732,8 +4738,10 @@ CONFIG_VIRTIO_MENU=y
 #
 # end of Microsoft Hyper-V guest support
 
+# CONFIG_GREYBUS is not set
 # CONFIG_STAGING is not set
 # CONFIG_GOLDFISH is not set
+# CONFIG_MFD_CROS_EC is not set
 # CONFIG_CHROME_PLATFORMS is not set
 # CONFIG_MELLANOX_PLATFORM is not set
 CONFIG_CLKDEV_LOOKUP=y
@@ -4776,12 +4784,7 @@ CONFIG_ARM_ARCH_TIMER=y
 CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
 # end of Clock Source drivers
 
-CONFIG_MAILBOX=y
-# CONFIG_PLATFORM_MHU is not set
-CONFIG_OMAP2PLUS_MBOX=m
-CONFIG_OMAP_MBOX_KFIFO_SIZE=256
-# CONFIG_ALTERA_MBOX is not set
-# CONFIG_MAILBOX_TEST is not set
+# CONFIG_MAILBOX is not set
 CONFIG_IOMMU_API=y
 CONFIG_IOMMU_SUPPORT=y
 
@@ -4802,15 +4805,12 @@ CONFIG_OMAP_IOMMU=y
 #
 # Remoteproc drivers
 #
-CONFIG_REMOTEPROC=m
-CONFIG_OMAP_REMOTEPROC=m
-CONFIG_WKUP_M3_RPROC=m
+# CONFIG_REMOTEPROC is not set
 # end of Remoteproc drivers
 
 #
 # Rpmsg drivers
 #
-# CONFIG_RPMSG_QCOM_GLINK_RPM is not set
 # CONFIG_RPMSG_VIRTIO is not set
 # end of Rpmsg drivers
 
@@ -4852,8 +4852,6 @@ CONFIG_WKUP_M3_RPROC=m
 # end of Qualcomm SoC drivers
 
 CONFIG_SOC_TI=y
-CONFIG_AMX3_PM=m
-CONFIG_WKUP_M3_IPC=m
 
 #
 # Xilinx SoC drivers
@@ -4912,7 +4910,6 @@ CONFIG_IIO_SW_TRIGGER=m
 # CONFIG_DMARD06 is not set
 # CONFIG_DMARD09 is not set
 # CONFIG_DMARD10 is not set
-# CONFIG_IIO_CROS_EC_ACCEL_LEGACY is not set
 CONFIG_IIO_ST_ACCEL_3AXIS=m
 CONFIG_IIO_ST_ACCEL_I2C_3AXIS=m
 CONFIG_IIO_ST_ACCEL_SPI_3AXIS=m
@@ -5138,6 +5135,7 @@ CONFIG_IIO_ST_SENSORS_CORE=m
 # Inertial measurement units
 #
 # CONFIG_ADIS16400 is not set
+# CONFIG_ADIS16460 is not set
 # CONFIG_ADIS16480 is not set
 # CONFIG_BMI160_I2C is not set
 # CONFIG_BMI160_SPI is not set
@@ -5170,6 +5168,7 @@ CONFIG_IIO_ST_SENSORS_CORE=m
 # CONFIG_LV0104CS is not set
 # CONFIG_MAX44000 is not set
 # CONFIG_MAX44009 is not set
+# CONFIG_NOA1305 is not set
 # CONFIG_OPT3001 is not set
 # CONFIG_PA12203001 is not set
 # CONFIG_SI1133 is not set
@@ -5232,6 +5231,7 @@ CONFIG_IIO_ST_SENSORS_CORE=m
 #
 # CONFIG_AD5272 is not set
 # CONFIG_DS1803 is not set
+# CONFIG_MAX5432 is not set
 # CONFIG_MAX5481 is not set
 # CONFIG_MAX5487 is not set
 # CONFIG_MCP4018 is not set
@@ -5427,6 +5427,7 @@ CONFIG_EXPORTFS=y
 CONFIG_FILE_LOCKING=y
 CONFIG_MANDATORY_FILE_LOCKING=y
 # CONFIG_FS_ENCRYPTION is not set
+# CONFIG_FS_VERITY is not set
 CONFIG_FSNOTIFY=y
 CONFIG_DNOTIFY=y
 CONFIG_INOTIFY_USER=y
@@ -5536,7 +5537,7 @@ CONFIG_CRAMFS_BLOCKDEV=y
 # CONFIG_PSTORE is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
-# CONFIG_AUFS_FS is not set
+# CONFIG_EROFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V2=y
@@ -5640,13 +5641,14 @@ CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
 # CONFIG_SECURITY_LOADPIN is not set
 # CONFIG_SECURITY_YAMA is not set
 # CONFIG_SECURITY_SAFESETID is not set
+# CONFIG_SECURITY_LOCKDOWN_LSM is not set
 CONFIG_INTEGRITY=y
 # CONFIG_INTEGRITY_SIGNATURE is not set
 CONFIG_INTEGRITY_AUDIT=y
 # CONFIG_IMA is not set
 # CONFIG_EVM is not set
 CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_LSM="yama,loadpin,safesetid,integrity"
+CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity"
 
 #
 # Kernel hardening options
@@ -5699,7 +5701,6 @@ CONFIG_CRYPTO_CRYPTD=m
 # CONFIG_CRYPTO_AUTHENC is not set
 # CONFIG_CRYPTO_TEST is not set
 CONFIG_CRYPTO_SIMD=m
-CONFIG_CRYPTO_ENGINE=m
 
 #
 # Public-key cryptography
@@ -5717,10 +5718,6 @@ CONFIG_CRYPTO_CCM=m
 CONFIG_CRYPTO_GCM=m
 # CONFIG_CRYPTO_CHACHA20POLY1305 is not set
 # CONFIG_CRYPTO_AEGIS128 is not set
-# CONFIG_CRYPTO_AEGIS128L is not set
-# CONFIG_CRYPTO_AEGIS256 is not set
-# CONFIG_CRYPTO_MORUS640 is not set
-# CONFIG_CRYPTO_MORUS1280 is not set
 CONFIG_CRYPTO_SEQIV=m
 # CONFIG_CRYPTO_ECHAINIV is not set
 
@@ -5738,6 +5735,7 @@ CONFIG_CRYPTO_PCBC=m
 # CONFIG_CRYPTO_XTS is not set
 # CONFIG_CRYPTO_KEYWRAP is not set
 # CONFIG_CRYPTO_ADIANTUM is not set
+# CONFIG_CRYPTO_ESSIV is not set
 
 #
 # Hash modes
@@ -5764,6 +5762,7 @@ CONFIG_CRYPTO_MICHAEL_MIC=y
 # CONFIG_CRYPTO_RMD256 is not set
 # CONFIG_CRYPTO_RMD320 is not set
 CONFIG_CRYPTO_SHA1=m
+CONFIG_CRYPTO_LIB_SHA256=m
 CONFIG_CRYPTO_SHA256=m
 # CONFIG_CRYPTO_SHA512 is not set
 # CONFIG_CRYPTO_SHA3 is not set
@@ -5775,6 +5774,7 @@ CONFIG_CRYPTO_SHA256=m
 #
 # Ciphers
 #
+CONFIG_CRYPTO_LIB_AES=m
 CONFIG_CRYPTO_AES=m
 # CONFIG_CRYPTO_AES_TI is not set
 # CONFIG_CRYPTO_ANUBIS is not set
@@ -5825,7 +5825,7 @@ CONFIG_CRYPTO_HW=y
 # CONFIG_CRYPTO_DEV_OMAP is not set
 # CONFIG_CRYPTO_DEV_ATMEL_ECC is not set
 # CONFIG_CRYPTO_DEV_ATMEL_SHA204A is not set
-CONFIG_CRYPTO_DEV_VIRTIO=m
+# CONFIG_CRYPTO_DEV_SAFEXCEL is not set
 # CONFIG_CRYPTO_DEV_CCREE is not set
 CONFIG_ASYMMETRIC_KEY_TYPE=y
 CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y
@@ -5933,7 +5933,6 @@ CONFIG_GENERIC_ATOMIC64=y
 CONFIG_CLZ_TAB=y
 # CONFIG_IRQ_POLL is not set
 CONFIG_MPILIB=y
-CONFIG_DIMLIB=y
 CONFIG_LIBFDT=y
 CONFIG_OID_REGISTRY=y
 CONFIG_FONT_SUPPORT=y
@@ -5985,10 +5984,9 @@ CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_WARN=1024
 # CONFIG_STRIP_ASM_SYMS is not set
 # CONFIG_READABLE_ASM is not set
-# CONFIG_UNUSED_SYMBOLS is not set
 CONFIG_DEBUG_FS=y
 # CONFIG_HEADERS_INSTALL is not set
-# CONFIG_OPTIMIZE_INLINING is not set
+CONFIG_OPTIMIZE_INLINING=y
 # CONFIG_DEBUG_SECTION_MISMATCH is not set
 CONFIG_SECTION_MISMATCH_WARN_ONLY=y
 # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
diff --git a/patches/soc/ti/beagleboard_dtbs/0001-Add-BeagleBoard.org-DTBS-v5.3.x.patch b/patches/soc/ti/beagleboard_dtbs/0001-Add-BeagleBoard.org-DTBS-v5.4.x.patch
similarity index 99%
rename from patches/soc/ti/beagleboard_dtbs/0001-Add-BeagleBoard.org-DTBS-v5.3.x.patch
rename to patches/soc/ti/beagleboard_dtbs/0001-Add-BeagleBoard.org-DTBS-v5.4.x.patch
index 1ddb8dee9ef95c3178b01d5b2f60009e354e3f9b..44a5b22c8e8093ab7bd25dffeee642ff77121dd8 100644
--- a/patches/soc/ti/beagleboard_dtbs/0001-Add-BeagleBoard.org-DTBS-v5.3.x.patch
+++ b/patches/soc/ti/beagleboard_dtbs/0001-Add-BeagleBoard.org-DTBS-v5.4.x.patch
@@ -1,9 +1,9 @@
-From c6423b69f11cc28a5d5f37b8bd548d91a983d738 Mon Sep 17 00:00:00 2001
+From 1012eb42edd62e3c26bb04228b09430c59dfec29 Mon Sep 17 00:00:00 2001
 From: Robert Nelson <robertcnelson@gmail.com>
-Date: Tue, 1 Oct 2019 10:29:42 -0500
-Subject: [PATCH] Add BeagleBoard.org DTBS: v5.3.x
+Date: Tue, 1 Oct 2019 13:27:28 -0500
+Subject: [PATCH] Add BeagleBoard.org DTBS: v5.4.x
 
-https://github.com/beagleboard/BeagleBoard-DeviceTrees/tree/v5.3.x
+https://github.com/beagleboard/BeagleBoard-DeviceTrees/tree/v5.4.x
 Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
 ---
  arch/arm/boot/dts/Makefile                    |    6 +
@@ -16,11 +16,11 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
  arch/arm/boot/dts/am335x-bone.dts             |    6 +
  .../arm/boot/dts/am335x-boneblack-common.dtsi |   10 +-
  .../boot/dts/am335x-boneblack-uboot-univ.dts  |   40 +
- arch/arm/boot/dts/am335x-boneblack-uboot.dts  |   41 +
+ arch/arm/boot/dts/am335x-boneblack-uboot.dts  |   40 +
  .../boot/dts/am335x-boneblack-wireless.dts    |    6 +
  arch/arm/boot/dts/am335x-boneblack.dts        |    6 +
- arch/arm/boot/dts/am335x-boneblue.dts         |  491 ++-
- ...am335x-bonegreen-wireless-common-univ.dtsi | 2794 ++++++++++++++++
+ arch/arm/boot/dts/am335x-boneblue.dts         |  469 ++-
+ ...am335x-bonegreen-wireless-common-univ.dtsi | 2823 ++++++++++++++++
  .../am335x-bonegreen-wireless-uboot-univ.dts  |   55 +
  .../boot/dts/am335x-bonegreen-wireless.dts    |    6 +
  arch/arm/boot/dts/am335x-bonegreen.dts        |    6 +
@@ -45,7 +45,7 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
  arch/arm/boot/dts/omap4.dtsi                  |    2 +
  arch/arm/boot/dts/twl6030.dtsi                |    5 +
  .../dt-bindings/board/am335x-bbw-bbb-base.h   |  103 +
- 39 files changed, 9465 insertions(+), 118 deletions(-)
+ 39 files changed, 9473 insertions(+), 116 deletions(-)
  create mode 100644 arch/arm/boot/dts/am335x-abbbi.dts
  create mode 100644 arch/arm/boot/dts/am335x-bone-common-no-capemgr.dtsi
  create mode 100644 arch/arm/boot/dts/am335x-bone-common-univ.dtsi
@@ -59,10 +59,10 @@ Signed-off-by: Robert Nelson <robertcnelson@gmail.com>
  create mode 100644 include/dt-bindings/board/am335x-bbw-bbb-base.h
 
 diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
-index 9159fa2cea90..fe03bb9ef7e5 100644
+index b21b3a64641a..a979e20ee430 100644
 --- a/arch/arm/boot/dts/Makefile
 +++ b/arch/arm/boot/dts/Makefile
-@@ -732,6 +732,11 @@ dtb-$(CONFIG_SOC_AM33XX) += \
+@@ -739,6 +739,11 @@ dtb-$(CONFIG_SOC_AM33XX) += \
  	am335x-base0033.dtb \
  	am335x-bone.dtb \
  	am335x-boneblack.dtb \
@@ -74,7 +74,7 @@ index 9159fa2cea90..fe03bb9ef7e5 100644
  	am335x-boneblack-wireless.dtb \
  	am335x-boneblue.dtb \
  	am335x-bonegreen.dtb \
-@@ -762,6 +767,7 @@ dtb-$(CONFIG_ARCH_OMAP4) += \
+@@ -769,6 +774,7 @@ dtb-$(CONFIG_ARCH_OMAP4) += \
  	omap4-duovero-parlor.dtb \
  	omap4-kc1.dtb \
  	omap4-panda.dtb \
@@ -3797,10 +3797,10 @@ index 000000000000..4e5633e38694
 +};
 diff --git a/arch/arm/boot/dts/am335x-boneblack-uboot.dts b/arch/arm/boot/dts/am335x-boneblack-uboot.dts
 new file mode 100644
-index 000000000000..09e8c27a4b29
+index 000000000000..285a92126854
 --- /dev/null
 +++ b/arch/arm/boot/dts/am335x-boneblack-uboot.dts
-@@ -0,0 +1,41 @@
+@@ -0,0 +1,40 @@
 +// SPDX-License-Identifier: GPL-2.0-only
 +/*
 + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
@@ -3809,7 +3809,6 @@ index 000000000000..09e8c27a4b29
 +
 +#include "am33xx.dtsi"
 +#include "am335x-bone-common.dtsi"
-+
 +/* #include "am335x-bone-jtag.dtsi" */
 +
 +/ {
@@ -3886,22 +3885,19 @@ index d3928662aed4..40b17b956109 100644
  
  &cpu0_opp_table {
 diff --git a/arch/arm/boot/dts/am335x-boneblue.dts b/arch/arm/boot/dts/am335x-boneblue.dts
-index 0257576d5d16..6df70194b15d 100644
+index 2f6652ef9a15..78a360558d9e 100644
 --- a/arch/arm/boot/dts/am335x-boneblue.dts
 +++ b/arch/arm/boot/dts/am335x-boneblue.dts
-@@ -11,6 +11,11 @@
- 	model = "TI AM335x BeagleBone Blue";
- 	compatible = "ti,am335x-bone-blue", "ti,am33xx";
+@@ -14,6 +14,8 @@
  
-+	chosen {
+ 	chosen {
+ 		stdout-path = &uart0;
 +		base_dtb = "am335x-boneblue.dts";
 +		base_dtb_timestamp = __TIMESTAMP__;
-+	};
-+
- 	cpus {
- 		cpu@0 {
- 			cpu0-supply = <&dcdc2_reg>;
-@@ -122,9 +127,183 @@
+ 	};
+ 
+ 	leds {
+@@ -112,9 +114,168 @@
  		gpio = <&gpio3 9 0>;
  		enable-active-high;
  	};
@@ -3916,21 +3912,6 @@ index 0257576d5d16..6df70194b15d 100644
 +			gpios = <&gpio0 28 GPIO_ACTIVE_HIGH>;
 +			default-state = "off";
 +		};
-+	};
-+};
-+
-+&cpu0_opp_table {
-+	/*
-+	* Octavo Systems:
-+	* The EFUSE_SMA register is not programmed for any of the AM335x wafers
-+	* we get and we are not programming them during our production test.
-+	* Therefore, from a DEVICE_ID revision point of view, the silicon looks
-+	* like it is Revision 2.1.  However, from an EFUSE_SMA point of view for
-+	* the HW OPP table, the silicon looks like it is Revision 1.0 (ie the
-+	* EFUSE_SMA register reads as all zeros).
-+	*/
-+	oppnitro-1000000000 {
-+		opp-supported-hw = <0x06 0x0100>;
 +	};
  };
  
@@ -4085,7 +4066,7 @@ index 0257576d5d16..6df70194b15d 100644
  	user_leds_s0: user_leds_s0 {
  		pinctrl-single,pins = <
  			AM33XX_PADCONF(AM335X_PIN_GPMC_A5, PIN_OUTPUT, MUX_MODE7) /* (V15) gpmc_a5.gpio1[21] - USR_LED_0 */
-@@ -181,11 +360,11 @@
+@@ -164,11 +325,11 @@
  	};
  
  	/* DSM2 */
@@ -4102,7 +4083,7 @@ index 0257576d5d16..6df70194b15d 100644
  
  	/* UT5 */
  	uart5_pins: pinmux_uart5_pins {
-@@ -258,6 +437,51 @@
+@@ -241,6 +402,51 @@
  			AM33XX_PADCONF(AM335X_PIN_MII1_RXD0, PIN_OUTPUT, MUX_MODE7)		/* (M16) gmii1_rxd0.gpio2[21] */
  		>;
  	};
@@ -4154,7 +4135,7 @@ index 0257576d5d16..6df70194b15d 100644
  };
  
  &uart0 {
-@@ -281,12 +505,12 @@
+@@ -264,12 +470,12 @@
  	status = "okay";
  };
  
@@ -4173,16 +4154,7 @@ index 0257576d5d16..6df70194b15d 100644
  
  &uart5 {
  	pinctrl-names = "default";
-@@ -384,6 +608,8 @@
- 	interrupts = <7>; /* NMI */
- 	interrupt-parent = <&intc>;
- 
-+	ti,pmic-shutdown-controller;
-+
- 	charger {
- 		interrupts = <0>, <1>;
- 		interrupt-names = "USB", "AC";
-@@ -484,22 +710,23 @@
+@@ -404,22 +610,23 @@
  	};
  };
  
@@ -4216,21 +4188,19 @@ index 0257576d5d16..6df70194b15d 100644
 +//	};
  };
  
- &aes {
-@@ -512,8 +739,10 @@
- 
  &rtc {
- 	system-power-controller;
--	clocks = <&clk_32768_ck>, <&clk_24mhz_clkctrl AM3_CLK_24MHZ_CLKDIV32K_CLKCTRL 0>;
--	clock-names = "ext-clk", "int-clk";
-+};
-+
-+&wkup_m3_ipc {
-+	ti,scale-data-fw = "am335x-bone-scale-data.bin";
+@@ -428,6 +635,10 @@
+ 	clock-names = "ext-clk", "int-clk";
  };
  
++&wkup_m3_ipc {
++	ti,scale-data-fw = "am335x-bone-scale-data.bin";
++};
++
  &dcan1 {
-@@ -530,3 +759,217 @@
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&dcan1_pins>;
+@@ -442,3 +653,217 @@
  		line-name = "LS_BUF_EN";
  	};
  };
@@ -4450,10 +4420,10 @@ index 0257576d5d16..6df70194b15d 100644
 +};
 diff --git a/arch/arm/boot/dts/am335x-bonegreen-wireless-common-univ.dtsi b/arch/arm/boot/dts/am335x-bonegreen-wireless-common-univ.dtsi
 new file mode 100644
-index 000000000000..e6f28c969b75
+index 000000000000..4662f304f3ee
 --- /dev/null
 +++ b/arch/arm/boot/dts/am335x-bonegreen-wireless-common-univ.dtsi
-@@ -0,0 +1,2794 @@
+@@ -0,0 +1,2823 @@
 +// SPDX-License-Identifier: GPL-2.0-only
 +/*
 + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
@@ -5584,6 +5554,18 @@ index 000000000000..e6f28c969b75
 +	/* P9_45                GND */
 +
 +	/* P9_46                GND */
++
++	/*       (ZCZ ball A15) */
++	A15_default_pin: pinmux_A15_default_pin {
++		pinctrl-single,pins = <0x1b0  0x0b>; };     /* Mode 3 */
++	A15_clkout_pin: pinmux_A15_clkout_pin {
++		pinctrl-single,pins = <0x1b0  0x0b>; };     /* Mode 3 */
++	A15_gpio_pin: pinmux_A15_gpio_pin {
++		pinctrl-single,pins = <0x1b0  0x2f>; };     /* Mode 7, RxActive */
++	A15_gpio_pu_pin: pinmux_A15_gpio_pu_pin {
++		pinctrl-single,pins = <0x1b0  0x37>; };     /* Mode 7, Pull-Up, RxActive */
++	A15_gpio_pd_pin: pinmux_A15_gpio_pd_pin {
++		pinctrl-single,pins = <0x1b0  0x27>; };     /* Mode 7, Pull-Down, RxActive */
 +};
 +
 +&i2c1 {
@@ -6784,6 +6766,17 @@ index 000000000000..e6f28c969b75
 +
 +	/* P9_46                GND */
 +
++	/*       (ZCZ ball A15) */
++	A15_pinmux {
++		compatible = "bone-pinmux-helper";
++		status = "okay";
++		pinctrl-names = "default", "clkout", "gpio", "gpio_pu", "gpio_pd";
++		pinctrl-0 = <&A15_default_pin>;
++		pinctrl-1 = <&A15_clkout_pin>;
++		pinctrl-2 = <&A15_gpio_pin>;
++		pinctrl-3 = <&A15_gpio_pu_pin>;
++		pinctrl-4 = <&A15_gpio_pd_pin>;
++	};
 +
 +	cape-universal {
 +		compatible = "gpio-of-helper";
@@ -7246,6 +7239,12 @@ index 000000000000..e6f28c969b75
 +			dir-changeable;
 +		};
 +
++		A15 {
++			gpio-name = "A15";
++			gpio = <&gpio0 19 0>;
++			input;
++			dir-changeable;
++		};
 +	};
 +};
 diff --git a/arch/arm/boot/dts/am335x-bonegreen-wireless-uboot-univ.dts b/arch/arm/boot/dts/am335x-bonegreen-wireless-uboot-univ.dts
@@ -9563,7 +9562,7 @@ index 8678e6e35493..2381a5c5110c 100644
  
  &am33xx_pinmux {
 diff --git a/arch/arm/boot/dts/am33xx-l4.dtsi b/arch/arm/boot/dts/am33xx-l4.dtsi
-index 46849d6ecb3e..7ba792f7213c 100644
+index 9915c891e05f..f391e88ea14f 100644
 --- a/arch/arm/boot/dts/am33xx-l4.dtsi
 +++ b/arch/arm/boot/dts/am33xx-l4.dtsi
 @@ -158,6 +158,39 @@
@@ -10202,7 +10201,7 @@ index 3c274965ff40..97001fefe875 100644
  
  &keypad {
 diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
-index c43e52fd5f65..ec51eaabb463 100644
+index 7cc95bc1598b..b4ebf768d0f9 100644
 --- a/arch/arm/boot/dts/omap4.dtsi
 +++ b/arch/arm/boot/dts/omap4.dtsi
 @@ -252,6 +252,7 @@
diff --git a/version.sh b/version.sh
index 9643d1693ffa79f236e7f209d6b5547a81f7d8ce..831b4f94deb05091cde1a75eb755cb5b0b584108 100644
--- a/version.sh
+++ b/version.sh
@@ -31,11 +31,11 @@ toolchain="gcc_arm_gnueabihf_8"
 #toolchain="gcc_arm_aarch64_gnu_8"
 
 #Kernel
-KERNEL_REL=5.3
-KERNEL_TAG=${KERNEL_REL}.2
+KERNEL_REL=5.4
+KERNEL_TAG=${KERNEL_REL}-rc1
 kernel_rt=".X-rtY"
 #Kernel Build
-BUILD=${build_prefix}9.2
+BUILD=${build_prefix}0
 
 #v5.X-rcX + upto SHA
 #prev_KERNEL_SHA=""