From: Gabor Juhos <juhosg@openwrt.org>
Date: Sat, 12 May 2012 12:05:21 +0000 (+0000)
Subject: linux/2.6.38: R.I.P.
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=e710aeeab10e2b420ad012c0d9fb639266a63515;p=openwrt%2Fstaging%2Fdangole.git

linux/2.6.38: R.I.P.

It is used only by the broken coldfire target.

SVN-Revision: 31688
---

diff --git a/target/linux/generic/config-2.6.38 b/target/linux/generic/config-2.6.38
deleted file mode 100644
index 5194f32ee9..0000000000
--- a/target/linux/generic/config-2.6.38
+++ /dev/null
@@ -1,3086 +0,0 @@
-CONFIG_32BIT=y
-# CONFIG_6PACK is not set
-# CONFIG_8139CP is not set
-# CONFIG_8139TOO is not set
-# CONFIG_9P_FS is not set
-# CONFIG_AB3100_CORE is not set
-# CONFIG_AB8500_CORE is not set
-# CONFIG_ABX500_CORE is not set
-# CONFIG_ACCESSIBILITY is not set
-# CONFIG_ACENIC is not set
-# CONFIG_ACORN_PARTITION is not set
-# CONFIG_ACPI_APEI is not set
-# CONFIG_ACPI_HED is not set
-# CONFIG_ACPI_POWER_METER is not set
-# CONFIG_AD525X_DPOT is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_ADFS_FS is not set
-# CONFIG_ADIS16255 is not set
-# CONFIG_ADM6996_PHY is not set
-# CONFIG_ADM8211 is not set
-CONFIG_AEABI=y
-# CONFIG_AFFS_FS is not set
-# CONFIG_AFS_FS is not set
-# CONFIG_AF_RXRPC is not set
-# CONFIG_AGP is not set
-CONFIG_AIO=y
-# CONFIG_AIRO is not set
-# CONFIG_AIRO_CS is not set
-# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
-# CONFIG_ALIM7101_WDT is not set
-# CONFIG_AMD8111_ETH is not set
-# CONFIG_AMIGA_PARTITION is not set
-CONFIG_ANON_INODES=y
-# CONFIG_APDS9802ALS is not set
-# CONFIG_APPLICOM is not set
-# CONFIG_AR7 is not set
-# CONFIG_AR8216_PHY is not set
-# CONFIG_AR9170_USB is not set
-# CONFIG_ARCH_AAEC2000 is not set
-# CONFIG_ARCH_AT91 is not set
-# CONFIG_ARCH_BCMRING is not set
-# CONFIG_ARCH_CLPS711X is not set
-# CONFIG_ARCH_CNS3XXX is not set
-# CONFIG_ARCH_DAVINCI is not set
-# CONFIG_ARCH_DOVE is not set
-# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_ARCH_EP93XX is not set
-CONFIG_ARCH_FLATMEM_ENABLE=y
-# CONFIG_ARCH_FOOTBRIDGE is not set
-# CONFIG_ARCH_GEMINI is not set
-# CONFIG_ARCH_H720X is not set
-# CONFIG_ARCH_INTEGRATOR is not set
-# CONFIG_ARCH_IOP13XX is not set
-# CONFIG_ARCH_IOP32X is not set
-# CONFIG_ARCH_IOP33X is not set
-# CONFIG_ARCH_IXP2000 is not set
-# CONFIG_ARCH_IXP23XX is not set
-# CONFIG_ARCH_IXP4XX is not set
-# CONFIG_ARCH_KIRKWOOD is not set
-# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_LH7A40X is not set
-# CONFIG_ARCH_LOKI is not set
-# CONFIG_ARCH_LPC32XX is not set
-# CONFIG_ARCH_MMP is not set
-# CONFIG_ARCH_MSM is not set
-# CONFIG_ARCH_MV78XX0 is not set
-# CONFIG_ARCH_MXC is not set
-# CONFIG_ARCH_MXS is not set
-# CONFIG_ARCH_NETX is not set
-# CONFIG_ARCH_NOMADIK is not set
-# CONFIG_ARCH_NS9XXX is not set
-# CONFIG_ARCH_NUC93X is not set
-# CONFIG_ARCH_OMAP is not set
-# CONFIG_ARCH_ORION5X is not set
-# CONFIG_ARCH_PNX4008 is not set
-# CONFIG_ARCH_PXA is not set
-# CONFIG_ARCH_REALVIEW is not set
-# CONFIG_ARCH_RPC is not set
-# CONFIG_ARCH_S3C2410 is not set
-# CONFIG_ARCH_S3C64XX is not set
-# CONFIG_ARCH_S5P6440 is not set
-# CONFIG_ARCH_S5P6442 is not set
-# CONFIG_ARCH_S5P64X0 is not set
-# CONFIG_ARCH_S5PC100 is not set
-# CONFIG_ARCH_S5PV210 is not set
-# CONFIG_ARCH_S5PV310 is not set
-# CONFIG_ARCH_SA1100 is not set
-# CONFIG_ARCH_SHARK is not set
-# CONFIG_ARCH_SHMOBILE is not set
-# CONFIG_ARCH_STMP3XXX is not set
-# CONFIG_ARCH_TCC_926 is not set
-# CONFIG_ARCH_TEGRA is not set
-# CONFIG_ARCH_U300 is not set
-# CONFIG_ARCH_U8500 is not set
-# CONFIG_ARCH_VERSATILE is not set
-# CONFIG_ARCH_VEXPRESS is not set
-# CONFIG_ARCH_W90X900 is not set
-# CONFIG_ARCNET is not set
-CONFIG_ARM_DMA_MEM_BUFFERABLE=y
-# CONFIG_ARM_ERRATA_411920 is not set
-# CONFIG_ARM_UNWIND is not set
-CONFIG_ARPD=y
-# CONFIG_ARTHUR is not set
-CONFIG_ASK_IP_FIB_HASH=y
-# CONFIG_ASUS_OLED is not set
-# CONFIG_ASYNC_RAID6_TEST is not set
-# CONFIG_ASYNC_TX_DMA is not set
-# CONFIG_AT76C50X_USB is not set
-# CONFIG_ATA is not set
-# CONFIG_ATALK is not set
-# CONFIG_ATARI_PARTITION is not set
-# CONFIG_ATA_ACPI is not set
-CONFIG_ATA_BMDMA=y
-# CONFIG_ATA_GENERIC is not set
-# CONFIG_ATA_NONSTANDARD is not set
-# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_ATA_PIIX is not set
-CONFIG_ATA_SFF=y
-# CONFIG_ATA_VERBOSE_ERROR is not set
-# CONFIG_ATH5K is not set
-# CONFIG_ATH6K_LEGACY is not set
-# CONFIG_ATH9K is not set
-# CONFIG_ATL1 is not set
-# CONFIG_ATL1C is not set
-# CONFIG_ATL1E is not set
-# CONFIG_ATL2 is not set
-# CONFIG_ATM is not set
-# CONFIG_ATMEL is not set
-# CONFIG_ATM_AMBASSADOR is not set
-# CONFIG_ATM_BR2684 is not set
-CONFIG_ATM_BR2684_IPFILTER=y
-# CONFIG_ATM_CLIP is not set
-CONFIG_ATM_CLIP_NO_ICMP=y
-# CONFIG_ATM_DRIVERS is not set
-# CONFIG_ATM_DUMMY is not set
-# CONFIG_ATM_ENI is not set
-# CONFIG_ATM_FIRESTREAM is not set
-# CONFIG_ATM_FORE200E is not set
-# CONFIG_ATM_HE is not set
-# CONFIG_ATM_HORIZON is not set
-# CONFIG_ATM_IA is not set
-# CONFIG_ATM_IDT77252 is not set
-# CONFIG_ATM_LANAI is not set
-# CONFIG_ATM_LANE is not set
-# CONFIG_ATM_MPOA is not set
-# CONFIG_ATM_NICSTAR is not set
-# CONFIG_ATM_SOLOS is not set
-# CONFIG_ATM_TCP is not set
-# CONFIG_ATM_ZATM is not set
-# CONFIG_ATOMIC64_SELFTEST is not set
-# CONFIG_AUDIT is not set
-# CONFIG_AUTOFS4_FS is not set
-# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTO_ZRELADDR is not set
-# CONFIG_AUXDISPLAY is not set
-# CONFIG_AVERAGE is not set
-# CONFIG_AX25 is not set
-# CONFIG_AX25_DAMA_SLAVE is not set
-# CONFIG_AX88796 is not set
-# CONFIG_B43 is not set
-# CONFIG_B43LEGACY is not set
-# CONFIG_B44 is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
-# CONFIG_BACKTRACE_SELF_TEST is not set
-CONFIG_BASE_FULL=y
-CONFIG_BASE_SMALL=0
-# CONFIG_BATMAN_ADV is not set
-# CONFIG_BATTERY_BQ27x00 is not set
-# CONFIG_BATTERY_DS2760 is not set
-# CONFIG_BATTERY_DS2782 is not set
-# CONFIG_BATTERY_MAX17040 is not set
-# CONFIG_BATTERY_MAX17042 is not set
-# CONFIG_BAYCOM_EPP is not set
-# CONFIG_BAYCOM_PAR is not set
-# CONFIG_BAYCOM_SER_FDX is not set
-# CONFIG_BAYCOM_SER_HDX is not set
-# CONFIG_BCM47XX is not set
-# CONFIG_BCM63XX is not set
-# CONFIG_BCM63XX_PHY is not set
-# CONFIG_BCMA is not set
-# CONFIG_BCM_WIMAX is not set
-# CONFIG_BDI_SWITCH is not set
-# CONFIG_BE2ISCSI is not set
-# CONFIG_BEFS_FS is not set
-# CONFIG_BFS_FS is not set
-# CONFIG_BINARY_PRINTF is not set
-# CONFIG_BINFMT_AOUT is not set
-CONFIG_BINFMT_ELF=y
-# CONFIG_BINFMT_MISC is not set
-CONFIG_BITREVERSE=y
-CONFIG_BKL=y
-# CONFIG_BLK_CPQ_CISS_DA is not set
-# CONFIG_BLK_CPQ_DA is not set
-CONFIG_BLK_DEV=y
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-# CONFIG_BLK_DEV_4DRIVES is not set
-# CONFIG_BLK_DEV_AEC62XX is not set
-# CONFIG_BLK_DEV_ALI14XX is not set
-# CONFIG_BLK_DEV_ALI15X3 is not set
-# CONFIG_BLK_DEV_AMD74XX is not set
-# CONFIG_BLK_DEV_ATIIXP is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_BLK_DEV_CMD640 is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_CRYPTOLOOP is not set
-# CONFIG_BLK_DEV_CS5520 is not set
-# CONFIG_BLK_DEV_CS5530 is not set
-# CONFIG_BLK_DEV_CS5535 is not set
-# CONFIG_BLK_DEV_CS5536 is not set
-# CONFIG_BLK_DEV_CY82C693 is not set
-# CONFIG_BLK_DEV_DAC960 is not set
-# CONFIG_BLK_DEV_DELKIN is not set
-# CONFIG_BLK_DEV_DRBD is not set
-# CONFIG_BLK_DEV_DTC2278 is not set
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_GENERIC is not set
-# CONFIG_BLK_DEV_HD is not set
-# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_BLK_DEV_HT6560B is not set
-# CONFIG_BLK_DEV_IDEACPI is not set
-# CONFIG_BLK_DEV_IDECD is not set
-# CONFIG_BLK_DEV_IDECS is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-# CONFIG_BLK_DEV_IDEPNP is not set
-# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDE_SATA is not set
-CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_INTEGRITY is not set
-# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_BLK_DEV_IT8172 is not set
-# CONFIG_BLK_DEV_IT8213 is not set
-# CONFIG_BLK_DEV_IT821X is not set
-# CONFIG_BLK_DEV_JMICRON is not set
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_OFFBOARD is not set
-# CONFIG_BLK_DEV_OPTI621 is not set
-# CONFIG_BLK_DEV_PDC202XX_NEW is not set
-# CONFIG_BLK_DEV_PDC202XX_OLD is not set
-# CONFIG_BLK_DEV_PIIX is not set
-# CONFIG_BLK_DEV_PLATFORM is not set
-# CONFIG_BLK_DEV_QD65XX is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_RBD is not set
-# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_SC1200 is not set
-# CONFIG_BLK_DEV_SD is not set
-# CONFIG_BLK_DEV_SIIMAGE is not set
-# CONFIG_BLK_DEV_SIS5513 is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
-# CONFIG_BLK_DEV_SLC90E66 is not set
-# CONFIG_BLK_DEV_SR is not set
-# CONFIG_BLK_DEV_SVWKS is not set
-# CONFIG_BLK_DEV_SX8 is not set
-# CONFIG_BLK_DEV_TC86C001 is not set
-# CONFIG_BLK_DEV_TRIFLEX is not set
-# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_UB is not set
-# CONFIG_BLK_DEV_UMC8672 is not set
-# CONFIG_BLK_DEV_UMEM is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_XIP is not set
-CONFIG_BLOCK=y
-# CONFIG_BMP085 is not set
-# CONFIG_BNA is not set
-# CONFIG_BNX2 is not set
-# CONFIG_BONDING is not set
-# CONFIG_BOOKE_WDT is not set
-# CONFIG_BOOT_PRINTK_DELAY is not set
-CONFIG_BOOT_RAW=y
-# CONFIG_BPQETHER is not set
-# CONFIG_BRCM80211 is not set
-CONFIG_BRIDGE=y
-# CONFIG_BRIDGE_EBT_802_3 is not set
-# CONFIG_BRIDGE_EBT_AMONG is not set
-# CONFIG_BRIDGE_EBT_ARP is not set
-# CONFIG_BRIDGE_EBT_ARPREPLY is not set
-# CONFIG_BRIDGE_EBT_BROUTE is not set
-# CONFIG_BRIDGE_EBT_DNAT is not set
-# CONFIG_BRIDGE_EBT_IP is not set
-# CONFIG_BRIDGE_EBT_IP6 is not set
-# CONFIG_BRIDGE_EBT_LIMIT is not set
-# CONFIG_BRIDGE_EBT_LOG is not set
-# CONFIG_BRIDGE_EBT_MARK is not set
-# CONFIG_BRIDGE_EBT_MARK_T is not set
-# CONFIG_BRIDGE_EBT_NFLOG is not set
-# CONFIG_BRIDGE_EBT_PKTTYPE is not set
-# CONFIG_BRIDGE_EBT_REDIRECT is not set
-# CONFIG_BRIDGE_EBT_SNAT is not set
-# CONFIG_BRIDGE_EBT_STP is not set
-# CONFIG_BRIDGE_EBT_T_FILTER is not set
-# CONFIG_BRIDGE_EBT_T_NAT is not set
-# CONFIG_BRIDGE_EBT_ULOG is not set
-# CONFIG_BRIDGE_EBT_VLAN is not set
-# CONFIG_BRIDGE_IGMP_SNOOPING is not set
-# CONFIG_BRIDGE_NETFILTER is not set
-# CONFIG_BRIDGE_NF_EBTABLES is not set
-# CONFIG_BROADCOM_PHY is not set
-CONFIG_BROKEN_ON_SMP=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_BSD_PROCESS_ACCT_V3 is not set
-# CONFIG_BT is not set
-# CONFIG_BTRFS_FS is not set
-# CONFIG_BT_ATH3K is not set
-# CONFIG_BT_BNEP is not set
-CONFIG_BT_BNEP_MC_FILTER=y
-CONFIG_BT_BNEP_PROTO_FILTER=y
-# CONFIG_BT_CMTP is not set
-# CONFIG_BT_HCIBCM203X is not set
-# CONFIG_BT_HCIBFUSB is not set
-# CONFIG_BT_HCIBLUECARD is not set
-# CONFIG_BT_HCIBPA10X is not set
-# CONFIG_BT_HCIBT3C is not set
-# CONFIG_BT_HCIBTSDIO is not set
-# CONFIG_BT_HCIBTUART is not set
-# CONFIG_BT_HCIBTUSB is not set
-# CONFIG_BT_HCIDTL1 is not set
-# CONFIG_BT_HCIUART is not set
-# CONFIG_BT_HCIUART_ATH3K is not set
-CONFIG_BT_HCIUART_BCSP=y
-CONFIG_BT_HCIUART_H4=y
-# CONFIG_BT_HCIUART_LL is not set
-# CONFIG_BT_HCIVHCI is not set
-# CONFIG_BT_HIDP is not set
-# CONFIG_BT_L2CAP is not set
-# CONFIG_BT_MRVL is not set
-# CONFIG_BT_RFCOMM is not set
-CONFIG_BT_RFCOMM_TTY=y
-# CONFIG_BT_SCO is not set
-CONFIG_BUG=y
-# CONFIG_C2PORT is not set
-# CONFIG_CAIF is not set
-# CONFIG_CAN is not set
-# CONFIG_CAPI_AVM is not set
-# CONFIG_CAPI_EICON is not set
-# CONFIG_CAPI_TRACE is not set
-CONFIG_CARDBUS=y
-# CONFIG_CARDMAN_4000 is not set
-# CONFIG_CARDMAN_4040 is not set
-# CONFIG_CASSINI is not set
-CONFIG_CAVIUM_OCTEON_HELPER=y
-# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
-# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
-# CONFIG_CB710_CORE is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
-# CONFIG_CC_STACKPROTECTOR is not set
-# CONFIG_CDROM_PKTCDVD is not set
-# CONFIG_CEPH_FS is not set
-# CONFIG_CEPH_LIB is not set
-# CONFIG_CFG80211 is not set
-# CONFIG_CGROUPS is not set
-# CONFIG_CHARGER_GPIO is not set
-# CONFIG_CHELSIO_T1 is not set
-# CONFIG_CHELSIO_T3 is not set
-# CONFIG_CHELSIO_T4 is not set
-# CONFIG_CHELSIO_T4VF is not set
-# CONFIG_CHR_DEV_OSST is not set
-# CONFIG_CHR_DEV_SCH is not set
-# CONFIG_CHR_DEV_SG is not set
-# CONFIG_CHR_DEV_ST is not set
-# CONFIG_CICADA_PHY is not set
-# CONFIG_CIFS is not set
-# CONFIG_CIFS_DEBUG2 is not set
-# CONFIG_CIFS_EXPERIMENTAL is not set
-CONFIG_CIFS_POSIX=y
-CONFIG_CIFS_STATS=y
-# CONFIG_CIFS_STATS2 is not set
-# CONFIG_CIFS_WEAK_PW_HASH is not set
-# CONFIG_CIFS_XATTR is not set
-CONFIG_CLS_U32_MARK=y
-CONFIG_CLS_U32_PERF=y
-CONFIG_CMDLINE=""
-# CONFIG_CMDLINE_BOOL is not set
-# CONFIG_CMDLINE_FORCE is not set
-# CONFIG_CNIC is not set
-# CONFIG_CODA_FS is not set
-# CONFIG_CODE_PATCHING_SELFTEST is not set
-# CONFIG_COMEDI is not set
-# CONFIG_COMPACTION is not set
-# CONFIG_COMPAT_BRK is not set
-# CONFIG_CONFIGFS_FS is not set
-# CONFIG_CONNECTOR is not set
-CONFIG_CONSTRUCTORS=y
-# CONFIG_CONTEXT_SWITCH_TRACER is not set
-# CONFIG_COPS is not set
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-# CONFIG_CPU_DCACHE_DISABLE is not set
-# CONFIG_CPU_FREQ is not set
-# CONFIG_CPU_IDLE is not set
-# CONFIG_CRAMFS is not set
-CONFIG_CRASHLOG=y
-# CONFIG_CRASH_DUMP is not set
-# CONFIG_CRC16 is not set
-CONFIG_CRC32=y
-# CONFIG_CRC7 is not set
-# CONFIG_CRC_CCITT is not set
-# CONFIG_CRC_ITU_T is not set
-# CONFIG_CRC_T10DIF is not set
-CONFIG_CROSS_COMPILE=""
-CONFIG_CRYPTO=y
-# CONFIG_CRYPTO_AEAD is not set
-# CONFIG_CRYPTO_AES is not set
-# CONFIG_CRYPTO_AES_586 is not set
-# CONFIG_CRYPTO_AES_NI_INTEL is not set
-# CONFIG_CRYPTO_ALGAPI is not set
-# CONFIG_CRYPTO_ALGAPI2 is not set
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_ANUBIS is not set
-# CONFIG_CRYPTO_ARC4 is not set
-# CONFIG_CRYPTO_AUTHENC is not set
-# CONFIG_CRYPTO_BLKCIPHER is not set
-# CONFIG_CRYPTO_BLOWFISH is not set
-# CONFIG_CRYPTO_CAMELLIA is not set
-# CONFIG_CRYPTO_CAST5 is not set
-# CONFIG_CRYPTO_CAST6 is not set
-# CONFIG_CRYPTO_CBC is not set
-# CONFIG_CRYPTO_CCM is not set
-# CONFIG_CRYPTO_CRC32C is not set
-# CONFIG_CRYPTO_CRC32C_INTEL is not set
-# CONFIG_CRYPTO_CRYPTD is not set
-# CONFIG_CRYPTO_CTR is not set
-# CONFIG_CRYPTO_CTS is not set
-# CONFIG_CRYPTO_DEFLATE is not set
-# CONFIG_CRYPTO_DES is not set
-# CONFIG_CRYPTO_DEV_HIFN_795X is not set
-# CONFIG_CRYPTO_DEV_MV_CESA is not set
-# CONFIG_CRYPTO_DEV_TALITOS is not set
-# CONFIG_CRYPTO_ECB is not set
-# CONFIG_CRYPTO_FCRYPT is not set
-# CONFIG_CRYPTO_FIPS is not set
-# CONFIG_CRYPTO_GCM is not set
-# CONFIG_CRYPTO_GF128MUL is not set
-# CONFIG_CRYPTO_GHASH is not set
-# CONFIG_CRYPTO_GHASH_CLMUL_NI_INTEL is not set
-# CONFIG_CRYPTO_HASH is not set
-# CONFIG_CRYPTO_HMAC is not set
-# CONFIG_CRYPTO_HW is not set
-# CONFIG_CRYPTO_KHAZAD is not set
-# CONFIG_CRYPTO_LRW is not set
-# CONFIG_CRYPTO_LZO is not set
-# CONFIG_CRYPTO_MANAGER is not set
-# CONFIG_CRYPTO_MANAGER2 is not set
-CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
-# CONFIG_CRYPTO_MD4 is not set
-# CONFIG_CRYPTO_MD5 is not set
-# CONFIG_CRYPTO_MICHAEL_MIC is not set
-# CONFIG_CRYPTO_NULL is not set
-# CONFIG_CRYPTO_PCBC is not set
-# CONFIG_CRYPTO_PCOMP is not set
-# CONFIG_CRYPTO_PCOMP2 is not set
-# CONFIG_CRYPTO_PCRYPT is not set
-# CONFIG_CRYPTO_RMD128 is not set
-# CONFIG_CRYPTO_RMD160 is not set
-# CONFIG_CRYPTO_RMD256 is not set
-# CONFIG_CRYPTO_RMD320 is not set
-# CONFIG_CRYPTO_RNG is not set
-# CONFIG_CRYPTO_SALSA20 is not set
-# CONFIG_CRYPTO_SALSA20_586 is not set
-# CONFIG_CRYPTO_SEED is not set
-# CONFIG_CRYPTO_SEQIV is not set
-# CONFIG_CRYPTO_SERPENT is not set
-# CONFIG_CRYPTO_SHA1 is not set
-# CONFIG_CRYPTO_SHA256 is not set
-# CONFIG_CRYPTO_SHA512 is not set
-# CONFIG_CRYPTO_TEA is not set
-# CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_TGR192 is not set
-# CONFIG_CRYPTO_TWOFISH is not set
-# CONFIG_CRYPTO_TWOFISH_586 is not set
-# CONFIG_CRYPTO_TWOFISH_COMMON is not set
-# CONFIG_CRYPTO_USER_API_HASH is not set
-# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
-# CONFIG_CRYPTO_VMAC is not set
-# CONFIG_CRYPTO_WP512 is not set
-# CONFIG_CRYPTO_XCBC is not set
-# CONFIG_CRYPTO_XTS is not set
-# CONFIG_CRYPTO_ZLIB is not set
-# CONFIG_CRYSTALHD is not set
-# CONFIG_CS5535_MFGPT is not set
-# CONFIG_CUSE is not set
-# CONFIG_CXT1E1 is not set
-# CONFIG_DAB is not set
-# CONFIG_DAVICOM_PHY is not set
-# CONFIG_DCB is not set
-# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_DEBUG_CREDENTIALS is not set
-# CONFIG_DEBUG_DEVRES is not set
-# CONFIG_DEBUG_DRIVER is not set
-# CONFIG_DEBUG_ERRORS is not set
-# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
-CONFIG_DEBUG_FS=y
-# CONFIG_DEBUG_GPIO is not set
-# CONFIG_DEBUG_ICEDCC is not set
-# CONFIG_DEBUG_INFO is not set
-CONFIG_DEBUG_INFO_REDUCED=y
-# CONFIG_DEBUG_KERNEL is not set
-# CONFIG_DEBUG_KMEMLEAK is not set
-# CONFIG_DEBUG_KOBJECT is not set
-# CONFIG_DEBUG_LIST is not set
-# CONFIG_DEBUG_LL is not set
-# CONFIG_DEBUG_LOCKDEP is not set
-# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
-# CONFIG_DEBUG_LOCK_ALLOC is not set
-# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_DEBUG_MUTEXES is not set
-# CONFIG_DEBUG_NOTIFIERS is not set
-# CONFIG_DEBUG_OBJECTS is not set
-# CONFIG_DEBUG_PAGEALLOC is not set
-# CONFIG_DEBUG_PREEMPT is not set
-# CONFIG_DEBUG_RODATA is not set
-# CONFIG_DEBUG_RT_MUTEXES is not set
-# CONFIG_DEBUG_SET_MODULE_RONX is not set
-# CONFIG_DEBUG_SG is not set
-# CONFIG_DEBUG_SHIRQ is not set
-# CONFIG_DEBUG_SLAB is not set
-# CONFIG_DEBUG_SPINLOCK is not set
-# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
-# CONFIG_DEBUG_STACKOVERFLOW is not set
-# CONFIG_DEBUG_STACK_USAGE is not set
-# CONFIG_DEBUG_VM is not set
-# CONFIG_DEBUG_WRITECOUNT is not set
-# CONFIG_DECNET is not set
-CONFIG_DECOMPRESS_LZMA_NEEDED=y
-CONFIG_DEFAULT_DEADLINE=y
-CONFIG_DEFAULT_IOSCHED="deadline"
-CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
-# CONFIG_DEFAULT_NOOP is not set
-# CONFIG_DEFAULT_RENO is not set
-CONFIG_DEFAULT_SECURITY=""
-CONFIG_DEFAULT_SECURITY_DAC=y
-CONFIG_DEFAULT_TCP_CONG="westwood"
-CONFIG_DEFAULT_WESTWOOD=y
-CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-# CONFIG_DEPRECATED_PARAM_STRUCT is not set
-# CONFIG_DETECT_HUNG_TASK is not set
-# CONFIG_DEVKMEM is not set
-CONFIG_DEVPORT=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-# CONFIG_DEVTMPFS is not set
-# CONFIG_DEVTMPFS_MOUNT is not set
-# CONFIG_DISCONTIGMEM_MANUAL is not set
-# CONFIG_DISPLAY_SUPPORT is not set
-# CONFIG_DL2K is not set
-# CONFIG_DLM is not set
-# CONFIG_DM9000 is not set
-# CONFIG_DMADEVICES is not set
-# CONFIG_DMADEVICES_DEBUG is not set
-# CONFIG_DMASCC is not set
-# CONFIG_DMATEST is not set
-# CONFIG_DMA_API_DEBUG is not set
-# CONFIG_DMA_ENGINE is not set
-# CONFIG_DM_LOG_USERSPACE is not set
-# CONFIG_DM_RAID is not set
-# CONFIG_DNET is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_DRAGONRISE_FF is not set
-# CONFIG_DRM is not set
-# CONFIG_DS1682 is not set
-# CONFIG_DTLK is not set
-# CONFIG_DUMMY is not set
-# CONFIG_DVB_CORE is not set
-# CONFIG_DX_SEP is not set
-# CONFIG_DYNAMIC_DEBUG is not set
-# CONFIG_E100 is not set
-# CONFIG_E1000 is not set
-# CONFIG_E1000E is not set
-# CONFIG_EASYCAP is not set
-# CONFIG_ECHO is not set
-# CONFIG_ECONET is not set
-# CONFIG_EDAC is not set
-# CONFIG_EEPROM_93CX6 is not set
-# CONFIG_EEPROM_AT24 is not set
-# CONFIG_EEPROM_AT25 is not set
-# CONFIG_EEPROM_LEGACY is not set
-# CONFIG_EEPROM_MAX6875 is not set
-CONFIG_EFI_PARTITION=y
-# CONFIG_EFS_FS is not set
-# CONFIG_ELF_CORE is not set
-CONFIG_EMBEDDED=y
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_ENABLE_WARN_DEPRECATED=y
-# CONFIG_ENC28J60 is not set
-# CONFIG_ENCLOSURE_SERVICES is not set
-# CONFIG_EPIC100 is not set
-CONFIG_EPOLL=y
-# CONFIG_EQUALIZER is not set
-# CONFIG_ET131X is not set
-# CONFIG_ETHOC is not set
-CONFIG_EVENTFD=y
-CONFIG_EXPERIMENTAL=y
-CONFIG_EXPERT=y
-# CONFIG_EXPORTFS is not set
-# CONFIG_EXT2_FS is not set
-# CONFIG_EXT2_FS_XATTR is not set
-# CONFIG_EXT2_FS_XIP is not set
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-# CONFIG_EXT3_FS is not set
-# CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_EXT4_DEBUG is not set
-# CONFIG_EXT4_FS is not set
-# CONFIG_EXT4_FS_POSIX_ACL is not set
-# CONFIG_EXT4_FS_SECURITY is not set
-CONFIG_EXT4_FS_XATTR=y
-CONFIG_EXT4_USE_FOR_EXT23=y
-CONFIG_EXTRA_FIRMWARE=""
-CONFIG_EXTRA_TARGETS=""
-# CONFIG_EZX_PCAP is not set
-# CONFIG_FAIR_GROUP_SCHED is not set
-# CONFIG_FANOTIFY is not set
-CONFIG_FAT_DEFAULT_CODEPAGE=437
-CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
-# CONFIG_FAT_FS is not set
-# CONFIG_FAULT_INJECTION is not set
-# CONFIG_FB is not set
-# CONFIG_FB_3DFX is not set
-# CONFIG_FB_ARC is not set
-# CONFIG_FB_ARK is not set
-# CONFIG_FB_ASILIANT is not set
-# CONFIG_FB_ATY is not set
-# CONFIG_FB_ATY128 is not set
-# CONFIG_FB_BACKLIGHT is not set
-# CONFIG_FB_BOOT_VESA_SUPPORT is not set
-# CONFIG_FB_BROADSHEET is not set
-# CONFIG_FB_CARMINE is not set
-# CONFIG_FB_CFB_COPYAREA is not set
-# CONFIG_FB_CFB_FILLRECT is not set
-# CONFIG_FB_CFB_IMAGEBLIT is not set
-# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
-# CONFIG_FB_CIRRUS is not set
-# CONFIG_FB_CYBER2000 is not set
-# CONFIG_FB_DDC is not set
-# CONFIG_FB_FOREIGN_ENDIAN is not set
-# CONFIG_FB_GEODE is not set
-# CONFIG_FB_HGA is not set
-# CONFIG_FB_IBM_GXT4500 is not set
-# CONFIG_FB_IMSTT is not set
-# CONFIG_FB_KYRO is not set
-# CONFIG_FB_LE80578 is not set
-# CONFIG_FB_MACMODES is not set
-# CONFIG_FB_MATROX is not set
-# CONFIG_FB_MB862XX is not set
-# CONFIG_FB_METRONOME is not set
-# CONFIG_FB_MODE_HELPERS is not set
-# CONFIG_FB_N411 is not set
-# CONFIG_FB_NEOMAGIC is not set
-# CONFIG_FB_NVIDIA is not set
-# CONFIG_FB_OF is not set
-# CONFIG_FB_PM2 is not set
-# CONFIG_FB_PM3 is not set
-# CONFIG_FB_PS3 is not set
-# CONFIG_FB_PXA is not set
-# CONFIG_FB_RADEON is not set
-# CONFIG_FB_RIVA is not set
-# CONFIG_FB_S1D13XXX is not set
-# CONFIG_FB_S3 is not set
-# CONFIG_FB_SAVAGE is not set
-# CONFIG_FB_SIS is not set
-# CONFIG_FB_SVGALIB is not set
-# CONFIG_FB_SYS_COPYAREA is not set
-# CONFIG_FB_SYS_FILLRECT is not set
-# CONFIG_FB_SYS_FOPS is not set
-# CONFIG_FB_SYS_IMAGEBLIT is not set
-# CONFIG_FB_TILEBLITTING is not set
-# CONFIG_FB_TRIDENT is not set
-# CONFIG_FB_UDL is not set
-# CONFIG_FB_VGA16 is not set
-# CONFIG_FB_VIA is not set
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FB_VOODOO1 is not set
-# CONFIG_FB_VT8623 is not set
-# CONFIG_FCOE is not set
-# CONFIG_FCOE_FNIC is not set
-# CONFIG_FDDI is not set
-# CONFIG_FEALNX is not set
-CONFIG_FIB_RULES=y
-CONFIG_FILE_LOCKING=y
-# CONFIG_FIREWIRE is not set
-# CONFIG_FIREWIRE_NOSY is not set
-# CONFIG_FIRMWARE_IN_KERNEL is not set
-# CONFIG_FIXED_PHY is not set
-CONFIG_FLATMEM=y
-CONFIG_FLATMEM_MANUAL=y
-CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_FORCEDETH is not set
-CONFIG_FORCE_MAX_ZONEORDER=11
-# CONFIG_FRAMEBUFFER_CONSOLE is not set
-CONFIG_FRAME_WARN=1024
-# CONFIG_FREEZER is not set
-# CONFIG_FSCACHE is not set
-CONFIG_FSNOTIFY=y
-# CONFIG_FS_POSIX_ACL is not set
-# CONFIG_FT1000 is not set
-# CONFIG_FTL is not set
-# CONFIG_FTRACE is not set
-# CONFIG_FTRACE_STARTUP_TEST is not set
-# CONFIG_FTR_FIXUP_SELFTEST is not set
-# CONFIG_FUNCTION_TRACER is not set
-# CONFIG_FUSE_FS is not set
-# CONFIG_FUSION is not set
-# CONFIG_FUSION_FC is not set
-# CONFIG_FUSION_SAS is not set
-# CONFIG_FUSION_SPI is not set
-CONFIG_FUTEX=y
-CONFIG_FW_LOADER=y
-CONFIG_GACT_PROB=y
-# CONFIG_GAMEPORT is not set
-# CONFIG_GCOV_KERNEL is not set
-CONFIG_GENERIC_CALIBRATE_DELAY=y
-CONFIG_GENERIC_HARDIRQS=y
-CONFIG_GENERIC_HWEIGHT=y
-CONFIG_GENERIC_IRQ_PROBE=y
-CONFIG_GENERIC_TIME=y
-# CONFIG_GFS2_FS is not set
-# CONFIG_GIGASET_CAPI is not set
-# CONFIG_GIGASET_DEBUG is not set
-# CONFIG_GPIOLIB is not set
-# CONFIG_GPIO_74X164 is not set
-# CONFIG_GPIO_ADP5588 is not set
-# CONFIG_GPIO_BASIC_MMIO is not set
-# CONFIG_GPIO_BT8XX is not set
-# CONFIG_GPIO_CS5535 is not set
-# CONFIG_GPIO_DEVICE is not set
-# CONFIG_GPIO_IT8761E is not set
-# CONFIG_GPIO_LANGWELL is not set
-# CONFIG_GPIO_MAX7300 is not set
-# CONFIG_GPIO_MAX7301 is not set
-# CONFIG_GPIO_MAX732X is not set
-# CONFIG_GPIO_MC33880 is not set
-# CONFIG_GPIO_MCP23S08 is not set
-# CONFIG_GPIO_ML_IOH is not set
-# CONFIG_GPIO_PCA953X is not set
-# CONFIG_GPIO_PCF857X is not set
-# CONFIG_GPIO_PCH is not set
-# CONFIG_GPIO_RDC321X is not set
-# CONFIG_GPIO_SCH is not set
-# CONFIG_GPIO_SX150X is not set
-# CONFIG_GPIO_SYSFS is not set
-# CONFIG_GPIO_VX855 is not set
-# CONFIG_GPIO_XILINX is not set
-# CONFIG_GREENASIA_FF is not set
-# CONFIG_HAMACHI is not set
-CONFIG_HAMRADIO=y
-# CONFIG_HAPPYMEAL is not set
-# CONFIG_HARDLOCKUP_DETECTOR is not set
-# CONFIG_HAVE_AOUT is not set
-CONFIG_HAVE_KPROBES=y
-CONFIG_HAVE_KRETPROBES=y
-# CONFIG_HCALL_STATS is not set
-# CONFIG_HDLC is not set
-# CONFIG_HDLC_CISCO is not set
-# CONFIG_HDLC_FR is not set
-# CONFIG_HDLC_PPP is not set
-# CONFIG_HDLC_RAW is not set
-# CONFIG_HDLC_RAW_ETH is not set
-# CONFIG_HEADERS_CHECK is not set
-# CONFIG_HERMES is not set
-# CONFIG_HFSPLUS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_HID is not set
-# CONFIG_HIDRAW is not set
-# CONFIG_HID_3M_PCT is not set
-# CONFIG_HID_A4TECH is not set
-# CONFIG_HID_ACRUX_FF is not set
-# CONFIG_HID_APPLE is not set
-# CONFIG_HID_BELKIN is not set
-# CONFIG_HID_CANDO is not set
-# CONFIG_HID_CHERRY is not set
-# CONFIG_HID_CHICONY is not set
-# CONFIG_HID_CYPRESS is not set
-# CONFIG_HID_DRAGONRISE is not set
-# CONFIG_HID_EGALAX is not set
-# CONFIG_HID_ELECOM is not set
-# CONFIG_HID_EMS_FF is not set
-# CONFIG_HID_EZKEY is not set
-# CONFIG_HID_GREENASIA is not set
-# CONFIG_HID_GYRATION is not set
-# CONFIG_HID_KENSINGTON is not set
-# CONFIG_HID_KYE is not set
-# CONFIG_HID_LOGITECH is not set
-# CONFIG_HID_MAGICMOUSE is not set
-# CONFIG_HID_MICROSOFT is not set
-# CONFIG_HID_MONTEREY is not set
-# CONFIG_HID_MOSART is not set
-# CONFIG_HID_MULTITOUCH is not set
-# CONFIG_HID_NTRIG is not set
-# CONFIG_HID_ORTEK is not set
-# CONFIG_HID_PANTHERLORD is not set
-# CONFIG_HID_PETALYNX is not set
-# CONFIG_HID_PICOLCD is not set
-# CONFIG_HID_PID is not set
-# CONFIG_HID_PRODIKEYS is not set
-# CONFIG_HID_QUANTA is not set
-# CONFIG_HID_ROCCAT is not set
-# CONFIG_HID_ROCCAT_KONE is not set
-# CONFIG_HID_ROCCAT_KONEPLUS is not set
-# CONFIG_HID_ROCCAT_PYRA is not set
-# CONFIG_HID_SAMSUNG is not set
-# CONFIG_HID_SMARTJOYPLUS is not set
-# CONFIG_HID_SONY is not set
-# CONFIG_HID_STANTUM is not set
-# CONFIG_HID_SUNPLUS is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_HID_THRUSTMASTER is not set
-# CONFIG_HID_TOPSEED is not set
-# CONFIG_HID_TWINHAN is not set
-# CONFIG_HID_UCLOGIC is not set
-# CONFIG_HID_WACOM is not set
-# CONFIG_HID_WALTOP is not set
-# CONFIG_HID_ZEROPLUS is not set
-# CONFIG_HID_ZYDACRON is not set
-# CONFIG_HID_ACRUX is not set
-# CONFIG_HIGHMEM is not set
-CONFIG_HIGH_RES_TIMERS=y
-# CONFIG_HIPPI is not set
-# CONFIG_HMC6352 is not set
-# CONFIG_HOSTAP is not set
-# CONFIG_HOSTAP_CS is not set
-# CONFIG_HOSTAP_PCI is not set
-# CONFIG_HOSTAP_PLX is not set
-CONFIG_HOTPLUG=y
-# CONFIG_HOTPLUG_CPU is not set
-# CONFIG_HOTPLUG_PCI is not set
-# CONFIG_HP100 is not set
-# CONFIG_HPFS_FS is not set
-# CONFIG_HP_ILO is not set
-# CONFIG_HTC_EGPIO is not set
-# CONFIG_HTC_I2CPLD is not set
-# CONFIG_HTC_PASIC3 is not set
-# CONFIG_HUGETLB_PAGE is not set
-# CONFIG_HVC_DCC is not set
-# CONFIG_HVC_UDBG is not set
-# CONFIG_HWMON is not set
-# CONFIG_HWMON_VID is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HW_RANDOM_AMD is not set
-# CONFIG_HW_RANDOM_GEODE is not set
-# CONFIG_HW_RANDOM_INTEL is not set
-# CONFIG_HW_RANDOM_TIMERIOMEM is not set
-# CONFIG_HW_RANDOM_VIA is not set
-# CONFIG_HYPERV is not set
-# CONFIG_HYSDN is not set
-CONFIG_HZ=100
-CONFIG_HZ_100=y
-# CONFIG_HZ_1000 is not set
-# CONFIG_HZ_1024 is not set
-# CONFIG_HZ_128 is not set
-# CONFIG_HZ_250 is not set
-# CONFIG_HZ_256 is not set
-# CONFIG_HZ_300 is not set
-# CONFIG_HZ_48 is not set
-# CONFIG_I2C is not set
-# CONFIG_I2C_ALGOBIT is not set
-# CONFIG_I2C_ALGOPCA is not set
-# CONFIG_I2C_ALGOPCF is not set
-# CONFIG_I2C_ALI1535 is not set
-# CONFIG_I2C_ALI1563 is not set
-# CONFIG_I2C_ALI15X3 is not set
-# CONFIG_I2C_AMD756 is not set
-# CONFIG_I2C_AMD8111 is not set
-# CONFIG_I2C_CHARDEV is not set
-# CONFIG_I2C_COMPAT is not set
-# CONFIG_I2C_DEBUG_ALGO is not set
-# CONFIG_I2C_DEBUG_BUS is not set
-# CONFIG_I2C_DEBUG_CORE is not set
-# CONFIG_I2C_DESIGNWARE is not set
-# CONFIG_I2C_EG20T is not set
-# CONFIG_I2C_ELEKTOR is not set
-# CONFIG_I2C_GPIO is not set
-# CONFIG_I2C_HELPER_AUTO is not set
-# CONFIG_I2C_I801 is not set
-# CONFIG_I2C_IBM_IIC is not set
-# CONFIG_I2C_INTEL_MID is not set
-# CONFIG_I2C_ISCH is not set
-# CONFIG_I2C_MPC is not set
-# CONFIG_I2C_MUX is not set
-# CONFIG_I2C_NFORCE2 is not set
-# CONFIG_I2C_OCORES is not set
-# CONFIG_I2C_PARPORT is not set
-# CONFIG_I2C_PARPORT_LIGHT is not set
-# CONFIG_I2C_PCA_ISA is not set
-# CONFIG_I2C_PCA_PLATFORM is not set
-# CONFIG_I2C_PIIX4 is not set
-# CONFIG_I2C_SIMTEC is not set
-# CONFIG_I2C_SCMI is not set
-# CONFIG_I2C_SIS5595 is not set
-# CONFIG_I2C_SIS630 is not set
-# CONFIG_I2C_SIS96X is not set
-# CONFIG_I2C_SMBUS is not set
-# CONFIG_I2C_STUB is not set
-# CONFIG_I2C_TAOS_EVM is not set
-# CONFIG_I2C_TINY_USB is not set
-# CONFIG_I2C_VIA is not set
-# CONFIG_I2C_VIAPRO is not set
-# CONFIG_I2C_XILINX is not set
-# CONFIG_I2O is not set
-# CONFIG_I82092 is not set
-# CONFIG_I82365 is not set
-# CONFIG_IBM_ASM is not set
-# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
-# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
-# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
-# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
-# CONFIG_IBM_NEW_EMAC_RGMII is not set
-# CONFIG_IBM_NEW_EMAC_TAH is not set
-# CONFIG_IBM_NEW_EMAC_ZMII is not set
-# CONFIG_ICPLUS_PHY is not set
-# CONFIG_ICS932S401 is not set
-# CONFIG_IDE is not set
-# CONFIG_IDE_GD is not set
-# CONFIG_IDE_PHISON is not set
-# CONFIG_IDE_PROC_FS is not set
-# CONFIG_IDE_TASK_IOCTL is not set
-# CONFIG_IDEAPAD_LAPTOP is not set
-# CONFIG_IEEE802154 is not set
-# CONFIG_IFB is not set
-# CONFIG_IGB is not set
-# CONFIG_IGBVF is not set
-# CONFIG_IIO is not set
-# CONFIG_IKCONFIG is not set
-# CONFIG_IKCONFIG_PROC is not set
-# CONFIG_IMAGE_CMDLINE_HACK is not set
-CONFIG_INET=y
-# CONFIG_INET6_AH is not set
-# CONFIG_INET6_ESP is not set
-# CONFIG_INET6_IPCOMP is not set
-# CONFIG_INET6_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
-# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_TUNNEL is not set
-# CONFIG_INET_AH is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_INET_ESP is not set
-# CONFIG_INET_IPCOMP is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_TCP_DIAG is not set
-# CONFIG_INET_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_TUNNEL is not set
-# CONFIG_INFINIBAND is not set
-# CONFIG_INFTL is not set
-# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
-# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
-# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
-CONFIG_INITRAMFS_COMPRESSION_NONE=y
-CONFIG_INIT_ENV_ARG_LIMIT=32
-# CONFIG_INLINE_READ_LOCK is not set
-# CONFIG_INLINE_READ_LOCK_BH is not set
-# CONFIG_INLINE_READ_LOCK_IRQ is not set
-# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
-# CONFIG_INLINE_READ_TRYLOCK is not set
-CONFIG_INLINE_READ_UNLOCK=y
-# CONFIG_INLINE_READ_UNLOCK_BH is not set
-CONFIG_INLINE_READ_UNLOCK_IRQ=y
-# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_SPIN_LOCK is not set
-# CONFIG_INLINE_SPIN_LOCK_BH is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
-# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
-# CONFIG_INLINE_SPIN_TRYLOCK is not set
-# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
-CONFIG_INLINE_SPIN_UNLOCK=y
-# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
-CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
-# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
-# CONFIG_INLINE_WRITE_LOCK is not set
-# CONFIG_INLINE_WRITE_LOCK_BH is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
-# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
-# CONFIG_INLINE_WRITE_TRYLOCK is not set
-CONFIG_INLINE_WRITE_UNLOCK=y
-# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
-CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
-# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
-CONFIG_INOTIFY_USER=y
-# CONFIG_INPUT is not set
-# CONFIG_INPUT_AD714X is not set
-# CONFIG_INPUT_ADXL34X is not set
-# CONFIG_INPUT_APANEL is not set
-# CONFIG_INPUT_ATI_REMOTE is not set
-# CONFIG_INPUT_ATI_REMOTE2 is not set
-# CONFIG_INPUT_ATLAS_BTNS is not set
-# CONFIG_INPUT_CMA3000 is not set
-# CONFIG_INPUT_CM109 is not set
-# CONFIG_INPUT_EVBUG is not set
-# CONFIG_INPUT_EVDEV is not set
-# CONFIG_INPUT_FF_MEMLESS is not set
-# CONFIG_INPUT_GPIO is not set
-# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_JOYSTICK is not set
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_KEYSPAN_REMOTE is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-# CONFIG_INPUT_PCF8574 is not set
-# CONFIG_INPUT_PCSPKR is not set
-# CONFIG_INPUT_POLLDEV is not set
-# CONFIG_INPUT_POWERMATE is not set
-# CONFIG_INPUT_SPARSEKMAP is not set
-# CONFIG_INPUT_TABLET is not set
-# CONFIG_INPUT_TOUCHSCREEN is not set
-# CONFIG_INPUT_UINPUT is not set
-# CONFIG_INPUT_WINBOND_CIR is not set
-# CONFIG_INPUT_WISTRON_BTNS is not set
-# CONFIG_INPUT_YEALINK is not set
-# CONFIG_INTEL_IDLE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_IOSCHED_DEADLINE=y
-CONFIG_IOSCHED_NOOP=y
-# CONFIG_IP1000 is not set
-# CONFIG_IP17XX_PHY is not set
-# CONFIG_IP6_NF_FILTER is not set
-# CONFIG_IP6_NF_IPTABLES is not set
-# CONFIG_IP6_NF_MANGLE is not set
-# CONFIG_IP6_NF_MATCH_AH is not set
-# CONFIG_IP6_NF_MATCH_EUI64 is not set
-# CONFIG_IP6_NF_MATCH_FRAG is not set
-# CONFIG_IP6_NF_MATCH_HL is not set
-# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set
-# CONFIG_IP6_NF_MATCH_MH is not set
-# CONFIG_IP6_NF_MATCH_OPTS is not set
-# CONFIG_IP6_NF_MATCH_RT is not set
-# CONFIG_IP6_NF_QUEUE is not set
-# CONFIG_IP6_NF_RAW is not set
-# CONFIG_IP6_NF_TARGET_HL is not set
-# CONFIG_IP6_NF_TARGET_LOG is not set
-# CONFIG_IP6_NF_TARGET_REJECT is not set
-# CONFIG_IPC_NS is not set
-# CONFIG_IPMI_HANDLER is not set
-# CONFIG_IPV6 is not set
-# CONFIG_IPV6_MIP6 is not set
-# CONFIG_IPV6_MROUTE is not set
-# CONFIG_IPV6_MROUTE_MULTIPLE_TABLES is not set
-# CONFIG_IPV6_MULTIPLE_TABLES is not set
-CONFIG_IPV6_NDISC_NODETYPE=y
-# CONFIG_IPV6_OPTIMISTIC_DAD is not set
-# CONFIG_IPV6_PRIVACY is not set
-# CONFIG_IPV6_ROUTER_PREF is not set
-# CONFIG_IPV6_ROUTE_INFO is not set
-# CONFIG_IPV6_SIT is not set
-# CONFIG_IPV6_SIT_6RD is not set
-# CONFIG_IPV6_TUNNEL is not set
-# CONFIG_IPW2100 is not set
-# CONFIG_IPW2100_DEBUG is not set
-CONFIG_IPW2100_MONITOR=y
-# CONFIG_IPW2200 is not set
-# CONFIG_IPW2200_DEBUG is not set
-CONFIG_IPW2200_MONITOR=y
-# CONFIG_IPW2200_PROMISCUOUS is not set
-# CONFIG_IPW2200_QOS is not set
-# CONFIG_IPW2200_RADIOTAP is not set
-# CONFIG_IPWIRELESS is not set
-# CONFIG_IPX is not set
-CONFIG_IP_ADVANCED_ROUTER=y
-# CONFIG_IP_DCCP is not set
-CONFIG_IP_FIB_HASH=y
-# CONFIG_IP_FIB_TRIE is not set
-CONFIG_IP_MROUTE=y
-CONFIG_IP_MROUTE_MULTIPLE_TABLES=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_MULTIPLE_TABLES=y
-# CONFIG_IP_NF_ARPFILTER is not set
-# CONFIG_IP_NF_ARPTABLES is not set
-# CONFIG_IP_NF_ARP_MANGLE is not set
-# CONFIG_IP_NF_FILTER is not set
-# CONFIG_IP_NF_IPTABLES is not set
-# CONFIG_IP_NF_MANGLE is not set
-# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
-# CONFIG_IP_NF_MATCH_AH is not set
-# CONFIG_IP_NF_MATCH_ECN is not set
-# CONFIG_IP_NF_MATCH_TTL is not set
-# CONFIG_IP_NF_QUEUE is not set
-# CONFIG_IP_NF_RAW is not set
-# CONFIG_IP_NF_SECURITY is not set
-# CONFIG_IP_NF_TARGET_CLUSTERIP is not set
-# CONFIG_IP_NF_TARGET_ECN is not set
-# CONFIG_IP_NF_TARGET_LOG is not set
-# CONFIG_IP_NF_TARGET_MASQUERADE is not set
-# CONFIG_IP_NF_TARGET_NETMAP is not set
-# CONFIG_IP_NF_TARGET_REDIRECT is not set
-# CONFIG_IP_NF_TARGET_REJECT is not set
-# CONFIG_IP_NF_TARGET_TTL is not set
-# CONFIG_IP_NF_TARGET_ULOG is not set
-# CONFIG_IP_PIMSM_V1 is not set
-# CONFIG_IP_PIMSM_V2 is not set
-# CONFIG_IP_PNP is not set
-CONFIG_IP_ROUTE_MULTIPATH=y
-CONFIG_IP_ROUTE_VERBOSE=y
-# CONFIG_IP_SCTP is not set
-# CONFIG_IP_VS is not set
-# CONFIG_IRDA is not set
-# CONFIG_IRQSOFF_TRACER is not set
-# CONFIG_IR_CORE is not set
-# CONFIG_IR_IMON is not set
-# CONFIG_IR_JVC_DECODER is not set
-# CONFIG_IR_LIRC_CODEC is not set
-# CONFIG_IR_MCEUSB is not set
-# CONFIG_IR_NEC_DECODER is not set
-# CONFIG_IR_RC5_DECODER is not set
-# CONFIG_IR_RC5_SZ_DECODER is not set
-# CONFIG_IR_RC6_DECODER is not set
-# CONFIG_IR_SONY_DECODER is not set
-# CONFIG_IR_STREAMZAP is not set
-# CONFIG_ISCSI_BOOT_SYSFS is not set
-# CONFIG_ISCSI_TCP is not set
-CONFIG_ISDN=y
-# CONFIG_ISDN_AUDIO is not set
-# CONFIG_ISDN_CAPI is not set
-# CONFIG_ISDN_CAPI_CAPIDRV is not set
-# CONFIG_ISDN_DIVERSION is not set
-# CONFIG_ISDN_DRV_ACT2000 is not set
-# CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON is not set
-# CONFIG_ISDN_DRV_GIGASET is not set
-# CONFIG_ISDN_DRV_HISAX is not set
-# CONFIG_ISDN_DRV_ICN is not set
-# CONFIG_ISDN_DRV_LOOP is not set
-# CONFIG_ISDN_DRV_PCBIT is not set
-# CONFIG_ISDN_DRV_SC is not set
-# CONFIG_ISDN_I4L is not set
-# CONFIG_ISL29003 is not set
-# CONFIG_ISL29020 is not set
-# CONFIG_ISO9660_FS is not set
-# CONFIG_ISS4xx is not set
-# CONFIG_IWL3945 is not set
-# CONFIG_IWLAGN is not set
-# CONFIG_IWLWIFI is not set
-# CONFIG_IWMC3200TOP is not set
-# CONFIG_IXGB is not set
-# CONFIG_JBD is not set
-# CONFIG_JBD2_DEBUG is not set
-# CONFIG_JBD_DEBUG is not set
-# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
-# CONFIG_JFFS2_CMODE_NONE is not set
-CONFIG_JFFS2_CMODE_PRIORITY=y
-# CONFIG_JFFS2_CMODE_SIZE is not set
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_FS_DEBUG=0
-# CONFIG_JFFS2_FS_POSIX_ACL is not set
-# CONFIG_JFFS2_FS_SECURITY is not set
-# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
-CONFIG_JFFS2_FS_WRITEBUFFER=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_LZMA=y
-# CONFIG_JFFS2_LZO is not set
-CONFIG_JFFS2_RTIME=y
-# CONFIG_JFFS2_RUBIN is not set
-CONFIG_JFFS2_SUMMARY=y
-# CONFIG_JFFS2_ZLIB is not set
-# CONFIG_JFS_DEBUG is not set
-# CONFIG_JFS_FS is not set
-# CONFIG_JFS_POSIX_ACL is not set
-# CONFIG_JFS_SECURITY is not set
-# CONFIG_JFS_STATISTICS is not set
-# CONFIG_JME is not set
-CONFIG_JOLIET=y
-# CONFIG_JUMP_LABEL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_KALLSYMS_ALL is not set
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
-# CONFIG_KARMA_PARTITION is not set
-# CONFIG_KERNEL_BZIP2 is not set
-# CONFIG_KERNEL_GZIP is not set
-CONFIG_KERNEL_LZMA=y
-# CONFIG_KERNEL_LZO is not set
-# CONFIG_KERNEL_XZ is not set
-# CONFIG_KEXEC is not set
-# CONFIG_KEYBOARD_ADP5588 is not set
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_GPIO_POLLED is not set
-# CONFIG_KEYBOARD_LKKBD is not set
-# CONFIG_KEYBOARD_LM8323 is not set
-# CONFIG_KEYBOARD_MATRIX is not set
-# CONFIG_KEYBOARD_MAX7359 is not set
-# CONFIG_KEYBOARD_MCS is not set
-# CONFIG_KEYBOARD_NEWTON is not set
-# CONFIG_KEYBOARD_OPENCORES is not set
-# CONFIG_KEYBOARD_QT2160 is not set
-# CONFIG_KEYBOARD_STOWAWAY is not set
-# CONFIG_KEYBOARD_SUNKBD is not set
-# CONFIG_KEYBOARD_TCA6416 is not set
-# CONFIG_KEYBOARD_XTKBD is not set
-# CONFIG_KEYS is not set
-# CONFIG_KGDB is not set
-# CONFIG_KMEMCHECK is not set
-# CONFIG_KPROBES is not set
-# CONFIG_KS8842 is not set
-# CONFIG_KS8851 is not set
-# CONFIG_KS8851_MLL is not set
-# CONFIG_KSM is not set
-# CONFIG_KSZ884X_PCI is not set
-# CONFIG_KVM_GUEST is not set
-# CONFIG_L2TP is not set
-# CONFIG_L2TP_ETH is not set
-# CONFIG_L2TP_IP is not set
-# CONFIG_L2TP_V3 is not set
-# CONFIG_LANMEDIA is not set
-# CONFIG_LAPB is not set
-# CONFIG_LASAT is not set
-# CONFIG_LATENCYTOP is not set
-CONFIG_LBDAF=y
-# CONFIG_LDM_PARTITION is not set
-# CONFIG_LEDS_BD2802 is not set
-CONFIG_LEDS_CLASS=y
-# CONFIG_LEDS_DAC124S085 is not set
-CONFIG_LEDS_GPIO_PLATFORM=y
-# CONFIG_LEDS_INTEL_SS4200 is not set
-# CONFIG_LEDS_LP3944 is not set
-# CONFIG_LEDS_LP5521 is not set
-# CONFIG_LEDS_LP5523 is not set
-# CONFIG_LEDS_LT3593 is not set
-# CONFIG_LEDS_PCA9532 is not set
-# CONFIG_LEDS_PCA955X is not set
-CONFIG_LEDS_TRIGGERS=y
-# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=y
-# CONFIG_LEDS_TRIGGER_GPIO is not set
-# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
-# CONFIG_LEDS_TRIGGER_IDE_DISK is not set
-# CONFIG_LEDS_TRIGGER_MORSE is not set
-CONFIG_LEDS_TRIGGER_NETDEV=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-# CONFIG_LEDS_TRIGGER_USBDEV is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_LIB80211 is not set
-# CONFIG_LIB80211_CRYPT_CCMP is not set
-# CONFIG_LIB80211_CRYPT_TKIP is not set
-# CONFIG_LIB80211_CRYPT_WEP is not set
-# CONFIG_LIB80211_DEBUG is not set
-# CONFIG_LIBCRC32C is not set
-# CONFIG_LIBERTAS is not set
-# CONFIG_LIBERTAS_THINFIRM is not set
-# CONFIG_LIBERTAS_USB is not set
-# CONFIG_LIBFC is not set
-# CONFIG_LIBFCOE is not set
-# CONFIG_LIBIPW_DEBUG is not set
-# CONFIG_LINE6_USB is not set
-# CONFIG_LIRC_STAGING is not set
-# CONFIG_LKDTM is not set
-CONFIG_LLC=y
-# CONFIG_LLC2 is not set
-CONFIG_LOCALVERSION=""
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_LOCKD is not set
-CONFIG_LOCKDEP_SUPPORT=y
-CONFIG_LOCKD_V4=y
-# CONFIG_LOCKUP_DETECTOR is not set
-# CONFIG_LOCK_STAT is not set
-# CONFIG_LOGFS is not set
-# CONFIG_LOGIRUMBLEPAD2_FF is not set
-# CONFIG_LOGITECH_FF is not set
-# CONFIG_LOGO is not set
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_LOONGSON_MC146818 is not set
-# CONFIG_LPC_SCH is not set
-# CONFIG_LP_CONSOLE is not set
-# CONFIG_LSI_ET1011C_PHY is not set
-# CONFIG_LTPC is not set
-# CONFIG_LXT_PHY is not set
-CONFIG_LZMA_COMPRESS=y
-CONFIG_LZMA_DECOMPRESS=y
-# CONFIG_MAC80211 is not set
-# CONFIG_MACH_DECSTATION is not set
-# CONFIG_MACH_JAZZ is not set
-# CONFIG_MACH_JZ4740 is not set
-# CONFIG_MACH_LOONGSON is not set
-# CONFIG_MACH_NO_WESTBRIDGE is not set
-# CONFIG_MACH_TX39XX is not set
-# CONFIG_MACH_TX49XX is not set
-# CONFIG_MACH_VR41XX is not set
-# CONFIG_MACINTOSH_DRIVERS is not set
-# CONFIG_MACVLAN is not set
-# CONFIG_MACVTAP is not set
-# CONFIG_MAC_EMUMOUSEBTN is not set
-# CONFIG_MAC_PARTITION is not set
-# CONFIG_MAGIC_SYSRQ is not set
-# CONFIG_MARVELL_PHY is not set
-# CONFIG_MAX63XX_WATCHDOG is not set
-# CONFIG_MD is not set
-# CONFIG_MDIO_BITBANG is not set
-# CONFIG_MEDIA_ATTACH is not set
-# CONFIG_MEDIA_SUPPORT is not set
-# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
-# CONFIG_MEGARAID_LEGACY is not set
-# CONFIG_MEGARAID_NEWGEN is not set
-# CONFIG_MEGARAID_SAS is not set
-# CONFIG_MEMORY_FAILURE is not set
-# CONFIG_MEMSTICK is not set
-# CONFIG_MFD_88PM860X is not set
-# CONFIG_MFD_ASIC3 is not set
-# CONFIG_MFD_CORE is not set
-# CONFIG_MFD_CS5535 is not set
-# CONFIG_MFD_JANZ_CMODIO is not set
-# CONFIG_MFD_MAX8925 is not set
-# CONFIG_MFD_MAX8998 is not set
-# CONFIG_MFD_MC13783 is not set
-# CONFIG_MFD_MC13XXX is not set
-# CONFIG_MFD_PCF50633 is not set
-# CONFIG_MFD_RDC321X is not set
-# CONFIG_MFD_SM501 is not set
-# CONFIG_MFD_STMPE is not set
-CONFIG_MFD_SUPPORT=y
-# CONFIG_MFD_TC35892 is not set
-# CONFIG_MFD_TC3589X is not set
-# CONFIG_MFD_TC6387XB is not set
-# CONFIG_MFD_TC6393XB is not set
-# CONFIG_MFD_TIMBERDALE is not set
-# CONFIG_MFD_TMIO is not set
-# CONFIG_MFD_TPS6586X is not set
-# CONFIG_MFD_VX855 is not set
-# CONFIG_MFD_WM831X is not set
-# CONFIG_MFD_WM831X_I2C is not set
-# CONFIG_MFD_WM831X_SPI is not set
-# CONFIG_MFD_WM8350_I2C is not set
-# CONFIG_MFD_WM8400 is not set
-# CONFIG_MFD_WM8994 is not set
-# CONFIG_MG_DISK is not set
-# CONFIG_MICREL_PHY is not set
-# CONFIG_MIGRATION is not set
-CONFIG_MII=y
-# CONFIG_MIKROTIK_RB532 is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_MINIX_SUBPARTITION is not set
-# CONFIG_MIPS_ALCHEMY is not set
-# CONFIG_MIPS_COBALT is not set
-# CONFIG_MIPS_FPU_EMU is not set
-# CONFIG_MIPS_MALTA is not set
-# CONFIG_MIPS_SIM is not set
-CONFIG_MISC_DEVICES=y
-CONFIG_MISC_FILESYSTEMS=y
-# CONFIG_MISDN is not set
-# CONFIG_MISDN_AVMFRITZ is not set
-# CONFIG_MISDN_HFCPCI is not set
-# CONFIG_MISDN_HFCUSB is not set
-# CONFIG_MISDN_INFINEON is not set
-# CONFIG_MISDN_NETJET is not set
-# CONFIG_MISDN_SPEEDFAX is not set
-# CONFIG_MISDN_W6692 is not set
-# CONFIG_MKISS is not set
-# CONFIG_MMC is not set
-# CONFIG_MMC_ARMMMCI is not set
-# CONFIG_MMC_BLOCK is not set
-CONFIG_MMC_BLOCK_BOUNCE=y
-CONFIG_MMC_BLOCK_MINORS=8
-# CONFIG_MMC_CB710 is not set
-# CONFIG_MMC_CLKGATE is not set
-# CONFIG_MMC_DEBUG is not set
-# CONFIG_MMC_DW is not set
-# CONFIG_MMC_MVSDIO is not set
-# CONFIG_MMC_S3C is not set
-# CONFIG_MMC_SDHCI is not set
-# CONFIG_MMC_SDRICOH_CS is not set
-# CONFIG_MMC_SPI is not set
-# CONFIG_MMC_TEST is not set
-# CONFIG_MMC_UNSAFE_RESUME is not set
-# CONFIG_MMC_USHC is not set
-# CONFIG_MMC_VIA_SDMMC is not set
-CONFIG_MMU=y
-CONFIG_MODULES=y
-# CONFIG_MODULE_FORCE_LOAD is not set
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODVERSIONS is not set
-# CONFIG_MOUSE_APPLETOUCH is not set
-# CONFIG_MOUSE_GPIO is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
-# CONFIG_MOUSE_PS2_SENTELIC is not set
-# CONFIG_MOUSE_SYNAPTICS_I2C is not set
-# CONFIG_MSDOS_FS is not set
-CONFIG_MSDOS_PARTITION=y
-# CONFIG_MSI_BITMAP_SELFTEST is not set
-CONFIG_MTD=y
-# CONFIG_MTD_ABSENT is not set
-# CONFIG_MTD_AFS_PARTS is not set
-# CONFIG_MTD_ALAUDA is not set
-# CONFIG_MTD_AR7_PARTS is not set
-# CONFIG_MTD_ARM_INTEGRATOR is not set
-CONFIG_MTD_BLKDEVS=y
-CONFIG_MTD_BLOCK=y
-# CONFIG_MTD_BLOCK2MTD is not set
-CONFIG_MTD_CFI=y
-# CONFIG_MTD_CFI_ADV_OPTIONS is not set
-CONFIG_MTD_CFI_AMDSTD=y
-# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_I1=y
-CONFIG_MTD_CFI_I2=y
-# CONFIG_MTD_CFI_I4 is not set
-# CONFIG_MTD_CFI_I8 is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
-CONFIG_MTD_CFI_NOSWAP=y
-# CONFIG_MTD_CFI_STAA is not set
-CONFIG_MTD_CFI_UTIL=y
-CONFIG_MTD_CHAR=y
-# CONFIG_MTD_CMDLINE_PARTS is not set
-CONFIG_MTD_COMPLEX_MAPPINGS=y
-# CONFIG_MTD_CONCAT is not set
-# CONFIG_MTD_DATAFLASH is not set
-# CONFIG_MTD_DEBUG is not set
-# CONFIG_MTD_DOC2000 is not set
-# CONFIG_MTD_DOC2001 is not set
-# CONFIG_MTD_DOC2001PLUS is not set
-CONFIG_MTD_GEN_PROBE=y
-# CONFIG_MTD_GPIO_ADDR is not set
-# CONFIG_MTD_INTEL_VR_NOR is not set
-# CONFIG_MTD_JEDECPROBE is not set
-# CONFIG_MTD_LPDDR is not set
-# CONFIG_MTD_M25P80 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_1=y
-# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_2=y
-# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
-CONFIG_MTD_MAP_BANK_WIDTH_4=y
-# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
-# CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_MYLOADER_PARTS is not set
-# CONFIG_MTD_NAND is not set
-# CONFIG_MTD_NAND_CAFE is not set
-# CONFIG_MTD_NAND_DENALI is not set
-CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR=0xff108018
-# CONFIG_MTD_NAND_DISKONCHIP is not set
-# CONFIG_MTD_NAND_ECC_SMC is not set
-# CONFIG_MTD_NAND_GPIO is not set
-CONFIG_MTD_NAND_IDS=y
-# CONFIG_MTD_NAND_MUSEUM_IDS is not set
-# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_PLATFORM is not set
-# CONFIG_MTD_NAND_RICOH is not set
-# CONFIG_MTD_NAND_VERIFY_WRITE is not set
-# CONFIG_MTD_ONENAND is not set
-# CONFIG_MTD_OOPS is not set
-# CONFIG_MTD_OTP is not set
-CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_PCI is not set
-# CONFIG_MTD_PCMCIA is not set
-# CONFIG_MTD_PHRAM is not set
-# CONFIG_MTD_PHYSMAP is not set
-# CONFIG_MTD_PHYSMAP_COMPAT is not set
-# CONFIG_MTD_PLATRAM is not set
-# CONFIG_MTD_PMC551 is not set
-# CONFIG_MTD_RAM is not set
-CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
-# CONFIG_MTD_REDBOOT_PARTS is not set
-# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
-# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
-# CONFIG_MTD_ROM is not set
-CONFIG_MTD_ROOTFS_ROOT_DEV=y
-CONFIG_MTD_ROOTFS_SPLIT=y
-# CONFIG_MTD_SLRAM is not set
-# CONFIG_MTD_SST25L is not set
-# CONFIG_MTD_TESTS is not set
-# CONFIG_MTD_UBI is not set
-# CONFIG_MUTEX_SPIN_ON_OWNER is not set
-# CONFIG_MV643XX_ETH is not set
-# CONFIG_MVSWITCH_PHY is not set
-# CONFIG_MWAVE is not set
-# CONFIG_MWL8K is not set
-# CONFIG_MYRI10GE is not set
-# CONFIG_NAMESPACES is not set
-# CONFIG_NATIONAL_PHY is not set
-# CONFIG_NATSEMI is not set
-# CONFIG_NCP_FS is not set
-# CONFIG_NE2K_PCI is not set
-# CONFIG_NEC_MARKEINS is not set
-CONFIG_NET=y
-# CONFIG_NETCONSOLE is not set
-CONFIG_NETDEVICES=y
-CONFIG_NETDEV_1000=y
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_NETFILTER is not set
-# CONFIG_NETFILTER_ADVANCED is not set
-# CONFIG_NETFILTER_DEBUG is not set
-# CONFIG_NETFILTER_NETLINK is not set
-# CONFIG_NETFILTER_NETLINK_LOG is not set
-# CONFIG_NETFILTER_NETLINK_QUEUE is not set
-# CONFIG_NETFILTER_TPROXY is not set
-# CONFIG_NETFILTER_XTABLES is not set
-# CONFIG_NETFILTER_XT_CONNMARK is not set
-# CONFIG_NETFILTER_XT_MARK is not set
-# CONFIG_NETFILTER_XT_MATCH_CLUSTER is not set
-# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNMARK is not set
-# CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set
-# CONFIG_NETFILTER_XT_MATCH_CPU is not set
-# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
-# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
-# CONFIG_NETFILTER_XT_MATCH_ESP is not set
-# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
-# CONFIG_NETFILTER_XT_MATCH_HL is not set
-# CONFIG_NETFILTER_XT_MATCH_IPRANGE is not set
-# CONFIG_NETFILTER_XT_MATCH_LAYER7 is not set
-# CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG is not set
-# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set
-# CONFIG_NETFILTER_XT_MATCH_LIMIT is not set
-# CONFIG_NETFILTER_XT_MATCH_MAC is not set
-# CONFIG_NETFILTER_XT_MATCH_MARK is not set
-# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
-# CONFIG_NETFILTER_XT_MATCH_OSF is not set
-# CONFIG_NETFILTER_XT_MATCH_OWNER is not set
-# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set
-# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set
-# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
-# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
-# CONFIG_NETFILTER_XT_MATCH_RATEEST is not set
-# CONFIG_NETFILTER_XT_MATCH_REALM is not set
-# CONFIG_NETFILTER_XT_MATCH_RECENT is not set
-# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
-# CONFIG_NETFILTER_XT_MATCH_SOCKET is not set
-# CONFIG_NETFILTER_XT_MATCH_STATE is not set
-# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
-# CONFIG_NETFILTER_XT_MATCH_STRING is not set
-# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
-# CONFIG_NETFILTER_XT_MATCH_TIME is not set
-# CONFIG_NETFILTER_XT_MATCH_U32 is not set
-# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set
-# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set
-# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set
-# CONFIG_NETFILTER_XT_TARGET_CT is not set
-# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
-# CONFIG_NETFILTER_XT_TARGET_HL is not set
-# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set
-# CONFIG_NETFILTER_XT_TARGET_LED is not set
-# CONFIG_NETFILTER_XT_TARGET_MARK is not set
-# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set
-# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
-# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
-# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPMSS is not set
-# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set
-# CONFIG_NETFILTER_XT_TARGET_TEE is not set
-# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set
-# CONFIG_NETFILTER_XT_TARGET_TRACE is not set
-# CONFIG_NETPOLL is not set
-# CONFIG_NETROM is not set
-CONFIG_NETWORK_FILESYSTEMS=y
-# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
-# CONFIG_NETWORK_SECMARK is not set
-# CONFIG_NETXEN_NIC is not set
-# CONFIG_NET_9P is not set
-# CONFIG_NET_ACT_CSUM is not set
-# CONFIG_NET_ACT_GACT is not set
-# CONFIG_NET_ACT_IPT is not set
-# CONFIG_NET_ACT_MIRRED is not set
-# CONFIG_NET_ACT_NAT is not set
-# CONFIG_NET_ACT_PEDIT is not set
-# CONFIG_NET_ACT_POLICE is not set
-# CONFIG_NET_ACT_SIMP is not set
-# CONFIG_NET_ACT_SKBEDIT is not set
-CONFIG_NET_CLS=y
-# CONFIG_NET_CLS_ACT is not set
-# CONFIG_NET_CLS_BASIC is not set
-# CONFIG_NET_CLS_FLOW is not set
-# CONFIG_NET_CLS_FW is not set
-CONFIG_NET_CLS_IND=y
-# CONFIG_NET_CLS_ROUTE4 is not set
-# CONFIG_NET_CLS_RSVP is not set
-# CONFIG_NET_CLS_RSVP6 is not set
-# CONFIG_NET_CLS_TCINDEX is not set
-# CONFIG_NET_CLS_U32 is not set
-# CONFIG_NET_DROP_MONITOR is not set
-# CONFIG_NET_DSA is not set
-# CONFIG_NET_DSA_MV88E6123_61_65 is not set
-# CONFIG_NET_DSA_MV88E6131 is not set
-# CONFIG_NET_DSA_MV88E6XXX is not set
-# CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set
-# CONFIG_NET_DSA_TAG_DSA is not set
-# CONFIG_NET_DSA_TAG_EDSA is not set
-# CONFIG_NET_EMATCH is not set
-# CONFIG_NET_EMATCH_CMP is not set
-# CONFIG_NET_EMATCH_META is not set
-# CONFIG_NET_EMATCH_NBYTE is not set
-CONFIG_NET_EMATCH_STACK=32
-# CONFIG_NET_EMATCH_TEXT is not set
-# CONFIG_NET_EMATCH_U32 is not set
-CONFIG_NET_ETHERNET=y
-# CONFIG_NET_FC is not set
-# CONFIG_NET_IPGRE is not set
-CONFIG_NET_IPGRE_BROADCAST=y
-# CONFIG_NET_IPGRE_DEMUX is not set
-# CONFIG_NET_IPIP is not set
-# CONFIG_NET_ISA is not set
-# CONFIG_NET_KEY is not set
-# CONFIG_NET_KEY_MIGRATE is not set
-CONFIG_NET_PCI=y
-# CONFIG_NET_PCMCIA is not set
-# CONFIG_NET_PKTGEN is not set
-# CONFIG_NET_POCKET is not set
-# CONFIG_NET_POLL_CONTROLLER is not set
-# CONFIG_NET_SB1000 is not set
-CONFIG_NET_SCHED=y
-# CONFIG_NET_SCH_ATM is not set
-# CONFIG_NET_SCH_CBQ is not set
-# CONFIG_NET_SCH_DRR is not set
-# CONFIG_NET_SCH_DSMARK is not set
-# CONFIG_NET_SCH_ESFQ is not set
-CONFIG_NET_SCH_ESFQ_NFCT=y
-CONFIG_NET_SCH_FIFO=y
-# CONFIG_NET_SCH_GRED is not set
-# CONFIG_NET_SCH_HFSC is not set
-# CONFIG_NET_SCH_HTB is not set
-# CONFIG_NET_SCH_INGRESS is not set
-# CONFIG_NET_SCH_MULTIQ is not set
-# CONFIG_NET_SCH_NETEM is not set
-# CONFIG_NET_SCH_PRIO is not set
-# CONFIG_NET_SCH_RED is not set
-# CONFIG_NET_SCH_SFQ is not set
-# CONFIG_NET_SCH_TBF is not set
-# CONFIG_NET_SCH_TEQL is not set
-# CONFIG_NET_TULIP is not set
-# CONFIG_NET_VENDOR_3COM is not set
-CONFIG_NEW_LEDS=y
-# CONFIG_NFC_DEVICES is not set
-# CONFIG_NFSD is not set
-# CONFIG_NFSD_DEPRECATED is not set
-# CONFIG_NFSD_V2_ACL is not set
-CONFIG_NFSD_V3=y
-# CONFIG_NFSD_V3_ACL is not set
-# CONFIG_NFSD_V4 is not set
-# CONFIG_NFS_ACL_SUPPORT is not set
-CONFIG_NFS_COMMON=y
-# CONFIG_NFS_FS is not set
-CONFIG_NFS_V3=y
-# CONFIG_NFS_V3_ACL is not set
-# CONFIG_NFS_V4 is not set
-# CONFIG_NFS_V4_1 is not set
-# CONFIG_NFTL is not set
-# CONFIG_NF_CONNTRACK is not set
-# CONFIG_NF_CONNTRACK_AMANDA is not set
-# CONFIG_NF_CONNTRACK_EVENTS is not set
-# CONFIG_NF_CONNTRACK_FTP is not set
-# CONFIG_NF_CONNTRACK_H323 is not set
-# CONFIG_NF_CONNTRACK_IPV4 is not set
-# CONFIG_NF_CONNTRACK_IPV6 is not set
-# CONFIG_NF_CONNTRACK_IRC is not set
-# CONFIG_NF_CONNTRACK_MARK is not set
-# CONFIG_NF_CONNTRACK_NETBIOS_NS is not set
-# CONFIG_NF_CONNTRACK_PPTP is not set
-# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
-# CONFIG_NF_CONNTRACK_RTSP is not set
-# CONFIG_NF_CONNTRACK_SANE is not set
-# CONFIG_NF_CONNTRACK_SIP is not set
-# CONFIG_NF_CONNTRACK_TFTP is not set
-# CONFIG_NF_CONNTRACK_ZONES is not set
-# CONFIG_NF_CT_NETLINK is not set
-# CONFIG_NF_CT_PROTO_DCCP is not set
-# CONFIG_NF_CT_PROTO_GRE is not set
-# CONFIG_NF_CT_PROTO_SCTP is not set
-# CONFIG_NF_CT_PROTO_UDPLITE is not set
-# CONFIG_NF_DEFRAG_IPV4 is not set
-# CONFIG_NF_NAT is not set
-# CONFIG_NF_NAT_AMANDA is not set
-# CONFIG_NF_NAT_FTP is not set
-# CONFIG_NF_NAT_H323 is not set
-# CONFIG_NF_NAT_IRC is not set
-# CONFIG_NF_NAT_NEEDED is not set
-# CONFIG_NF_NAT_PPTP is not set
-# CONFIG_NF_NAT_PROTO_GRE is not set
-# CONFIG_NF_NAT_RTSP is not set
-# CONFIG_NF_NAT_SIP is not set
-# CONFIG_NF_NAT_SNMP_BASIC is not set
-# CONFIG_NF_NAT_TFTP is not set
-# CONFIG_NILFS2_FS is not set
-CONFIG_NLATTR=y
-# CONFIG_NLS is not set
-# CONFIG_NLS_ASCII is not set
-# CONFIG_NLS_CODEPAGE_1250 is not set
-# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_CODEPAGE_437 is not set
-# CONFIG_NLS_CODEPAGE_737 is not set
-# CONFIG_NLS_CODEPAGE_775 is not set
-# CONFIG_NLS_CODEPAGE_850 is not set
-# CONFIG_NLS_CODEPAGE_852 is not set
-# CONFIG_NLS_CODEPAGE_855 is not set
-# CONFIG_NLS_CODEPAGE_857 is not set
-# CONFIG_NLS_CODEPAGE_860 is not set
-# CONFIG_NLS_CODEPAGE_861 is not set
-# CONFIG_NLS_CODEPAGE_862 is not set
-# CONFIG_NLS_CODEPAGE_863 is not set
-# CONFIG_NLS_CODEPAGE_864 is not set
-# CONFIG_NLS_CODEPAGE_865 is not set
-# CONFIG_NLS_CODEPAGE_866 is not set
-# CONFIG_NLS_CODEPAGE_869 is not set
-# CONFIG_NLS_CODEPAGE_874 is not set
-# CONFIG_NLS_CODEPAGE_932 is not set
-# CONFIG_NLS_CODEPAGE_936 is not set
-# CONFIG_NLS_CODEPAGE_949 is not set
-# CONFIG_NLS_CODEPAGE_950 is not set
-CONFIG_NLS_DEFAULT="iso8859-1"
-# CONFIG_NLS_ISO8859_1 is not set
-# CONFIG_NLS_ISO8859_13 is not set
-# CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
-# CONFIG_NLS_ISO8859_2 is not set
-# CONFIG_NLS_ISO8859_3 is not set
-# CONFIG_NLS_ISO8859_4 is not set
-# CONFIG_NLS_ISO8859_5 is not set
-# CONFIG_NLS_ISO8859_6 is not set
-# CONFIG_NLS_ISO8859_7 is not set
-# CONFIG_NLS_ISO8859_8 is not set
-# CONFIG_NLS_ISO8859_9 is not set
-# CONFIG_NLS_KOI8_R is not set
-# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
-# CONFIG_NOP_USB_XCEIV is not set
-# CONFIG_NORTEL_HERMES is not set
-# CONFIG_NOZOMI is not set
-# CONFIG_NO_BOOTMEM is not set
-# CONFIG_NO_HZ is not set
-# CONFIG_NO_IOPORT is not set
-# CONFIG_NS83820 is not set
-# CONFIG_NTFS_DEBUG is not set
-# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
-# CONFIG_NVRAM is not set
-# CONFIG_NV_TCO is not set
-# CONFIG_NXP_STB220 is not set
-# CONFIG_NXP_STB225 is not set
-# CONFIG_N_GSM is not set
-# CONFIG_OABI_COMPAT is not set
-# CONFIG_OCFS2_FS is not set
-# CONFIG_OCF_BENCH is not set
-# CONFIG_OCF_C7108 is not set
-# CONFIG_OCF_CRYPTOCTEON is not set
-# CONFIG_OCF_EP80579 is not set
-# CONFIG_OCF_HIFN is not set
-# CONFIG_OCF_HIFNHIPP is not set
-# CONFIG_OCF_IXP4XX is not set
-# CONFIG_OCF_KIRKWOOD is not set
-# CONFIG_OCF_OCF is not set
-# CONFIG_OCF_OCFNULL is not set
-# CONFIG_OCF_SAFE is not set
-# CONFIG_OCF_TALITOS is not set
-# CONFIG_OCF_UBSEC_SSB is not set
-# CONFIG_OC_ETM is not set
-# CONFIG_OMFS_FS is not set
-# CONFIG_ORION_WATCHDOG is not set
-# CONFIG_OSF_PARTITION is not set
-CONFIG_OVERLAYFS_FS=y
-# CONFIG_P54_COMMON is not set
-CONFIG_PACKET=y
-# CONFIG_PAGE_POISONING is not set
-# CONFIG_PAGE_SIZE_16KB is not set
-# CONFIG_PAGE_SIZE_32KB is not set
-CONFIG_PAGE_SIZE_4KB=y
-# CONFIG_PAGE_SIZE_64KB is not set
-# CONFIG_PAGE_SIZE_8KB is not set
-# CONFIG_PANEL is not set
-# CONFIG_PANTHERLORD_FF is not set
-# CONFIG_PARPORT is not set
-# CONFIG_PARPORT_1284 is not set
-# CONFIG_PARPORT_AX88796 is not set
-# CONFIG_PARPORT_PC is not set
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_PATA_ALI is not set
-# CONFIG_PATA_AMD is not set
-# CONFIG_PATA_ARTOP is not set
-# CONFIG_PATA_ATIIXP is not set
-# CONFIG_PATA_ATP867X is not set
-# CONFIG_PATA_CMD640_PCI is not set
-# CONFIG_PATA_CMD64X is not set
-# CONFIG_PATA_CS5520 is not set
-# CONFIG_PATA_CS5530 is not set
-# CONFIG_PATA_CS5535 is not set
-# CONFIG_PATA_CS5536 is not set
-# CONFIG_PATA_CYPRESS is not set
-# CONFIG_PATA_EFAR is not set
-# CONFIG_PATA_HPT366 is not set
-# CONFIG_PATA_HPT37X is not set
-# CONFIG_PATA_HPT3X2N is not set
-# CONFIG_PATA_HPT3X3 is not set
-# CONFIG_PATA_ISAPNP is not set
-# CONFIG_PATA_IT8213 is not set
-# CONFIG_PATA_IT821X is not set
-# CONFIG_PATA_JMICRON is not set
-# CONFIG_PATA_LEGACY is not set
-# CONFIG_PATA_MARVELL is not set
-# CONFIG_PATA_MPIIX is not set
-# CONFIG_PATA_NETCELL is not set
-# CONFIG_PATA_NINJA32 is not set
-# CONFIG_PATA_NS87410 is not set
-# CONFIG_PATA_NS87415 is not set
-# CONFIG_PATA_OLDPIIX is not set
-# CONFIG_PATA_OPTI is not set
-# CONFIG_PATA_OPTIDMA is not set
-# CONFIG_PATA_PCMCIA is not set
-# CONFIG_PATA_PDC2027X is not set
-# CONFIG_PATA_PDC_OLD is not set
-# CONFIG_PATA_PLATFORM is not set
-# CONFIG_PATA_QDI is not set
-# CONFIG_PATA_RADISYS is not set
-# CONFIG_PATA_RDC is not set
-# CONFIG_PATA_RZ1000 is not set
-# CONFIG_PATA_SC1200 is not set
-# CONFIG_PATA_SCH is not set
-# CONFIG_PATA_SERVERWORKS is not set
-# CONFIG_PATA_SIL680 is not set
-# CONFIG_PATA_SIS is not set
-# CONFIG_PATA_TOSHIBA is not set
-# CONFIG_PATA_TRIFLEX is not set
-# CONFIG_PATA_VIA is not set
-# CONFIG_PATA_WINBOND is not set
-# CONFIG_PATA_WINBOND_VLB is not set
-# CONFIG_PC300TOO is not set
-# CONFIG_PCCARD is not set
-# CONFIG_PCH_GBE is not set
-# CONFIG_PCH_PHUB is not set
-# CONFIG_PCI200SYN is not set
-# CONFIG_PCIEAER_INJECT is not set
-# CONFIG_PCIEASPM is not set
-# CONFIG_PCIE_ECRC is not set
-# CONFIG_PCIPCWATCHDOG is not set
-# CONFIG_PCI_ATMEL is not set
-# CONFIG_PCI_CNB20LE_QUIRK is not set
-# CONFIG_PCI_DEBUG is not set
-# CONFIG_PCI_DISABLE_COMMON_QUIRKS is not set
-# CONFIG_PCI_HERMES is not set
-# CONFIG_PCI_IOV is not set
-# CONFIG_PCI_MSI is not set
-CONFIG_PCI_QUIRKS=y
-# CONFIG_PCI_STUB is not set
-CONFIG_PCI_SYSCALL=y
-# CONFIG_PCMCIA is not set
-# CONFIG_PCMCIA_AHA152X is not set
-# CONFIG_PCMCIA_ATMEL is not set
-# CONFIG_PCMCIA_DEBUG is not set
-# CONFIG_PCMCIA_FDOMAIN is not set
-# CONFIG_PCMCIA_HERMES is not set
-# CONFIG_PCMCIA_LOAD_CIS is not set
-# CONFIG_PCMCIA_NINJA_SCSI is not set
-# CONFIG_PCMCIA_QLOGIC is not set
-# CONFIG_PCMCIA_RAYCS is not set
-# CONFIG_PCMCIA_SPECTRUM is not set
-# CONFIG_PCMCIA_SYM53C500 is not set
-# CONFIG_PCMCIA_WL3501 is not set
-# CONFIG_PCMCIA_XIRCOM is not set
-# CONFIG_PCNET32 is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_PD6729 is not set
-# CONFIG_PDC_ADMA is not set
-# CONFIG_PERF_COUNTERS is not set
-# CONFIG_PERF_EVENTS is not set
-# CONFIG_PHANTOM is not set
-# CONFIG_PHONE is not set
-# CONFIG_PHONET is not set
-# CONFIG_PHYLIB is not set
-# CONFIG_PHYS_ADDR_T_64BIT is not set
-# CONFIG_PID_NS is not set
-# CONFIG_PLAT_SPEAR is not set
-# CONFIG_PLIP is not set
-# CONFIG_PLX_HERMES is not set
-# CONFIG_PM is not set
-# CONFIG_PMC_MSP is not set
-# CONFIG_PMC_YOSEMITE is not set
-# CONFIG_PMIC_ADP5520 is not set
-# CONFIG_PMIC_DA903X is not set
-# CONFIG_PNX8550_JBS is not set
-# CONFIG_PNX8550_STB810 is not set
-# CONFIG_POHMELFS is not set
-# CONFIG_POSIX_MQUEUE is not set
-# CONFIG_POWERTV is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_PPC4xx_GPIO is not set
-# CONFIG_PPC_16K_PAGES is not set
-# CONFIG_PPC_256K_PAGES is not set
-CONFIG_PPC_4K_PAGES=y
-# CONFIG_PPC_64K_PAGES is not set
-# CONFIG_PPC_DISABLE_WERROR is not set
-# CONFIG_PPC_EMULATED_STATS is not set
-# CONFIG_PPP is not set
-# CONFIG_PPPOATM is not set
-# CONFIG_PPPOE is not set
-# CONFIG_PPPOL2TP is not set
-# CONFIG_PPP_ASYNC is not set
-# CONFIG_PPP_BSDCOMP is not set
-# CONFIG_PPP_DEFLATE is not set
-CONFIG_PPP_FILTER=y
-# CONFIG_PPP_MPPE is not set
-CONFIG_PPP_MULTILINK=y
-# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPS is not set
-# CONFIG_PPTP is not set
-# CONFIG_PREEMPT is not set
-CONFIG_PREEMPT_NONE=y
-# CONFIG_PREEMPT_VOLUNTARY is not set
-CONFIG_PREVENT_FIRMWARE_BUILD=y
-CONFIG_PRINTK=y
-# CONFIG_PRINTK_TIME is not set
-# CONFIG_PRISM2_USB is not set
-# CONFIG_PRISM54 is not set
-# CONFIG_PROBE_INITRD_HEADER is not set
-CONFIG_PROC_FS=y
-# CONFIG_PROC_KCORE is not set
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_PROC_SYSCTL=y
-# CONFIG_PROFILING is not set
-# CONFIG_PROVE_LOCKING is not set
-# CONFIG_PROVE_RCU is not set
-# CONFIG_QLA3XXX is not set
-# CONFIG_QLCNIC is not set
-# CONFIG_QNX4FS_FS is not set
-# CONFIG_QSEMI_PHY is not set
-# CONFIG_QUOTA is not set
-# CONFIG_QUOTA_DEBUG is not set
-# CONFIG_R3964 is not set
-# CONFIG_R6040 is not set
-# CONFIG_R8169 is not set
-# CONFIG_R8187SE is not set
-# CONFIG_R8712U is not set
-# CONFIG_RADIO_ADAPTERS is not set
-# CONFIG_RADIO_AZTECH is not set
-# CONFIG_RADIO_CADET is not set
-# CONFIG_RADIO_GEMTEK is not set
-# CONFIG_RADIO_GEMTEK_PCI is not set
-# CONFIG_RADIO_MAESTRO is not set
-# CONFIG_RADIO_MAXIRADIO is not set
-# CONFIG_RADIO_RTRACK is not set
-# CONFIG_RADIO_RTRACK2 is not set
-# CONFIG_RADIO_SF16FMI is not set
-# CONFIG_RADIO_SF16FMR2 is not set
-# CONFIG_RADIO_TERRATEC is not set
-# CONFIG_RADIO_TRUST is not set
-# CONFIG_RADIO_TYPHOON is not set
-# CONFIG_RADIO_ZOLTRIX is not set
-# CONFIG_RAID_ATTRS is not set
-# CONFIG_RAMOOPS is not set
-# CONFIG_RAR_REGISTER is not set
-# CONFIG_RAW_DRIVER is not set
-# CONFIG_RC_CORE is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-CONFIG_RCU_FANOUT=32
-# CONFIG_RCU_FANOUT_EXACT is not set
-# CONFIG_RCU_FAST_NO_HZ is not set
-# CONFIG_RCU_TORTURE_TEST is not set
-# CONFIG_RCU_TRACE is not set
-# CONFIG_RC_MAP is not set
-# CONFIG_RDS is not set
-# CONFIG_RD_BZIP2 is not set
-# CONFIG_RD_GZIP is not set
-CONFIG_RD_LZMA=y
-# CONFIG_RD_LZO is not set
-# CONFIG_RD_XZ is not set
-# CONFIG_REALTEK_PHY is not set
-# CONFIG_REDWOOD is not set
-# CONFIG_REGULATOR is not set
-# CONFIG_REGULATOR_BQ24022 is not set
-# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
-# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
-# CONFIG_REISERFS_CHECK is not set
-# CONFIG_REISERFS_FS is not set
-# CONFIG_REISERFS_FS_XATTR is not set
-# CONFIG_REISERFS_PROC_INFO is not set
-# CONFIG_RELAY is not set
-# CONFIG_RFD_FTL is not set
-# CONFIG_RFKILL is not set
-# CONFIG_RFKILL_INPUT is not set
-# CONFIG_ROMFS_FS is not set
-# CONFIG_ROSE is not set
-# CONFIG_RPCSEC_GSS_KRB5 is not set
-# CONFIG_RPCSEC_GSS_SPKM3 is not set
-# CONFIG_RT2860 is not set
-# CONFIG_RT2870 is not set
-# CONFIG_RT2X00 is not set
-# CONFIG_RTC_CLASS is not set
-# CONFIG_RTC_DEBUG is not set
-# CONFIG_RTC_DRV_BQ32K is not set
-# CONFIG_RTC_DRV_BQ4802 is not set
-CONFIG_RTC_DRV_CMOS=y
-# CONFIG_RTC_DRV_DS1286 is not set
-# CONFIG_RTC_DRV_DS1305 is not set
-# CONFIG_RTC_DRV_DS1307 is not set
-# CONFIG_RTC_DRV_DS1374 is not set
-# CONFIG_RTC_DRV_DS1390 is not set
-# CONFIG_RTC_DRV_DS1511 is not set
-# CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_DS1672 is not set
-# CONFIG_RTC_DRV_DS1742 is not set
-# CONFIG_RTC_DRV_DS3232 is not set
-# CONFIG_RTC_DRV_DS3234 is not set
-# CONFIG_RTC_DRV_EP93XX is not set
-# CONFIG_RTC_DRV_FM3130 is not set
-# CONFIG_RTC_DRV_GENERIC is not set
-# CONFIG_RTC_DRV_ISL12022 is not set
-# CONFIG_RTC_DRV_ISL1208 is not set
-# CONFIG_RTC_DRV_M41T80 is not set
-# CONFIG_RTC_DRV_M41T94 is not set
-# CONFIG_RTC_DRV_M48T35 is not set
-# CONFIG_RTC_DRV_M48T59 is not set
-# CONFIG_RTC_DRV_M48T86 is not set
-# CONFIG_RTC_DRV_MAX6900 is not set
-# CONFIG_RTC_DRV_MAX6902 is not set
-# CONFIG_RTC_DRV_MSM6242 is not set
-# CONFIG_RTC_DRV_PCF2123 is not set
-# CONFIG_RTC_DRV_PCF8563 is not set
-# CONFIG_RTC_DRV_PCF8583 is not set
-# CONFIG_RTC_DRV_PL030 is not set
-# CONFIG_RTC_DRV_PL031 is not set
-# CONFIG_RTC_DRV_PS3 is not set
-# CONFIG_RTC_DRV_R9701 is not set
-# CONFIG_RTC_DRV_RP5C01 is not set
-# CONFIG_RTC_DRV_RS5C348 is not set
-# CONFIG_RTC_DRV_RS5C372 is not set
-# CONFIG_RTC_DRV_RTC7301 is not set
-# CONFIG_RTC_DRV_RX8025 is not set
-# CONFIG_RTC_DRV_RX8581 is not set
-# CONFIG_RTC_DRV_S35390A is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
-# CONFIG_RTC_DRV_TEST is not set
-# CONFIG_RTC_DRV_V3020 is not set
-# CONFIG_RTC_DRV_X1205 is not set
-CONFIG_RTC_HCTOSYS=y
-CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
-CONFIG_RTC_INTF_DEV=y
-# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
-CONFIG_RTC_INTF_PROC=y
-CONFIG_RTC_INTF_SYSFS=y
-CONFIG_RTC_LIB=y
-# CONFIG_RTL8180 is not set
-# CONFIG_RTL8187 is not set
-# CONFIG_RTL8192E is not set
-# CONFIG_RTL8192SU is not set
-# CONFIG_RTL8192U is not set
-# CONFIG_RTL8306_PHY is not set
-# CONFIG_RTL8366RB_PHY is not set
-# CONFIG_RTL8366S_PHY is not set
-# CONFIG_RTL8366S_PHY_DEBUG_FS is not set
-# CONFIG_RTL8366_SMI is not set
-CONFIG_RT_MUTEXES=y
-# CONFIG_RT_MUTEX_TESTER is not set
-# CONFIG_RUNTIME_DEBUG is not set
-CONFIG_RWSEM_GENERIC_SPINLOCK=y
-# CONFIG_S2IO is not set
-# CONFIG_SAMPLES is not set
-# CONFIG_SATA_ACARD_AHCI is not set
-# CONFIG_SATA_AHCI is not set
-# CONFIG_SATA_AHCI_PLATFORM is not set
-# CONFIG_SATA_DWC is not set
-# CONFIG_SATA_INIC162X is not set
-# CONFIG_SATA_MV is not set
-# CONFIG_SATA_NV is not set
-# CONFIG_SATA_PMP is not set
-# CONFIG_SATA_PROMISE is not set
-# CONFIG_SATA_QSTOR is not set
-# CONFIG_SATA_SIL is not set
-# CONFIG_SATA_SIL24 is not set
-# CONFIG_SATA_SIS is not set
-# CONFIG_SATA_SVW is not set
-# CONFIG_SATA_SX4 is not set
-# CONFIG_SATA_ULI is not set
-# CONFIG_SATA_VIA is not set
-# CONFIG_SATA_VITESSE is not set
-# CONFIG_SBC_FITPC2_WATCHDOG is not set
-# CONFIG_SBE_2T3E3 is not set
-# CONFIG_SC92031 is not set
-# CONFIG_SCC is not set
-# CONFIG_SCHEDSTATS is not set
-# CONFIG_SCHED_AUTOGROUP is not set
-# CONFIG_SCHED_DEBUG is not set
-CONFIG_SCHED_OMIT_FRAME_POINTER=y
-# CONFIG_SCHED_TRACER is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_3W_9XXX is not set
-# CONFIG_SCSI_3W_SAS is not set
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_AACRAID is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AIC79XX is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_AIC7XXX_OLD is not set
-# CONFIG_SCSI_AIC94XX is not set
-# CONFIG_SCSI_ARCMSR is not set
-# CONFIG_SCSI_BFA_FC is not set
-# CONFIG_SCSI_BNX2_ISCSI is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_CONSTANTS is not set
-# CONFIG_SCSI_CXGB4_ISCSI is not set
-# CONFIG_SCSI_DC390T is not set
-# CONFIG_SCSI_DC395x is not set
-# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_DH is not set
-CONFIG_SCSI_DMA=y
-# CONFIG_SCSI_DMX3191D is not set
-# CONFIG_SCSI_DPT_I2O is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_FC_ATTRS is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
-# CONFIG_SCSI_HPSA is not set
-# CONFIG_SCSI_HPTIOP is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_INIA100 is not set
-# CONFIG_SCSI_INITIO is not set
-# CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_IPS is not set
-# CONFIG_SCSI_ISCSI_ATTRS is not set
-# CONFIG_SCSI_LOGGING is not set
-CONFIG_SCSI_LOWLEVEL=y
-# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
-# CONFIG_SCSI_LPFC is not set
-CONFIG_SCSI_MOD=y
-# CONFIG_SCSI_MPT2SAS is not set
-CONFIG_SCSI_MULTI_LUN=y
-# CONFIG_SCSI_MVSAS is not set
-# CONFIG_SCSI_MVSAS_DEBUG is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_NETLINK is not set
-# CONFIG_SCSI_NSP32 is not set
-# CONFIG_SCSI_OSD_INITIATOR is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PM8001 is not set
-# CONFIG_SCSI_PMCRAID is not set
-CONFIG_SCSI_PROC_FS=y
-# CONFIG_SCSI_QLA_FC is not set
-# CONFIG_SCSI_QLA_ISCSI is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SAS_ATTRS is not set
-# CONFIG_SCSI_SAS_LIBSAS is not set
-# CONFIG_SCSI_SCAN_ASYNC is not set
-# CONFIG_SCSI_SPI_ATTRS is not set
-# CONFIG_SCSI_SRP is not set
-# CONFIG_SCSI_SRP_ATTRS is not set
-# CONFIG_SCSI_STEX is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_SYM53C8XX_2 is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_TGT is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-CONFIG_SCSI_WAIT_SCAN=m
-# CONFIG_SECCOMP is not set
-# CONFIG_SECURITY is not set
-# CONFIG_SECURITYFS is not set
-# CONFIG_SECURITY_DMESG_RESTRICT is not set
-CONFIG_SELECT_MEMORY_MODEL=y
-# CONFIG_SENSORS_ABITUGURU is not set
-# CONFIG_SENSORS_ABITUGURU3 is not set
-# CONFIG_SENSORS_AD7414 is not set
-# CONFIG_SENSORS_AD7418 is not set
-# CONFIG_SENSORS_ADCXX is not set
-# CONFIG_SENSORS_ADM1021 is not set
-# CONFIG_SENSORS_ADM1025 is not set
-# CONFIG_SENSORS_ADM1026 is not set
-# CONFIG_SENSORS_ADM1029 is not set
-# CONFIG_SENSORS_ADM1031 is not set
-# CONFIG_SENSORS_ADM9240 is not set
-# CONFIG_SENSORS_ADS7828 is not set
-# CONFIG_SENSORS_ADS7871 is not set
-# CONFIG_SENSORS_ADT7411 is not set
-# CONFIG_SENSORS_ADT7462 is not set
-# CONFIG_SENSORS_ADT7470 is not set
-# CONFIG_SENSORS_ADT7475 is not set
-# CONFIG_SENSORS_AMC6821 is not set
-# CONFIG_SENSORS_APDS990X is not set
-# CONFIG_SENSORS_APPLESMC is not set
-# CONFIG_SENSORS_ASB100 is not set
-# CONFIG_SENSORS_ASC7621 is not set
-# CONFIG_SENSORS_ATK0110 is not set
-# CONFIG_SENSORS_ATXP1 is not set
-# CONFIG_SENSORS_BH1770 is not set
-# CONFIG_SENSORS_BH1780 is not set
-# CONFIG_SENSORS_CORETEMP is not set
-# CONFIG_SENSORS_DME1737 is not set
-# CONFIG_SENSORS_DS1621 is not set
-# CONFIG_SENSORS_DS620 is not set
-# CONFIG_SENSORS_EMC1403 is not set
-# CONFIG_SENSORS_EMC2103 is not set
-# CONFIG_SENSORS_F71805F is not set
-# CONFIG_SENSORS_F71882FG is not set
-# CONFIG_SENSORS_F75375S is not set
-# CONFIG_SENSORS_FSCHMD is not set
-# CONFIG_SENSORS_G760A is not set
-# CONFIG_SENSORS_GL518SM is not set
-# CONFIG_SENSORS_GL520SM is not set
-# CONFIG_SENSORS_GPIO_FAN is not set
-# CONFIG_SENSORS_HDAPS is not set
-# CONFIG_SENSORS_I5K_AMB is not set
-# CONFIG_SENSORS_IT87 is not set
-# CONFIG_SENSORS_JC42 is not set
-# CONFIG_SENSORS_K8TEMP is not set
-# CONFIG_SENSORS_LIS3LV02D is not set
-# CONFIG_SENSORS_LIS3_I2C is not set
-# CONFIG_SENSORS_LIS3_SPI is not set
-# CONFIG_SENSORS_LM63 is not set
-# CONFIG_SENSORS_LM70 is not set
-# CONFIG_SENSORS_LM73 is not set
-# CONFIG_SENSORS_LM75 is not set
-# CONFIG_SENSORS_LM77 is not set
-# CONFIG_SENSORS_LM78 is not set
-# CONFIG_SENSORS_LM80 is not set
-# CONFIG_SENSORS_LM83 is not set
-# CONFIG_SENSORS_LM85 is not set
-# CONFIG_SENSORS_LM87 is not set
-# CONFIG_SENSORS_LM90 is not set
-# CONFIG_SENSORS_LM92 is not set
-# CONFIG_SENSORS_LM93 is not set
-# CONFIG_SENSORS_LM95241 is not set
-# CONFIG_SENSORS_LTC4215 is not set
-# CONFIG_SENSORS_LTC4245 is not set
-# CONFIG_SENSORS_LTC4261 is not set
-# CONFIG_SENSORS_MAX1111 is not set
-# CONFIG_SENSORS_MAX1619 is not set
-# CONFIG_SENSORS_MAX6650 is not set
-# CONFIG_SENSORS_PC87360 is not set
-# CONFIG_SENSORS_PC87427 is not set
-# CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_SHT15 is not set
-# CONFIG_SENSORS_SHT21 is not set
-# CONFIG_SENSORS_SIS5595 is not set
-# CONFIG_SENSORS_SMM665 is not set
-# CONFIG_SENSORS_SMSC47B397 is not set
-# CONFIG_SENSORS_SMSC47M1 is not set
-# CONFIG_SENSORS_SMSC47M192 is not set
-# CONFIG_SENSORS_THMC50 is not set
-# CONFIG_SENSORS_TMP102 is not set
-# CONFIG_SENSORS_TMP401 is not set
-# CONFIG_SENSORS_TMP421 is not set
-# CONFIG_SENSORS_TSL2550 is not set
-# CONFIG_SENSORS_VIA686A is not set
-# CONFIG_SENSORS_VT1211 is not set
-# CONFIG_SENSORS_VT8231 is not set
-# CONFIG_SENSORS_W83627EHF is not set
-# CONFIG_SENSORS_W83627HF is not set
-# CONFIG_SENSORS_W83781D is not set
-# CONFIG_SENSORS_W83791D is not set
-# CONFIG_SENSORS_W83792D is not set
-# CONFIG_SENSORS_W83793 is not set
-# CONFIG_SENSORS_W83795 is not set
-# CONFIG_SENSORS_W83L785TS is not set
-# CONFIG_SENSORS_W83L786NG is not set
-CONFIG_SERIAL_8250=y
-# CONFIG_SERIAL_8250_ACCENT is not set
-# CONFIG_SERIAL_8250_BOCA is not set
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_CS is not set
-# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
-# CONFIG_SERIAL_8250_EXTENDED is not set
-# CONFIG_SERIAL_8250_FOURPORT is not set
-# CONFIG_SERIAL_8250_HUB6 is not set
-CONFIG_SERIAL_8250_NR_UARTS=2
-# CONFIG_SERIAL_8250_PCI is not set
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-# CONFIG_SERIAL_ALTERA_JTAGUART is not set
-# CONFIG_SERIAL_ALTERA_UART is not set
-CONFIG_SERIAL_CORE=y
-CONFIG_SERIAL_CORE_CONSOLE=y
-# CONFIG_SERIAL_GRLIB_GAISLER_APBUART is not set
-# CONFIG_SERIAL_IFX6X60 is not set
-# CONFIG_SERIAL_JSM is not set
-# CONFIG_SERIAL_MAX3100 is not set
-# CONFIG_SERIAL_MAX3107 is not set
-# CONFIG_SERIAL_MFD_HSU is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL is not set
-# CONFIG_SERIAL_TIMBERDALE is not set
-# CONFIG_SERIAL_UARTLITE is not set
-# CONFIG_SERIO is not set
-# CONFIG_SERIO_ALTERA_PS2 is not set
-# CONFIG_SERIO_PS2MULT is not set
-# CONFIG_SFI is not set
-# CONFIG_SGI_IOC4 is not set
-# CONFIG_SGI_IP22 is not set
-# CONFIG_SGI_IP27 is not set
-# CONFIG_SGI_IP28 is not set
-# CONFIG_SGI_IP32 is not set
-# CONFIG_SGI_PARTITION is not set
-CONFIG_SHMEM=y
-# CONFIG_SIBYTE_BIGSUR is not set
-# CONFIG_SIBYTE_CARMEL is not set
-# CONFIG_SIBYTE_CRHINE is not set
-# CONFIG_SIBYTE_CRHONE is not set
-# CONFIG_SIBYTE_LITTLESUR is not set
-# CONFIG_SIBYTE_RHONE is not set
-# CONFIG_SIBYTE_SENTOSA is not set
-# CONFIG_SIBYTE_SWARM is not set
-CONFIG_SIGNALFD=y
-# CONFIG_SIMPLE_GPIO is not set
-# CONFIG_SIS190 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_SKGE is not set
-# CONFIG_SKY2 is not set
-# CONFIG_SKY2_DEBUG is not set
-CONFIG_SLAB=y
-CONFIG_SLABINFO=y
-# CONFIG_SLHC is not set
-# CONFIG_SLICOSS is not set
-# CONFIG_SLIP is not set
-# CONFIG_SLOB is not set
-# CONFIG_SLUB is not set
-# CONFIG_SLUB_DEBUG is not set
-# CONFIG_SLUB_STATS is not set
-# CONFIG_SMARTJOYPLUS_FF is not set
-# CONFIG_SMB_FS is not set
-# CONFIG_SMB_NLS_DEFAULT is not set
-# CONFIG_SMC911X is not set
-# CONFIG_SMC91X is not set
-# CONFIG_SMP is not set
-# CONFIG_SMSC911X is not set
-# CONFIG_SMSC9420 is not set
-# CONFIG_SMSC_PHY is not set
-# CONFIG_SM_FTL is not set
-# CONFIG_SND is not set
-# CONFIG_SND_AC97_POWER_SAVE is not set
-# CONFIG_SND_AD1816A is not set
-# CONFIG_SND_AD1848 is not set
-# CONFIG_SND_AD1889 is not set
-# CONFIG_SND_ADLIB is not set
-# CONFIG_SND_ALI5451 is not set
-# CONFIG_SND_ALOOP is not set
-# CONFIG_SND_ALS100 is not set
-# CONFIG_SND_ALS300 is not set
-# CONFIG_SND_ALS4000 is not set
-# CONFIG_SND_ARM is not set
-# CONFIG_SND_ASIHPI is not set
-# CONFIG_SND_ATIIXP is not set
-# CONFIG_SND_ATIIXP_MODEM is not set
-# CONFIG_SND_ATMEL_AC97C is not set
-# CONFIG_SND_ATMEL_SOC is not set
-# CONFIG_SND_AU8810 is not set
-# CONFIG_SND_AU8820 is not set
-# CONFIG_SND_AU8830 is not set
-# CONFIG_SND_AW2 is not set
-# CONFIG_SND_AZT2320 is not set
-# CONFIG_SND_AZT3328 is not set
-# CONFIG_SND_BT87X is not set
-# CONFIG_SND_CA0106 is not set
-# CONFIG_SND_CMI8330 is not set
-# CONFIG_SND_CMIPCI is not set
-# CONFIG_SND_CS4231 is not set
-# CONFIG_SND_CS4236 is not set
-# CONFIG_SND_CS4281 is not set
-# CONFIG_SND_CS46XX is not set
-# CONFIG_SND_CS5530 is not set
-# CONFIG_SND_CS5535AUDIO is not set
-# CONFIG_SND_CTXFI is not set
-# CONFIG_SND_DARLA20 is not set
-# CONFIG_SND_DARLA24 is not set
-# CONFIG_SND_DEBUG is not set
-CONFIG_SND_DRIVERS=y
-# CONFIG_SND_DUMMY is not set
-# CONFIG_SND_DYNAMIC_MINORS is not set
-# CONFIG_SND_ECHO3G is not set
-# CONFIG_SND_EMU10K1 is not set
-# CONFIG_SND_EMU10K1X is not set
-# CONFIG_SND_ENS1370 is not set
-# CONFIG_SND_ENS1371 is not set
-# CONFIG_SND_ES1688 is not set
-# CONFIG_SND_ES18XX is not set
-# CONFIG_SND_ES1938 is not set
-# CONFIG_SND_ES1968 is not set
-# CONFIG_SND_FM801 is not set
-# CONFIG_SND_GINA20 is not set
-# CONFIG_SND_GINA24 is not set
-# CONFIG_SND_GUSCLASSIC is not set
-# CONFIG_SND_GUSEXTREME is not set
-# CONFIG_SND_GUSMAX is not set
-# CONFIG_SND_HDA_INTEL is not set
-# CONFIG_SND_HDSP is not set
-# CONFIG_SND_HDSPM is not set
-# CONFIG_SND_HIFIER is not set
-# CONFIG_SND_HRTIMER is not set
-# CONFIG_SND_HWDEP is not set
-# CONFIG_SND_ICE1712 is not set
-# CONFIG_SND_ICE1724 is not set
-# CONFIG_SND_INDIGO is not set
-# CONFIG_SND_INDIGODJ is not set
-# CONFIG_SND_INDIGODJX is not set
-# CONFIG_SND_INDIGOIO is not set
-# CONFIG_SND_INDIGOIOX is not set
-# CONFIG_SND_INTEL8X0 is not set
-# CONFIG_SND_INTEL8X0M is not set
-# CONFIG_SND_INTERWAVE is not set
-# CONFIG_SND_INTERWAVE_STB is not set
-# CONFIG_SND_ISA is not set
-# CONFIG_SND_KIRKWOOD_SOC is not set
-# CONFIG_SND_KORG1212 is not set
-# CONFIG_SND_LAYLA20 is not set
-# CONFIG_SND_LAYLA24 is not set
-# CONFIG_SND_LX6464ES is not set
-# CONFIG_SND_MAESTRO3 is not set
-# CONFIG_SND_MIA is not set
-# CONFIG_SND_MIPS is not set
-# CONFIG_SND_MIRO is not set
-# CONFIG_SND_MIXART is not set
-# CONFIG_SND_MIXER_OSS is not set
-# CONFIG_SND_MONA is not set
-# CONFIG_SND_MPU401 is not set
-# CONFIG_SND_MTPAV is not set
-# CONFIG_SND_MTS64 is not set
-# CONFIG_SND_NM256 is not set
-# CONFIG_SND_OPL3SA2 is not set
-# CONFIG_SND_OPTI92X_AD1848 is not set
-# CONFIG_SND_OPTI92X_CS4231 is not set
-# CONFIG_SND_OPTI93X is not set
-CONFIG_SND_OSSEMUL=y
-# CONFIG_SND_OXYGEN is not set
-CONFIG_SND_PCI=y
-# CONFIG_SND_PCM is not set
-# CONFIG_SND_PCMCIA is not set
-# CONFIG_SND_PCM_OSS is not set
-CONFIG_SND_PCM_OSS_PLUGINS=y
-# CONFIG_SND_PCXHR is not set
-# CONFIG_SND_PDAUDIOCF is not set
-# CONFIG_SND_PORTMAN2X4 is not set
-# CONFIG_SND_RAWMIDI is not set
-# CONFIG_SND_RIPTIDE is not set
-# CONFIG_SND_RME32 is not set
-# CONFIG_SND_RME96 is not set
-# CONFIG_SND_RME9652 is not set
-# CONFIG_SND_RTCTIMER is not set
-# CONFIG_SND_SB16 is not set
-# CONFIG_SND_SB8 is not set
-# CONFIG_SND_SBAWE is not set
-# CONFIG_SND_SEQUENCER is not set
-# CONFIG_SND_SERIAL_U16550 is not set
-# CONFIG_SND_SGALAXY is not set
-# CONFIG_SND_SIS7019 is not set
-# CONFIG_SND_SOC is not set
-# CONFIG_SND_SOC_CACHE_LZO is not set
-# CONFIG_SND_SONICVIBES is not set
-# CONFIG_SND_SPI is not set
-# CONFIG_SND_SSCAPE is not set
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_TIMER is not set
-# CONFIG_SND_TRIDENT is not set
-CONFIG_SND_USB=y
-# CONFIG_SND_USB_AUDIO is not set
-# CONFIG_SND_USB_CAIAQ is not set
-# CONFIG_SND_USB_UA101 is not set
-# CONFIG_SND_USB_US122L is not set
-# CONFIG_SND_USB_USX2Y is not set
-# CONFIG_SND_VERBOSE_PRINTK is not set
-CONFIG_SND_VERBOSE_PROCFS=y
-# CONFIG_SND_VIA82XX is not set
-# CONFIG_SND_VIA82XX_MODEM is not set
-# CONFIG_SND_VIRTUOSO is not set
-# CONFIG_SND_VX222 is not set
-# CONFIG_SND_VXPOCKET is not set
-# CONFIG_SND_WAVEFRONT is not set
-# CONFIG_SND_YMFPCI is not set
-# CONFIG_SNI_RM is not set
-# CONFIG_SOC_CAMERA is not set
-# CONFIG_SOFT_WATCHDOG is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_SOLO6X10 is not set
-# CONFIG_SONYPI is not set
-# CONFIG_SONY_LAPTOP is not set
-# CONFIG_SOUND is not set
-# CONFIG_SOUND_PRIME is not set
-# CONFIG_SP5100_TCO is not set
-# CONFIG_SPARSEMEM_MANUAL is not set
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
-# CONFIG_SPARSE_IRQ is not set
-# CONFIG_SPARSE_RCU_POINTER is not set
-# CONFIG_SPEAKUP is not set
-# CONFIG_SPI is not set
-# CONFIG_SPINLOCK_TEST is not set
-# CONFIG_SPI_BUTTERFLY is not set
-# CONFIG_SPI_DEBUG is not set
-# CONFIG_SPI_DESIGNWARE is not set
-# CONFIG_SPI_GPIO_OLD is not set
-# CONFIG_SPI_LM70_LLP is not set
-# CONFIG_SPI_MASTER is not set
-# CONFIG_SPI_ORION is not set
-# CONFIG_SPI_PXA2XX is not set
-# CONFIG_SPI_RB4XX is not set
-# CONFIG_SPI_RB4XX_CPLD is not set
-# CONFIG_SPI_SPIDEV is not set
-# CONFIG_SPI_TLE62X0 is not set
-# CONFIG_SPI_TOPCLIFF_PCH is not set
-# CONFIG_SPI_VSC7385 is not set
-# CONFIG_SPI_XILINX is not set
-CONFIG_SPLIT_PTLOCK_CPUS=4
-CONFIG_SQUASHFS=y
-# CONFIG_SQUASHFS_EMBEDDED is not set
-CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
-CONFIG_SQUASHFS_LZMA=y
-# CONFIG_SQUASHFS_LZO is not set
-# CONFIG_SQUASHFS_XATTR is not set
-# CONFIG_SQUASHFS_XATTRS is not set
-CONFIG_SQUASHFS_XZ=y
-# CONFIG_SSB is not set
-# CONFIG_SSB_DEBUG is not set
-# CONFIG_SSB_PCMCIAHOST is not set
-CONFIG_SSB_POSSIBLE=y
-# CONFIG_SSB_SDIOHOST is not set
-# CONFIG_SSB_SILENT is not set
-# CONFIG_SSFDC is not set
-CONFIG_STACKTRACE_SUPPORT=y
-# CONFIG_STACK_TRACER is not set
-CONFIG_STAGING=y
-# CONFIG_STAGING_EXCLUDE_BUILD is not set
-CONFIG_STANDALONE=y
-CONFIG_STDBINUTILS=y
-# CONFIG_STE10XP is not set
-# CONFIG_STMMAC_ETH is not set
-CONFIG_STP=y
-# CONFIG_STRICT_DEVMEM is not set
-CONFIG_STRIP_ASM_SYMS=y
-# CONFIG_STUB_POULSBO is not set
-# CONFIG_ST_BT is not set
-# CONFIG_SUNDANCE is not set
-# CONFIG_SUNGEM is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_SUNRPC_GSS is not set
-# CONFIG_SUN_PARTITION is not set
-CONFIG_SWAP=y
-# CONFIG_SWCONFIG is not set
-# CONFIG_SYNCLINK_CS is not set
-CONFIG_SYN_COOKIES=y
-CONFIG_SYSCTL=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_SYSCTL_SYSCALL_CHECK is not set
-CONFIG_SYSFS=y
-# CONFIG_SYSFS_DEPRECATED is not set
-# CONFIG_SYSFS_DEPRECATED_V2 is not set
-# CONFIG_SYSV68_PARTITION is not set
-CONFIG_SYSVIPC=y
-CONFIG_SYSVIPC_SYSCTL=y
-# CONFIG_SYSV_FS is not set
-# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_TARGET_CORE is not set
-# CONFIG_TASKSTATS is not set
-# CONFIG_TC35815 is not set
-# CONFIG_TCG_TPM is not set
-# CONFIG_TCIC is not set
-CONFIG_TCP_CONG_ADVANCED=y
-# CONFIG_TCP_CONG_BIC is not set
-# CONFIG_TCP_CONG_CUBIC is not set
-# CONFIG_TCP_CONG_HSTCP is not set
-# CONFIG_TCP_CONG_HTCP is not set
-# CONFIG_TCP_CONG_HYBLA is not set
-# CONFIG_TCP_CONG_ILLINOIS is not set
-# CONFIG_TCP_CONG_LP is not set
-# CONFIG_TCP_CONG_SCALABLE is not set
-# CONFIG_TCP_CONG_VEGAS is not set
-# CONFIG_TCP_CONG_VENO is not set
-CONFIG_TCP_CONG_WESTWOOD=y
-# CONFIG_TCP_CONG_YEAH is not set
-# CONFIG_TCP_MD5SIG is not set
-# CONFIG_TEST_KSTRTOX is not set
-# CONFIG_TEST_LIST_SORT is not set
-# CONFIG_TEST_POWER is not set
-CONFIG_TEXTSEARCH=y
-# CONFIG_TEXTSEARCH_BM is not set
-# CONFIG_TEXTSEARCH_FSM is not set
-# CONFIG_TEXTSEARCH_KMP is not set
-# CONFIG_THERMAL is not set
-# CONFIG_THERMAL_HWMON is not set
-# CONFIG_THRUSTMASTER_FF is not set
-CONFIG_TICK_ONESHOT=y
-# CONFIG_TIFM_CORE is not set
-# CONFIG_TIGON3 is not set
-# CONFIG_TIMB_DMA is not set
-CONFIG_TIMERFD=y
-# CONFIG_TIMER_STATS is not set
-CONFIG_TINY_RCU=y
-# CONFIG_TIPC is not set
-# CONFIG_TI_DAC7512 is not set
-# CONFIG_TI_ST is not set
-# CONFIG_TLAN is not set
-# CONFIG_TMD_HERMES is not set
-CONFIG_TMPFS=y
-# CONFIG_TMPFS_POSIX_ACL is not set
-# CONFIG_TOUCHSCREEN_AD7877 is not set
-# CONFIG_TOUCHSCREEN_AD7879 is not set
-# CONFIG_TOUCHSCREEN_AD7879_I2C is not set
-# CONFIG_TOUCHSCREEN_AD7879_SPI is not set
-# CONFIG_TOUCHSCREEN_ADS7846 is not set
-# CONFIG_TOUCHSCREEN_BU21013 is not set
-# CONFIG_TOUCHSCREEN_CLEARPAD_TM1217 is not set
-# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
-# CONFIG_TOUCHSCREEN_EETI is not set
-# CONFIG_TOUCHSCREEN_ELO is not set
-# CONFIG_TOUCHSCREEN_FUJITSU is not set
-# CONFIG_TOUCHSCREEN_GUNZE is not set
-# CONFIG_TOUCHSCREEN_INEXIO is not set
-# CONFIG_TOUCHSCREEN_MCS5000 is not set
-# CONFIG_TOUCHSCREEN_MK712 is not set
-# CONFIG_TOUCHSCREEN_MTOUCH is not set
-# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_QT602240 is not set
-# CONFIG_TOUCHSCREEN_S3C2410 is not set
-# CONFIG_TOUCHSCREEN_ST1232 is not set
-# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
-# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
-# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
-# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
-# CONFIG_TOUCHSCREEN_TPS6507X is not set
-# CONFIG_TOUCHSCREEN_TSC2007 is not set
-# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
-# CONFIG_TOUCHSCREEN_W90X900 is not set
-# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
-# CONFIG_TPS65010 is not set
-# CONFIG_TPS6507X is not set
-# CONFIG_TR is not set
-# CONFIG_TRACE_BRANCH_PROFILING is not set
-CONFIG_TRACE_IRQFLAGS_SUPPORT=y
-CONFIG_TRACING_SUPPORT=y
-CONFIG_TRAD_SIGNALS=y
-# CONFIG_TRANZPORT is not set
-# CONFIG_TREE_PREEMPT_RCU is not set
-# CONFIG_TREE_RCU is not set
-# CONFIG_TREE_RCU_TRACE is not set
-# CONFIG_TTY_PRINTK is not set
-# CONFIG_TUN is not set
-# CONFIG_TWL4030_CORE is not set
-# CONFIG_UACCESS_WITH_MEMCPY is not set
-# CONFIG_UCB1400_CORE is not set
-# CONFIG_UDF_FS is not set
-CONFIG_UDF_NLS=y
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-# CONFIG_UFS_FS is not set
-# CONFIG_UIO is not set
-# CONFIG_ULTRIX_PARTITION is not set
-CONFIG_UNIX=y
-CONFIG_UNIX98_PTYS=y
-# CONFIG_UNIXWARE_DISKLABEL is not set
-# CONFIG_UNUSED_SYMBOLS is not set
-# CONFIG_USB is not set
-# CONFIG_USBPCWATCHDOG is not set
-# CONFIG_USB_ACM is not set
-# CONFIG_USB_ADUTUX is not set
-CONFIG_USB_ALI_M5632=y
-CONFIG_USB_AN2720=y
-# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
-# CONFIG_USB_APPLEDISPLAY is not set
-CONFIG_USB_ARCH_HAS_EHCI=y
-CONFIG_USB_ARCH_HAS_HCD=y
-CONFIG_USB_ARCH_HAS_OHCI=y
-CONFIG_USB_ARMLINUX=y
-# CONFIG_USB_ATM is not set
-CONFIG_USB_BELKIN=y
-# CONFIG_USB_C67X00_HCD is not set
-# CONFIG_USB_CATC is not set
-# CONFIG_USB_CXACRU is not set
-# CONFIG_USB_CYPRESS_CY7C63 is not set
-# CONFIG_USB_CYTHERM is not set
-# CONFIG_USB_DABUSB is not set
-# CONFIG_USB_DEBUG is not set
-CONFIG_USB_DEVICEFS=y
-# CONFIG_USB_DEVICE_CLASS is not set
-# CONFIG_USB_DSBR is not set
-# CONFIG_USB_DYNAMIC_MINORS is not set
-# CONFIG_USB_EHCI_HCD_PPC_OF is not set
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-# CONFIG_USB_EHCI_TT_NEWSCHED is not set
-# CONFIG_USB_EMI26 is not set
-# CONFIG_USB_EMI62 is not set
-# CONFIG_USB_ENESTORAGE is not set
-# CONFIG_USB_EPSON2888 is not set
-# CONFIG_USB_ET61X251 is not set
-CONFIG_USB_EZUSB=y
-# CONFIG_USB_FTDI_ELAN is not set
-# CONFIG_USB_GADGET is not set
-# CONFIG_USB_GADGET_DEBUG is not set
-# CONFIG_USB_GL860 is not set
-# CONFIG_USB_GPIO_VBUS is not set
-# CONFIG_USB_GSPCA is not set
-# CONFIG_USB_GSPCA_BENQ is not set
-# CONFIG_USB_GSPCA_CONEX is not set
-# CONFIG_USB_GSPCA_CPIA1 is not set
-# CONFIG_USB_GSPCA_ETOMS is not set
-# CONFIG_USB_GSPCA_FINEPIX is not set
-# CONFIG_USB_GSPCA_JEILINJ is not set
-# CONFIG_USB_GSPCA_KONICA is not set
-# CONFIG_USB_GSPCA_MARS is not set
-# CONFIG_USB_GSPCA_MR97310A is not set
-# CONFIG_USB_GSPCA_OV519 is not set
-# CONFIG_USB_GSPCA_OV534 is not set
-# CONFIG_USB_GSPCA_OV534_9 is not set
-# CONFIG_USB_GSPCA_PAC207 is not set
-# CONFIG_USB_GSPCA_PAC7302 is not set
-# CONFIG_USB_GSPCA_PAC7311 is not set
-# CONFIG_USB_GSPCA_SN9C2028 is not set
-# CONFIG_USB_GSPCA_SN9C20X is not set
-# CONFIG_USB_GSPCA_SONIXB is not set
-# CONFIG_USB_GSPCA_SONIXJ is not set
-# CONFIG_USB_GSPCA_SPCA1528 is not set
-# CONFIG_USB_GSPCA_SPCA500 is not set
-# CONFIG_USB_GSPCA_SPCA501 is not set
-# CONFIG_USB_GSPCA_SPCA505 is not set
-# CONFIG_USB_GSPCA_SPCA506 is not set
-# CONFIG_USB_GSPCA_SPCA508 is not set
-# CONFIG_USB_GSPCA_SPCA561 is not set
-# CONFIG_USB_GSPCA_SQ905 is not set
-# CONFIG_USB_GSPCA_SQ905C is not set
-# CONFIG_USB_GSPCA_SQ930X is not set
-# CONFIG_USB_GSPCA_STK014 is not set
-# CONFIG_USB_GSPCA_STV0680 is not set
-# CONFIG_USB_GSPCA_SUNPLUS is not set
-# CONFIG_USB_GSPCA_T613 is not set
-# CONFIG_USB_GSPCA_TV8532 is not set
-# CONFIG_USB_GSPCA_VC032X is not set
-# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
-# CONFIG_USB_GSPCA_ZC3XX is not set
-# CONFIG_USB_G_MULTI is not set
-# CONFIG_USB_G_NOKIA is not set
-# CONFIG_USB_HID is not set
-# CONFIG_USB_HIDDEV is not set
-# CONFIG_USB_HSO is not set
-# CONFIG_USB_HWA_HCD is not set
-# CONFIG_USB_IBMCAM is not set
-# CONFIG_USB_IDMOUSE is not set
-# CONFIG_USB_IOWARRIOR is not set
-# CONFIG_USB_IPHETH is not set
-# CONFIG_USB_IP_COMMON is not set
-# CONFIG_USB_ISIGHTFW is not set
-# CONFIG_USB_ISP116X_HCD is not set
-# CONFIG_USB_ISP1362_HCD is not set
-# CONFIG_USB_ISP1760_HCD is not set
-# CONFIG_USB_KAWETH is not set
-# CONFIG_USB_KBD is not set
-# CONFIG_USB_KC2190 is not set
-# CONFIG_USB_KONICAWC is not set
-# CONFIG_USB_LCD is not set
-# CONFIG_USB_LD is not set
-# CONFIG_USB_LED is not set
-# CONFIG_USB_LEGOTOWER is not set
-# CONFIG_USB_LIBUSUAL is not set
-# CONFIG_USB_M5602 is not set
-# CONFIG_USB_MASS_STORAGE is not set
-# CONFIG_USB_MDC800 is not set
-# CONFIG_USB_MICROTEK is not set
-# CONFIG_USB_MON is not set
-# CONFIG_USB_MOUSE is not set
-# CONFIG_USB_MUSB_HDRC is not set
-# CONFIG_USB_NET_AX8817X is not set
-# CONFIG_USB_NET_CDCETHER is not set
-# CONFIG_USB_NET_CDC_EEM is not set
-# CONFIG_USB_NET_CDC_NCM is not set
-# CONFIG_USB_NET_CDC_SUBSET is not set
-# CONFIG_USB_NET_CX82310_ETH is not set
-# CONFIG_USB_NET_DM9601 is not set
-# CONFIG_USB_NET_GL620A is not set
-# CONFIG_USB_NET_INT51X1 is not set
-# CONFIG_USB_NET_MCS7830 is not set
-# CONFIG_USB_NET_NET1080 is not set
-# CONFIG_USB_NET_PLUSB is not set
-# CONFIG_USB_NET_RNDIS_HOST is not set
-# CONFIG_USB_NET_RNDIS_WLAN is not set
-# CONFIG_USB_NET_SMSC75XX is not set
-# CONFIG_USB_NET_SMSC95XX is not set
-# CONFIG_USB_NET_ZAURUS is not set
-# CONFIG_USB_OHCI_HCD is not set
-# CONFIG_USB_OHCI_HCD_PCI is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF_BE is not set
-# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
-# CONFIG_USB_OHCI_HCD_PPC_SOC is not set
-# CONFIG_USB_OHCI_HCD_SSB is not set
-CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-# CONFIG_USB_OTG is not set
-# CONFIG_USB_OTG_BLACKLIST_HUB is not set
-# CONFIG_USB_OTG_WHITELIST is not set
-# CONFIG_USB_OXU210HP_HCD is not set
-# CONFIG_USB_PEGASUS is not set
-# CONFIG_USB_PRINTER is not set
-# CONFIG_USB_PWC_INPUT_EVDEV is not set
-# CONFIG_USB_R8A66597_HCD is not set
-# CONFIG_USB_RIO500 is not set
-# CONFIG_USB_RTL8150 is not set
-# CONFIG_USB_S2255 is not set
-# CONFIG_USB_SE401 is not set
-# CONFIG_USB_SERIAL is not set
-# CONFIG_USB_SERIAL_AIRCABLE is not set
-# CONFIG_USB_SERIAL_ARK3116 is not set
-# CONFIG_USB_SERIAL_BELKIN is not set
-# CONFIG_USB_SERIAL_CH341 is not set
-# CONFIG_USB_SERIAL_CP210X is not set
-# CONFIG_USB_SERIAL_CYBERJACK is not set
-# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
-# CONFIG_USB_SERIAL_DEBUG is not set
-# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT is not set
-# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
-# CONFIG_USB_SERIAL_EMPEG is not set
-# CONFIG_USB_SERIAL_FTDI_SIO is not set
-# CONFIG_USB_SERIAL_FUNSOFT is not set
-# CONFIG_USB_SERIAL_GARMIN is not set
-CONFIG_USB_SERIAL_GENERIC=y
-# CONFIG_USB_SERIAL_HP4X is not set
-# CONFIG_USB_SERIAL_IPAQ is not set
-# CONFIG_USB_SERIAL_IPW is not set
-# CONFIG_USB_SERIAL_IR is not set
-# CONFIG_USB_SERIAL_IUU is not set
-# CONFIG_USB_SERIAL_KEYSPAN is not set
-CONFIG_USB_SERIAL_KEYSPAN_MPR=y
-# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
-CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
-CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
-CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
-CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
-# CONFIG_USB_SERIAL_KLSI is not set
-# CONFIG_USB_SERIAL_KOBIL_SCT is not set
-# CONFIG_USB_SERIAL_MCT_U232 is not set
-# CONFIG_USB_SERIAL_MOS7720 is not set
-# CONFIG_USB_SERIAL_MOS7840 is not set
-# CONFIG_USB_SERIAL_MOTOROLA is not set
-# CONFIG_USB_SERIAL_NAVMAN is not set
-# CONFIG_USB_SERIAL_OMNINET is not set
-# CONFIG_USB_SERIAL_OPTICON is not set
-# CONFIG_USB_SERIAL_OPTION is not set
-# CONFIG_USB_SERIAL_OTI6858 is not set
-# CONFIG_USB_SERIAL_PL2303 is not set
-# CONFIG_USB_SERIAL_QCAUX is not set
-# CONFIG_USB_SERIAL_QUALCOMM is not set
-# CONFIG_USB_SERIAL_QUATECH2 is not set
-# CONFIG_USB_SERIAL_QUATECH_USB2 is not set
-# CONFIG_USB_SERIAL_SAFE is not set
-CONFIG_USB_SERIAL_SAFE_PADDED=y
-# CONFIG_USB_SERIAL_SAMBA is not set
-# CONFIG_USB_SERIAL_SIEMENS_MPI is not set
-# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
-# CONFIG_USB_SERIAL_SPCP8X5 is not set
-# CONFIG_USB_SERIAL_SSU100 is not set
-# CONFIG_USB_SERIAL_SYMBOL is not set
-# CONFIG_USB_SERIAL_TI is not set
-# CONFIG_USB_SERIAL_VISOR is not set
-# CONFIG_USB_SERIAL_VIVOPAY_SERIAL is not set
-# CONFIG_USB_SERIAL_WHITEHEAT is not set
-# CONFIG_USB_SERIAL_XIRCOM is not set
-# CONFIG_USB_SERIAL_ZIO is not set
-# CONFIG_USB_SEVSEG is not set
-# CONFIG_USB_SIERRA_NET is not set
-# CONFIG_USB_SISUSBVGA is not set
-# CONFIG_USB_SL811_HCD is not set
-# CONFIG_USB_SN9C102 is not set
-# CONFIG_USB_SPEEDTOUCH is not set
-# CONFIG_USB_STKWEBCAM is not set
-# CONFIG_USB_STORAGE is not set
-# CONFIG_USB_STORAGE_ALAUDA is not set
-# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
-# CONFIG_USB_STORAGE_DATAFAB is not set
-# CONFIG_USB_STORAGE_DEBUG is not set
-# CONFIG_USB_STORAGE_FREECOM is not set
-# CONFIG_USB_STORAGE_ISD200 is not set
-# CONFIG_USB_STORAGE_JUMPSHOT is not set
-# CONFIG_USB_STORAGE_KARMA is not set
-# CONFIG_USB_STORAGE_ONETOUCH is not set
-# CONFIG_USB_STORAGE_SDDR09 is not set
-# CONFIG_USB_STORAGE_SDDR55 is not set
-# CONFIG_USB_STORAGE_USBAT is not set
-# CONFIG_USB_STV06XX is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_USB_SUSPEND is not set
-# CONFIG_USB_TEST is not set
-# CONFIG_USB_TMC is not set
-# CONFIG_USB_TRANCEVIBRATOR is not set
-# CONFIG_USB_UAS is not set
-# CONFIG_USB_UEAGLEATM is not set
-# CONFIG_USB_ULPI is not set
-# CONFIG_USB_USBNET is not set
-# CONFIG_USB_USS720 is not set
-# CONFIG_USB_VICAM is not set
-# CONFIG_USB_VIDEO_CLASS is not set
-CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
-# CONFIG_USB_WDM is not set
-# CONFIG_USB_WHCI_HCD is not set
-# CONFIG_USB_WUSB is not set
-# CONFIG_USB_WUSB_CBAF is not set
-# CONFIG_USB_XHCI_HCD is not set
-# CONFIG_USB_XUSBATM is not set
-# CONFIG_USB_YUREX is not set
-# CONFIG_USB_ZD1201 is not set
-# CONFIG_USB_ZR364XX is not set
-# CONFIG_USE_GENERIC_SMP_HELPERS is not set
-# CONFIG_USE_OF is not set
-# CONFIG_UTS_NS is not set
-# CONFIG_UWB is not set
-# CONFIG_V4L_MEM2MEM_DRIVERS is not set
-# CONFIG_VETH is not set
-# CONFIG_VFAT_FS is not set
-# CONFIG_VGASTATE is not set
-# CONFIG_VGA_ARB is not set
-# CONFIG_VGA_SWITCHEROO is not set
-# CONFIG_VIA_RHINE is not set
-# CONFIG_VIA_VELOCITY is not set
-# CONFIG_VIDEO_ADV7170 is not set
-# CONFIG_VIDEO_ADV7175 is not set
-# CONFIG_VIDEO_ADV7180 is not set
-# CONFIG_VIDEO_ADV7343 is not set
-# CONFIG_VIDEO_ADV_DEBUG is not set
-# CONFIG_VIDEO_AK881X is not set
-# CONFIG_VIDEO_ALLOW_V4L1 is not set
-# CONFIG_VIDEO_BT819 is not set
-# CONFIG_VIDEO_BT848 is not set
-# CONFIG_VIDEO_BT856 is not set
-# CONFIG_VIDEO_BT866 is not set
-# CONFIG_VIDEO_BWQCAM is not set
-# CONFIG_VIDEO_CAFE_CCIC is not set
-# CONFIG_VIDEO_CAPTURE_DRIVERS is not set
-# CONFIG_VIDEO_CPIA is not set
-# CONFIG_VIDEO_CQCAM is not set
-# CONFIG_VIDEO_CS5345 is not set
-# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_CX231XX is not set
-# CONFIG_VIDEO_CX2341X is not set
-# CONFIG_VIDEO_CX25840 is not set
-# CONFIG_VIDEO_CX88 is not set
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_VIDEO_DT3155 is not set
-# CONFIG_VIDEO_EM28XX is not set
-# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
-# CONFIG_VIDEO_GO7007 is not set
-# CONFIG_VIDEO_HDPVR is not set
-# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
-# CONFIG_VIDEO_HEXIUM_GEMINI is not set
-# CONFIG_VIDEO_HEXIUM_ORION is not set
-# CONFIG_VIDEO_IR_I2C is not set
-# CONFIG_VIDEO_IVTV is not set
-# CONFIG_VIDEO_KS0127 is not set
-# CONFIG_VIDEO_M52790 is not set
-# CONFIG_VIDEO_MEDIA is not set
-# CONFIG_VIDEO_MSP3400 is not set
-# CONFIG_VIDEO_MT9V011 is not set
-# CONFIG_VIDEO_MXB is not set
-# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_VIDEO_OV7670 is not set
-# CONFIG_VIDEO_PMS is not set
-# CONFIG_VIDEO_PVRUSB2 is not set
-# CONFIG_VIDEO_SAA5246A is not set
-# CONFIG_VIDEO_SAA5249 is not set
-# CONFIG_VIDEO_SAA6588 is not set
-# CONFIG_VIDEO_SAA7110 is not set
-# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA7127 is not set
-# CONFIG_VIDEO_SAA7134 is not set
-# CONFIG_VIDEO_SAA717X is not set
-# CONFIG_VIDEO_SAA7185 is not set
-# CONFIG_VIDEO_SAA7191 is not set
-# CONFIG_VIDEO_SH_MOBILE_CEU is not set
-# CONFIG_VIDEO_SR030PC30 is not set
-# CONFIG_VIDEO_STRADIS is not set
-# CONFIG_VIDEO_TCM825X is not set
-# CONFIG_VIDEO_TDA7432 is not set
-# CONFIG_VIDEO_TDA9840 is not set
-# CONFIG_VIDEO_TDA9875 is not set
-# CONFIG_VIDEO_TEA6415C is not set
-# CONFIG_VIDEO_TEA6420 is not set
-# CONFIG_VIDEO_THS7303 is not set
-# CONFIG_VIDEO_TIMBERDALE is not set
-# CONFIG_VIDEO_TLV320AIC23B is not set
-# CONFIG_VIDEO_TM6000 is not set
-# CONFIG_VIDEO_TVAUDIO is not set
-# CONFIG_VIDEO_TVP514X is not set
-# CONFIG_VIDEO_TVP5150 is not set
-# CONFIG_VIDEO_TVP7002 is not set
-# CONFIG_VIDEO_UPD64031A is not set
-# CONFIG_VIDEO_UPD64083 is not set
-# CONFIG_VIDEO_USBVISION is not set
-# CONFIG_VIDEO_V4L1 is not set
-CONFIG_VIDEO_V4L1_COMPAT=y
-# CONFIG_VIDEO_V4L2 is not set
-# CONFIG_VIDEO_V4L2_COMMON is not set
-# CONFIG_VIDEO_VIVI is not set
-# CONFIG_VIDEO_VP27SMPX is not set
-# CONFIG_VIDEO_VPX3220 is not set
-# CONFIG_VIDEO_WM8739 is not set
-# CONFIG_VIDEO_WM8775 is not set
-# CONFIG_VIDEO_ZORAN is not set
-# CONFIG_VIRQ_DEBUG is not set
-# CONFIG_VIRTUALIZATION is not set
-CONFIG_VIRT_TO_BUS=y
-# CONFIG_VITESSE_PHY is not set
-CONFIG_VLAN_8021Q=y
-# CONFIG_VLAN_8021Q_GVRP is not set
-# CONFIG_VME_BUS is not set
-# CONFIG_VMSPLIT_1G is not set
-# CONFIG_VMSPLIT_2G is not set
-# CONFIG_VMSPLIT_2G_OPT is not set
-CONFIG_VMSPLIT_3G=y
-# CONFIG_VMSPLIT_3G_OPT is not set
-# CONFIG_VMXNET3 is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_VT is not set
-# CONFIG_VT6655 is not set
-# CONFIG_VT6656 is not set
-# CONFIG_VXFS_FS is not set
-# CONFIG_W1 is not set
-# CONFIG_W1_CON is not set
-# CONFIG_W1_MASTER_DS1WM is not set
-# CONFIG_W1_MASTER_DS2482 is not set
-# CONFIG_W1_MASTER_DS2490 is not set
-# CONFIG_W1_MASTER_GPIO is not set
-# CONFIG_W1_MASTER_MATROX is not set
-# CONFIG_W1_SLAVE_BQ27000 is not set
-# CONFIG_W1_SLAVE_DS2423 is not set
-# CONFIG_W1_SLAVE_DS2431 is not set
-# CONFIG_W1_SLAVE_DS2433 is not set
-# CONFIG_W1_SLAVE_DS2760 is not set
-# CONFIG_W1_SLAVE_SMEM is not set
-# CONFIG_W1_SLAVE_THERM is not set
-# CONFIG_W83627HF_WDT is not set
-# CONFIG_W83697HF_WDT is not set
-# CONFIG_W83877F_WDT is not set
-# CONFIG_W83977F_WDT is not set
-# CONFIG_WAN is not set
-# CONFIG_WANXL is not set
-# CONFIG_WAN_ROUTER is not set
-CONFIG_WATCHDOG=y
-# CONFIG_WATCHDOG_NOWAYOUT is not set
-# CONFIG_WDTPCI is not set
-CONFIG_WEXT_CORE=y
-CONFIG_WEXT_PRIV=y
-CONFIG_WEXT_PROC=y
-CONFIG_WEXT_SPY=y
-# CONFIG_WIMAX is not set
-CONFIG_WIRELESS=y
-CONFIG_WIRELESS_EXT=y
-# CONFIG_WIRELESS_EXT_SYSFS is not set
-# CONFIG_WLAGS49_H2 is not set
-# CONFIG_WLAGS49_H25 is not set
-CONFIG_WLAN=y
-# CONFIG_WORKQUEUE_TRACER is not set
-# CONFIG_WR_PPMC is not set
-# CONFIG_X25 is not set
-CONFIG_XFRM=y
-# CONFIG_XFRM_IPCOMP is not set
-# CONFIG_XFRM_MIGRATE is not set
-# CONFIG_XFRM_STATISTICS is not set
-# CONFIG_XFRM_SUB_POLICY is not set
-# CONFIG_XFRM_USER is not set
-# CONFIG_XFS_DEBUG is not set
-# CONFIG_XFS_FS is not set
-# CONFIG_XFS_POSIX_ACL is not set
-# CONFIG_XFS_QUOTA is not set
-# CONFIG_XFS_RT is not set
-# CONFIG_XILINX_EMACLITE is not set
-# CONFIG_XILINX_LL_TEMAC is not set
-# CONFIG_XIP_KERNEL is not set
-# CONFIG_XMON is not set
-# CONFIG_XZ_DEC is not set
-# CONFIG_XZ_DEC_ARM is not set
-# CONFIG_XZ_DEC_ARMTHUMB is not set
-# CONFIG_XZ_DEC_BCJ is not set
-# CONFIG_XZ_DEC_IA64 is not set
-# CONFIG_XZ_DEC_POWERPC is not set
-# CONFIG_XZ_DEC_SPARC is not set
-# CONFIG_XZ_DEC_TEST is not set
-# CONFIG_XZ_DEC_X86 is not set
-# CONFIG_YAFFS_FS is not set
-# CONFIG_YAM is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_YENTA is not set
-# CONFIG_YENTA_O2 is not set
-# CONFIG_YENTA_RICOH is not set
-# CONFIG_YENTA_TI is not set
-# CONFIG_YENTA_TOSHIBA is not set
-# CONFIG_ZD1211RW is not set
-# CONFIG_ZD1211RW_DEBUG is not set
-# CONFIG_ZEROPLUS_FF is not set
-CONFIG_ZISOFS=y
-CONFIG_ZLIB_DEFLATE=y
-CONFIG_ZLIB_INFLATE=y
-CONFIG_ZONE_DMA=y
-CONFIG_ZONE_DMA_FLAG=1
-# CONFIG_ZRAM is not set
diff --git a/target/linux/generic/patches-2.6.38/020-ssb_update.patch b/target/linux/generic/patches-2.6.38/020-ssb_update.patch
deleted file mode 100644
index 8578f75310..0000000000
--- a/target/linux/generic/patches-2.6.38/020-ssb_update.patch
+++ /dev/null
@@ -1,1950 +0,0 @@
---- a/drivers/ssb/main.c
-+++ b/drivers/ssb/main.c
-@@ -3,7 +3,7 @@
-  * Subsystem core
-  *
-  * Copyright 2005, Broadcom Corporation
-- * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
-@@ -12,6 +12,7 @@
- 
- #include <linux/delay.h>
- #include <linux/io.h>
-+#include <linux/module.h>
- #include <linux/ssb/ssb.h>
- #include <linux/ssb/ssb_regs.h>
- #include <linux/ssb/ssb_driver_gige.h>
-@@ -139,19 +140,6 @@ static void ssb_device_put(struct ssb_de
- 		put_device(dev->dev);
- }
- 
--static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv)
--{
--	if (drv)
--		get_driver(&drv->drv);
--	return drv;
--}
--
--static inline void ssb_driver_put(struct ssb_driver *drv)
--{
--	if (drv)
--		put_driver(&drv->drv);
--}
--
- static int ssb_device_resume(struct device *dev)
- {
- 	struct ssb_device *ssb_dev = dev_to_ssb_dev(dev);
-@@ -249,11 +237,9 @@ int ssb_devices_freeze(struct ssb_bus *b
- 			ssb_device_put(sdev);
- 			continue;
- 		}
--		sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver));
--		if (!sdrv || SSB_WARN_ON(!sdrv->remove)) {
--			ssb_device_put(sdev);
-+		sdrv = drv_to_ssb_drv(sdev->dev->driver);
-+		if (SSB_WARN_ON(!sdrv->remove))
- 			continue;
--		}
- 		sdrv->remove(sdev);
- 		ctx->device_frozen[i] = 1;
- 	}
-@@ -292,7 +278,6 @@ int ssb_devices_thaw(struct ssb_freeze_c
- 				   dev_name(sdev->dev));
- 			result = err;
- 		}
--		ssb_driver_put(sdrv);
- 		ssb_device_put(sdev);
- 	}
- 
-@@ -557,7 +542,7 @@ error:
- }
- 
- /* Needs ssb_buses_lock() */
--static int ssb_attach_queued_buses(void)
-+static int __devinit ssb_attach_queued_buses(void)
- {
- 	struct ssb_bus *bus, *n;
- 	int err = 0;
-@@ -768,9 +753,9 @@ out:
- 	return err;
- }
- 
--static int ssb_bus_register(struct ssb_bus *bus,
--			    ssb_invariants_func_t get_invariants,
--			    unsigned long baseaddr)
-+static int __devinit ssb_bus_register(struct ssb_bus *bus,
-+				      ssb_invariants_func_t get_invariants,
-+				      unsigned long baseaddr)
- {
- 	int err;
- 
-@@ -851,8 +836,8 @@ err_disable_xtal:
- }
- 
- #ifdef CONFIG_SSB_PCIHOST
--int ssb_bus_pcibus_register(struct ssb_bus *bus,
--			    struct pci_dev *host_pci)
-+int __devinit ssb_bus_pcibus_register(struct ssb_bus *bus,
-+				      struct pci_dev *host_pci)
- {
- 	int err;
- 
-@@ -875,9 +860,9 @@ EXPORT_SYMBOL(ssb_bus_pcibus_register);
- #endif /* CONFIG_SSB_PCIHOST */
- 
- #ifdef CONFIG_SSB_PCMCIAHOST
--int ssb_bus_pcmciabus_register(struct ssb_bus *bus,
--			       struct pcmcia_device *pcmcia_dev,
--			       unsigned long baseaddr)
-+int __devinit ssb_bus_pcmciabus_register(struct ssb_bus *bus,
-+					 struct pcmcia_device *pcmcia_dev,
-+					 unsigned long baseaddr)
- {
- 	int err;
- 
-@@ -897,8 +882,9 @@ EXPORT_SYMBOL(ssb_bus_pcmciabus_register
- #endif /* CONFIG_SSB_PCMCIAHOST */
- 
- #ifdef CONFIG_SSB_SDIOHOST
--int ssb_bus_sdiobus_register(struct ssb_bus *bus, struct sdio_func *func,
--			     unsigned int quirks)
-+int __devinit ssb_bus_sdiobus_register(struct ssb_bus *bus,
-+				       struct sdio_func *func,
-+				       unsigned int quirks)
- {
- 	int err;
- 
-@@ -918,9 +904,9 @@ int ssb_bus_sdiobus_register(struct ssb_
- EXPORT_SYMBOL(ssb_bus_sdiobus_register);
- #endif /* CONFIG_SSB_PCMCIAHOST */
- 
--int ssb_bus_ssbbus_register(struct ssb_bus *bus,
--			    unsigned long baseaddr,
--			    ssb_invariants_func_t get_invariants)
-+int __devinit ssb_bus_ssbbus_register(struct ssb_bus *bus,
-+				      unsigned long baseaddr,
-+				      ssb_invariants_func_t get_invariants)
- {
- 	int err;
- 
-@@ -1001,8 +987,8 @@ u32 ssb_calc_clock_rate(u32 plltype, u32
- 	switch (plltype) {
- 	case SSB_PLLTYPE_6: /* 100/200 or 120/240 only */
- 		if (m & SSB_CHIPCO_CLK_T6_MMASK)
--			return SSB_CHIPCO_CLK_T6_M0;
--		return SSB_CHIPCO_CLK_T6_M1;
-+			return SSB_CHIPCO_CLK_T6_M1;
-+		return SSB_CHIPCO_CLK_T6_M0;
- 	case SSB_PLLTYPE_1: /* 48Mhz base, 3 dividers */
- 	case SSB_PLLTYPE_3: /* 25Mhz, 2 dividers */
- 	case SSB_PLLTYPE_4: /* 48Mhz, 4 dividers */
-@@ -1092,6 +1078,9 @@ u32 ssb_clockspeed(struct ssb_bus *bus)
- 	u32 plltype;
- 	u32 clkctl_n, clkctl_m;
- 
-+	if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
-+		return ssb_pmu_get_controlclock(&bus->chipco);
-+
- 	if (ssb_extif_available(&bus->extif))
- 		ssb_extif_get_clockcontrol(&bus->extif, &plltype,
- 					   &clkctl_n, &clkctl_m);
-@@ -1117,23 +1106,22 @@ static u32 ssb_tmslow_reject_bitmask(str
- {
- 	u32 rev = ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_SSBREV;
- 
--	/* The REJECT bit changed position in TMSLOW between
--	 * Backplane revisions. */
-+	/* The REJECT bit seems to be different for Backplane rev 2.3 */
- 	switch (rev) {
- 	case SSB_IDLOW_SSBREV_22:
--		return SSB_TMSLOW_REJECT_22;
-+	case SSB_IDLOW_SSBREV_24:
-+	case SSB_IDLOW_SSBREV_26:
-+		return SSB_TMSLOW_REJECT;
- 	case SSB_IDLOW_SSBREV_23:
- 		return SSB_TMSLOW_REJECT_23;
--	case SSB_IDLOW_SSBREV_24:     /* TODO - find the proper REJECT bits */
--	case SSB_IDLOW_SSBREV_25:     /* same here */
--	case SSB_IDLOW_SSBREV_26:     /* same here */
-+	case SSB_IDLOW_SSBREV_25:     /* TODO - find the proper REJECT bit */
- 	case SSB_IDLOW_SSBREV_27:     /* same here */
--		return SSB_TMSLOW_REJECT_23;	/* this is a guess */
-+		return SSB_TMSLOW_REJECT;	/* this is a guess */
- 	default:
- 		printk(KERN_INFO "ssb: Backplane Revision 0x%.8X\n", rev);
- 		WARN_ON(1);
- 	}
--	return (SSB_TMSLOW_REJECT_22 | SSB_TMSLOW_REJECT_23);
-+	return (SSB_TMSLOW_REJECT | SSB_TMSLOW_REJECT_23);
- }
- 
- int ssb_device_is_enabled(struct ssb_device *dev)
-@@ -1192,10 +1180,10 @@ void ssb_device_enable(struct ssb_device
- }
- EXPORT_SYMBOL(ssb_device_enable);
- 
--/* Wait for a bit in a register to get set or unset.
-+/* Wait for bitmask in a register to get set or cleared.
-  * timeout is in units of ten-microseconds */
--static int ssb_wait_bit(struct ssb_device *dev, u16 reg, u32 bitmask,
--			int timeout, int set)
-+static int ssb_wait_bits(struct ssb_device *dev, u16 reg, u32 bitmask,
-+			 int timeout, int set)
- {
- 	int i;
- 	u32 val;
-@@ -1203,7 +1191,7 @@ static int ssb_wait_bit(struct ssb_devic
- 	for (i = 0; i < timeout; i++) {
- 		val = ssb_read32(dev, reg);
- 		if (set) {
--			if (val & bitmask)
-+			if ((val & bitmask) == bitmask)
- 				return 0;
- 		} else {
- 			if (!(val & bitmask))
-@@ -1220,20 +1208,38 @@ static int ssb_wait_bit(struct ssb_devic
- 
- void ssb_device_disable(struct ssb_device *dev, u32 core_specific_flags)
- {
--	u32 reject;
-+	u32 reject, val;
- 
- 	if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_RESET)
- 		return;
- 
- 	reject = ssb_tmslow_reject_bitmask(dev);
--	ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
--	ssb_wait_bit(dev, SSB_TMSLOW, reject, 1000, 1);
--	ssb_wait_bit(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
--	ssb_write32(dev, SSB_TMSLOW,
--		    SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
--		    reject | SSB_TMSLOW_RESET |
--		    core_specific_flags);
--	ssb_flush_tmslow(dev);
-+
-+	if (ssb_read32(dev, SSB_TMSLOW) & SSB_TMSLOW_CLOCK) {
-+		ssb_write32(dev, SSB_TMSLOW, reject | SSB_TMSLOW_CLOCK);
-+		ssb_wait_bits(dev, SSB_TMSLOW, reject, 1000, 1);
-+		ssb_wait_bits(dev, SSB_TMSHIGH, SSB_TMSHIGH_BUSY, 1000, 0);
-+
-+		if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
-+			val = ssb_read32(dev, SSB_IMSTATE);
-+			val |= SSB_IMSTATE_REJECT;
-+			ssb_write32(dev, SSB_IMSTATE, val);
-+			ssb_wait_bits(dev, SSB_IMSTATE, SSB_IMSTATE_BUSY, 1000,
-+				      0);
-+		}
-+
-+		ssb_write32(dev, SSB_TMSLOW,
-+			SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
-+			reject | SSB_TMSLOW_RESET |
-+			core_specific_flags);
-+		ssb_flush_tmslow(dev);
-+
-+		if (ssb_read32(dev, SSB_IDLOW) & SSB_IDLOW_INITIATOR) {
-+			val = ssb_read32(dev, SSB_IMSTATE);
-+			val &= ~SSB_IMSTATE_REJECT;
-+			ssb_write32(dev, SSB_IMSTATE, val);
-+		}
-+	}
- 
- 	ssb_write32(dev, SSB_TMSLOW,
- 		    reject | SSB_TMSLOW_RESET |
-@@ -1242,13 +1248,34 @@ void ssb_device_disable(struct ssb_devic
- }
- EXPORT_SYMBOL(ssb_device_disable);
- 
-+/* Some chipsets need routing known for PCIe and 64-bit DMA */
-+static bool ssb_dma_translation_special_bit(struct ssb_device *dev)
-+{
-+	u16 chip_id = dev->bus->chip_id;
-+
-+	if (dev->id.coreid == SSB_DEV_80211) {
-+		return (chip_id == 0x4322 || chip_id == 43221 ||
-+			chip_id == 43231 || chip_id == 43222);
-+	}
-+
-+	return 0;
-+}
-+
- u32 ssb_dma_translation(struct ssb_device *dev)
- {
- 	switch (dev->bus->bustype) {
- 	case SSB_BUSTYPE_SSB:
- 		return 0;
- 	case SSB_BUSTYPE_PCI:
--		return SSB_PCI_DMA;
-+		if (pci_is_pcie(dev->bus->host_pci) &&
-+		    ssb_read32(dev, SSB_TMSHIGH) & SSB_TMSHIGH_DMA64) {
-+			return SSB_PCIE_DMA_H32;
-+		} else {
-+			if (ssb_dma_translation_special_bit(dev))
-+				return SSB_PCIE_DMA_H32;
-+			else
-+				return SSB_PCI_DMA;
-+		}
- 	default:
- 		__ssb_dma_not_implemented(dev);
- 	}
-@@ -1291,20 +1318,20 @@ EXPORT_SYMBOL(ssb_bus_may_powerdown);
- 
- int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl)
- {
--	struct ssb_chipcommon *cc;
- 	int err;
- 	enum ssb_clkmode mode;
- 
- 	err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1);
- 	if (err)
- 		goto error;
--	cc = &bus->chipco;
--	mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
--	ssb_chipco_set_clockmode(cc, mode);
- 
- #ifdef CONFIG_SSB_DEBUG
- 	bus->powered_up = 1;
- #endif
-+
-+	mode = dynamic_pctl ? SSB_CLKMODE_DYNAMIC : SSB_CLKMODE_FAST;
-+	ssb_chipco_set_clockmode(&bus->chipco, mode);
-+
- 	return 0;
- error:
- 	ssb_printk(KERN_ERR PFX "Bus powerup failed\n");
-@@ -1312,6 +1339,37 @@ error:
- }
- EXPORT_SYMBOL(ssb_bus_powerup);
- 
-+static void ssb_broadcast_value(struct ssb_device *dev,
-+				u32 address, u32 data)
-+{
-+#ifdef CONFIG_SSB_DRIVER_PCICORE
-+	/* This is used for both, PCI and ChipCommon core, so be careful. */
-+	BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
-+	BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
-+#endif
-+
-+	ssb_write32(dev, SSB_CHIPCO_BCAST_ADDR, address);
-+	ssb_read32(dev, SSB_CHIPCO_BCAST_ADDR); /* flush */
-+	ssb_write32(dev, SSB_CHIPCO_BCAST_DATA, data);
-+	ssb_read32(dev, SSB_CHIPCO_BCAST_DATA); /* flush */
-+}
-+
-+void ssb_commit_settings(struct ssb_bus *bus)
-+{
-+	struct ssb_device *dev;
-+
-+#ifdef CONFIG_SSB_DRIVER_PCICORE
-+	dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
-+#else
-+	dev = bus->chipco.dev;
-+#endif
-+	if (WARN_ON(!dev))
-+		return;
-+	/* This forces an update of the cached registers. */
-+	ssb_broadcast_value(dev, 0xFD8, 0);
-+}
-+EXPORT_SYMBOL(ssb_commit_settings);
-+
- u32 ssb_admatch_base(u32 adm)
- {
- 	u32 base = 0;
---- a/drivers/ssb/pci.c
-+++ b/drivers/ssb/pci.c
-@@ -1,7 +1,7 @@
- /*
-  * Sonics Silicon Backplane PCI-Hostbus related functions.
-  *
-- * Copyright (C) 2005-2006 Michael Buesch <mb@bu3sch.de>
-+ * Copyright (C) 2005-2006 Michael Buesch <m@bues.ch>
-  * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
-  * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
-  * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
-@@ -331,7 +331,6 @@ static void sprom_extract_r123(struct ss
- {
- 	int i;
- 	u16 v;
--	s8 gain;
- 	u16 loc[3];
- 
- 	if (out->revision == 3)			/* rev 3 moved MAC */
-@@ -390,20 +389,12 @@ static void sprom_extract_r123(struct ss
- 		SPEX(boardflags_hi, SSB_SPROM2_BFLHI, 0xFFFF, 0);
- 
- 	/* Extract the antenna gain values. */
--	gain = r123_extract_antgain(out->revision, in,
--				    SSB_SPROM1_AGAIN_BG,
--				    SSB_SPROM1_AGAIN_BG_SHIFT);
--	out->antenna_gain.ghz24.a0 = gain;
--	out->antenna_gain.ghz24.a1 = gain;
--	out->antenna_gain.ghz24.a2 = gain;
--	out->antenna_gain.ghz24.a3 = gain;
--	gain = r123_extract_antgain(out->revision, in,
--				    SSB_SPROM1_AGAIN_A,
--				    SSB_SPROM1_AGAIN_A_SHIFT);
--	out->antenna_gain.ghz5.a0 = gain;
--	out->antenna_gain.ghz5.a1 = gain;
--	out->antenna_gain.ghz5.a2 = gain;
--	out->antenna_gain.ghz5.a3 = gain;
-+	out->antenna_gain.a0 = r123_extract_antgain(out->revision, in,
-+						    SSB_SPROM1_AGAIN_BG,
-+						    SSB_SPROM1_AGAIN_BG_SHIFT);
-+	out->antenna_gain.a1 = r123_extract_antgain(out->revision, in,
-+						    SSB_SPROM1_AGAIN_A,
-+						    SSB_SPROM1_AGAIN_A_SHIFT);
- }
- 
- /* Revs 4 5 and 8 have partially shared layout */
-@@ -468,10 +459,14 @@ static void sprom_extract_r45(struct ssb
- 		SPEX(country_code, SSB_SPROM4_CCODE, 0xFFFF, 0);
- 		SPEX(boardflags_lo, SSB_SPROM4_BFLLO, 0xFFFF, 0);
- 		SPEX(boardflags_hi, SSB_SPROM4_BFLHI, 0xFFFF, 0);
-+		SPEX(boardflags2_lo, SSB_SPROM4_BFL2LO, 0xFFFF, 0);
-+		SPEX(boardflags2_hi, SSB_SPROM4_BFL2HI, 0xFFFF, 0);
- 	} else {
- 		SPEX(country_code, SSB_SPROM5_CCODE, 0xFFFF, 0);
- 		SPEX(boardflags_lo, SSB_SPROM5_BFLLO, 0xFFFF, 0);
- 		SPEX(boardflags_hi, SSB_SPROM5_BFLHI, 0xFFFF, 0);
-+		SPEX(boardflags2_lo, SSB_SPROM5_BFL2LO, 0xFFFF, 0);
-+		SPEX(boardflags2_hi, SSB_SPROM5_BFL2HI, 0xFFFF, 0);
- 	}
- 	SPEX(ant_available_a, SSB_SPROM4_ANTAVAIL, SSB_SPROM4_ANTAVAIL_A,
- 	     SSB_SPROM4_ANTAVAIL_A_SHIFT);
-@@ -500,16 +495,14 @@ static void sprom_extract_r45(struct ssb
- 	}
- 
- 	/* Extract the antenna gain values. */
--	SPEX(antenna_gain.ghz24.a0, SSB_SPROM4_AGAIN01,
-+	SPEX(antenna_gain.a0, SSB_SPROM4_AGAIN01,
- 	     SSB_SPROM4_AGAIN0, SSB_SPROM4_AGAIN0_SHIFT);
--	SPEX(antenna_gain.ghz24.a1, SSB_SPROM4_AGAIN01,
-+	SPEX(antenna_gain.a1, SSB_SPROM4_AGAIN01,
- 	     SSB_SPROM4_AGAIN1, SSB_SPROM4_AGAIN1_SHIFT);
--	SPEX(antenna_gain.ghz24.a2, SSB_SPROM4_AGAIN23,
-+	SPEX(antenna_gain.a2, SSB_SPROM4_AGAIN23,
- 	     SSB_SPROM4_AGAIN2, SSB_SPROM4_AGAIN2_SHIFT);
--	SPEX(antenna_gain.ghz24.a3, SSB_SPROM4_AGAIN23,
-+	SPEX(antenna_gain.a3, SSB_SPROM4_AGAIN23,
- 	     SSB_SPROM4_AGAIN3, SSB_SPROM4_AGAIN3_SHIFT);
--	memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
--	       sizeof(out->antenna_gain.ghz5));
- 
- 	sprom_extract_r458(out, in);
- 
-@@ -519,7 +512,13 @@ static void sprom_extract_r45(struct ssb
- static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in)
- {
- 	int i;
--	u16 v;
-+	u16 v, o;
-+	u16 pwr_info_offset[] = {
-+		SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
-+		SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
-+	};
-+	BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
-+			ARRAY_SIZE(out->core_pwr_info));
- 
- 	/* extract the MAC address */
- 	for (i = 0; i < 3; i++) {
-@@ -592,16 +591,69 @@ static void sprom_extract_r8(struct ssb_
- 	SPEX32(ofdm5ghpo, SSB_SPROM8_OFDM5GHPO, 0xFFFFFFFF, 0);
- 
- 	/* Extract the antenna gain values. */
--	SPEX(antenna_gain.ghz24.a0, SSB_SPROM8_AGAIN01,
-+	SPEX(antenna_gain.a0, SSB_SPROM8_AGAIN01,
- 	     SSB_SPROM8_AGAIN0, SSB_SPROM8_AGAIN0_SHIFT);
--	SPEX(antenna_gain.ghz24.a1, SSB_SPROM8_AGAIN01,
-+	SPEX(antenna_gain.a1, SSB_SPROM8_AGAIN01,
- 	     SSB_SPROM8_AGAIN1, SSB_SPROM8_AGAIN1_SHIFT);
--	SPEX(antenna_gain.ghz24.a2, SSB_SPROM8_AGAIN23,
-+	SPEX(antenna_gain.a2, SSB_SPROM8_AGAIN23,
- 	     SSB_SPROM8_AGAIN2, SSB_SPROM8_AGAIN2_SHIFT);
--	SPEX(antenna_gain.ghz24.a3, SSB_SPROM8_AGAIN23,
-+	SPEX(antenna_gain.a3, SSB_SPROM8_AGAIN23,
- 	     SSB_SPROM8_AGAIN3, SSB_SPROM8_AGAIN3_SHIFT);
--	memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24,
--	       sizeof(out->antenna_gain.ghz5));
-+
-+	/* Extract cores power info info */
-+	for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
-+		o = pwr_info_offset[i];
-+		SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
-+			SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
-+		SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
-+			SSB_SPROM8_2G_MAXP, 0);
-+
-+		SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
-+
-+		SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
-+			SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
-+		SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
-+			SSB_SPROM8_5G_MAXP, 0);
-+		SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
-+			SSB_SPROM8_5GH_MAXP, 0);
-+		SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
-+			SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
-+
-+		SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
-+	}
-+
-+	/* Extract FEM info */
-+	SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G,
-+		SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
-+	SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G,
-+		SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
-+	SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G,
-+		SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
-+	SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G,
-+		SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
-+	SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G,
-+		SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
-+
-+	SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G,
-+		SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT);
-+	SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G,
-+		SSB_SROM8_FEM_EXTPA_GAIN, SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
-+	SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G,
-+		SSB_SROM8_FEM_PDET_RANGE, SSB_SROM8_FEM_PDET_RANGE_SHIFT);
-+	SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G,
-+		SSB_SROM8_FEM_TR_ISO, SSB_SROM8_FEM_TR_ISO_SHIFT);
-+	SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G,
-+		SSB_SROM8_FEM_ANTSWLUT, SSB_SROM8_FEM_ANTSWLUT_SHIFT);
- 
- 	sprom_extract_r458(out, in);
- 
-@@ -641,7 +693,7 @@ static int sprom_extract(struct ssb_bus
- 		break;
- 	default:
- 		ssb_printk(KERN_WARNING PFX "Unsupported SPROM"
--			   "  revision %d detected. Will extract"
-+			   " revision %d detected. Will extract"
- 			   " v1\n", out->revision);
- 		out->revision = 1;
- 		sprom_extract_r123(out, in);
-@@ -658,7 +710,6 @@ static int sprom_extract(struct ssb_bus
- static int ssb_pci_sprom_get(struct ssb_bus *bus,
- 			     struct ssb_sprom *sprom)
- {
--	const struct ssb_sprom *fallback;
- 	int err;
- 	u16 *buf;
- 
-@@ -666,7 +717,7 @@ static int ssb_pci_sprom_get(struct ssb_
- 		ssb_printk(KERN_ERR PFX "No SPROM available!\n");
- 		return -ENODEV;
- 	}
--	if (bus->chipco.dev) {	/* can be unavailible! */
-+	if (bus->chipco.dev) {	/* can be unavailable! */
- 		/*
- 		 * get SPROM offset: SSB_SPROM_BASE1 except for
- 		 * chipcommon rev >= 31 or chip ID is 0x4312 and
-@@ -703,10 +754,17 @@ static int ssb_pci_sprom_get(struct ssb_
- 		if (err) {
- 			/* All CRC attempts failed.
- 			 * Maybe there is no SPROM on the device?
--			 * If we have a fallback, use that. */
--			fallback = ssb_get_fallback_sprom();
--			if (fallback) {
--				memcpy(sprom, fallback, sizeof(*sprom));
-+			 * Now we ask the arch code if there is some sprom
-+			 * available for this device in some other storage */
-+			err = ssb_fill_sprom_with_fallback(bus, sprom);
-+			if (err) {
-+				ssb_printk(KERN_WARNING PFX "WARNING: Using"
-+					   " fallback SPROM failed (err %d)\n",
-+					   err);
-+			} else {
-+				ssb_dprintk(KERN_DEBUG PFX "Using SPROM"
-+					    " revision %d provided by"
-+					    " platform.\n", sprom->revision);
- 				err = 0;
- 				goto out_free;
- 			}
-@@ -724,12 +782,9 @@ out_free:
- static void ssb_pci_get_boardinfo(struct ssb_bus *bus,
- 				  struct ssb_boardinfo *bi)
- {
--	pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_VENDOR_ID,
--			     &bi->vendor);
--	pci_read_config_word(bus->host_pci, PCI_SUBSYSTEM_ID,
--			     &bi->type);
--	pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
--			     &bi->rev);
-+	bi->vendor = bus->host_pci->subsystem_vendor;
-+	bi->type = bus->host_pci->subsystem_device;
-+	bi->rev = bus->host_pci->revision;
- }
- 
- int ssb_pci_get_invariants(struct ssb_bus *bus,
---- a/include/linux/ssb/ssb_regs.h
-+++ b/include/linux/ssb/ssb_regs.h
-@@ -85,6 +85,8 @@
- #define  SSB_IMSTATE_AP_RSV	0x00000030 /* Reserved */
- #define  SSB_IMSTATE_IBE	0x00020000 /* In Band Error */
- #define  SSB_IMSTATE_TO		0x00040000 /* Timeout */
-+#define  SSB_IMSTATE_BUSY	0x01800000 /* Busy (Backplane rev >= 2.3 only) */
-+#define  SSB_IMSTATE_REJECT	0x02000000 /* Reject (Backplane rev >= 2.3 only) */
- #define SSB_INTVEC		0x0F94     /* SB Interrupt Mask */
- #define  SSB_INTVEC_PCI		0x00000001 /* Enable interrupts for PCI */
- #define  SSB_INTVEC_ENET0	0x00000002 /* Enable interrupts for enet 0 */
-@@ -95,9 +97,8 @@
- #define  SSB_INTVEC_ENET1	0x00000040 /* Enable interrupts for enet 1 */
- #define SSB_TMSLOW		0x0F98     /* SB Target State Low */
- #define  SSB_TMSLOW_RESET	0x00000001 /* Reset */
--#define  SSB_TMSLOW_REJECT_22	0x00000002 /* Reject (Backplane rev 2.2) */
-+#define  SSB_TMSLOW_REJECT	0x00000002 /* Reject (Standard Backplane) */
- #define  SSB_TMSLOW_REJECT_23	0x00000004 /* Reject (Backplane rev 2.3) */
--#define  SSB_TMSLOW_PHYCLK	0x00000010 /* MAC PHY Clock Control Enable */
- #define  SSB_TMSLOW_CLOCK	0x00010000 /* Clock Enable */
- #define  SSB_TMSLOW_FGC		0x00020000 /* Force Gated Clocks On */
- #define  SSB_TMSLOW_PE		0x40000000 /* Power Management Enable */
-@@ -268,6 +269,8 @@
- /* SPROM Revision 4 */
- #define SSB_SPROM4_BFLLO		0x0044	/* Boardflags (low 16 bits) */
- #define SSB_SPROM4_BFLHI		0x0046  /* Board Flags Hi */
-+#define SSB_SPROM4_BFL2LO		0x0048	/* Board flags 2 (low 16 bits) */
-+#define SSB_SPROM4_BFL2HI		0x004A	/* Board flags 2 Hi */
- #define SSB_SPROM4_IL0MAC		0x004C	/* 6 byte MAC address for a/b/g/n */
- #define SSB_SPROM4_CCODE		0x0052	/* Country Code (2 bytes) */
- #define SSB_SPROM4_GPIOA		0x0056	/* Gen. Purpose IO # 0 and 1 */
-@@ -358,6 +361,8 @@
- #define SSB_SPROM5_CCODE		0x0044	/* Country Code (2 bytes) */
- #define SSB_SPROM5_BFLLO		0x004A	/* Boardflags (low 16 bits) */
- #define SSB_SPROM5_BFLHI		0x004C  /* Board Flags Hi */
-+#define SSB_SPROM5_BFL2LO		0x004E	/* Board flags 2 (low 16 bits) */
-+#define SSB_SPROM5_BFL2HI		0x0050	/* Board flags 2 Hi */
- #define SSB_SPROM5_IL0MAC		0x0052	/* 6 byte MAC address for a/b/g/n */
- #define SSB_SPROM5_GPIOA		0x0076	/* Gen. Purpose IO # 0 and 1 */
- #define  SSB_SPROM5_GPIOA_P0		0x00FF	/* Pin 0 */
-@@ -427,6 +432,56 @@
- #define  SSB_SPROM8_RXPO2G		0x00FF	/* 2GHz RX power offset */
- #define  SSB_SPROM8_RXPO5G		0xFF00	/* 5GHz RX power offset */
- #define  SSB_SPROM8_RXPO5G_SHIFT	8
-+#define SSB_SPROM8_FEM2G		0x00AE
-+#define SSB_SPROM8_FEM5G		0x00B0
-+#define  SSB_SROM8_FEM_TSSIPOS		0x0001
-+#define  SSB_SROM8_FEM_TSSIPOS_SHIFT	0
-+#define  SSB_SROM8_FEM_EXTPA_GAIN	0x0006
-+#define  SSB_SROM8_FEM_EXTPA_GAIN_SHIFT	1
-+#define  SSB_SROM8_FEM_PDET_RANGE	0x00F8
-+#define  SSB_SROM8_FEM_PDET_RANGE_SHIFT	3
-+#define  SSB_SROM8_FEM_TR_ISO		0x0700
-+#define  SSB_SROM8_FEM_TR_ISO_SHIFT	8
-+#define  SSB_SROM8_FEM_ANTSWLUT		0xF800
-+#define  SSB_SROM8_FEM_ANTSWLUT_SHIFT	11
-+#define SSB_SPROM8_THERMAL		0x00B2
-+#define SSB_SPROM8_MPWR_RAWTS		0x00B4
-+#define SSB_SPROM8_TS_SLP_OPT_CORRX	0x00B6
-+#define SSB_SPROM8_FOC_HWIQ_IQSWP	0x00B8
-+#define SSB_SPROM8_PHYCAL_TEMPDELTA	0x00BA
-+
-+/* There are 4 blocks with power info sharing the same layout */
-+#define SSB_SROM8_PWR_INFO_CORE0	0x00C0
-+#define SSB_SROM8_PWR_INFO_CORE1	0x00E0
-+#define SSB_SROM8_PWR_INFO_CORE2	0x0100
-+#define SSB_SROM8_PWR_INFO_CORE3	0x0120
-+
-+#define SSB_SROM8_2G_MAXP_ITSSI		0x00
-+#define  SSB_SPROM8_2G_MAXP		0x00FF
-+#define  SSB_SPROM8_2G_ITSSI		0xFF00
-+#define  SSB_SPROM8_2G_ITSSI_SHIFT	8
-+#define SSB_SROM8_2G_PA_0		0x02	/* 2GHz power amp settings */
-+#define SSB_SROM8_2G_PA_1		0x04
-+#define SSB_SROM8_2G_PA_2		0x06
-+#define SSB_SROM8_5G_MAXP_ITSSI		0x08	/* 5GHz ITSSI and 5.3GHz Max Power */
-+#define  SSB_SPROM8_5G_MAXP		0x00FF
-+#define  SSB_SPROM8_5G_ITSSI		0xFF00
-+#define  SSB_SPROM8_5G_ITSSI_SHIFT	8
-+#define SSB_SPROM8_5GHL_MAXP		0x0A	/* 5.2GHz and 5.8GHz Max Power */
-+#define  SSB_SPROM8_5GH_MAXP		0x00FF
-+#define  SSB_SPROM8_5GL_MAXP		0xFF00
-+#define  SSB_SPROM8_5GL_MAXP_SHIFT	8
-+#define SSB_SROM8_5G_PA_0		0x0C	/* 5.3GHz power amp settings */
-+#define SSB_SROM8_5G_PA_1		0x0E
-+#define SSB_SROM8_5G_PA_2		0x10
-+#define SSB_SROM8_5GL_PA_0		0x12	/* 5.2GHz power amp settings */
-+#define SSB_SROM8_5GL_PA_1		0x14
-+#define SSB_SROM8_5GL_PA_2		0x16
-+#define SSB_SROM8_5GH_PA_0		0x18	/* 5.8GHz power amp settings */
-+#define SSB_SROM8_5GH_PA_1		0x1A
-+#define SSB_SROM8_5GH_PA_2		0x1C
-+
-+/* TODO: Make it deprecated */
- #define SSB_SPROM8_MAXP_BG		0x00C0  /* Max Power 2GHz in path 1 */
- #define  SSB_SPROM8_MAXP_BG_MASK	0x00FF  /* Mask for Max Power 2GHz */
- #define  SSB_SPROM8_ITSSI_BG		0xFF00	/* Mask for path 1 itssi_bg */
-@@ -451,12 +506,53 @@
- #define SSB_SPROM8_PA1HIB0		0x00D8	/* 5.8GHz power amp settings */
- #define SSB_SPROM8_PA1HIB1		0x00DA
- #define SSB_SPROM8_PA1HIB2		0x00DC
-+
- #define SSB_SPROM8_CCK2GPO		0x0140	/* CCK power offset */
- #define SSB_SPROM8_OFDM2GPO		0x0142	/* 2.4GHz OFDM power offset */
- #define SSB_SPROM8_OFDM5GPO		0x0146	/* 5.3GHz OFDM power offset */
- #define SSB_SPROM8_OFDM5GLPO		0x014A	/* 5.2GHz OFDM power offset */
- #define SSB_SPROM8_OFDM5GHPO		0x014E	/* 5.8GHz OFDM power offset */
- 
-+/* Values for boardflags_lo read from SPROM */
-+#define SSB_BFL_BTCOEXIST		0x0001	/* implements Bluetooth coexistance */
-+#define SSB_BFL_PACTRL			0x0002	/* GPIO 9 controlling the PA */
-+#define SSB_BFL_AIRLINEMODE		0x0004	/* implements GPIO 13 radio disable indication */
-+#define SSB_BFL_RSSI			0x0008	/* software calculates nrssi slope. */
-+#define SSB_BFL_ENETSPI			0x0010	/* has ephy roboswitch spi */
-+#define SSB_BFL_XTAL_NOSLOW		0x0020	/* no slow clock available */
-+#define SSB_BFL_CCKHIPWR		0x0040	/* can do high power CCK transmission */
-+#define SSB_BFL_ENETADM			0x0080	/* has ADMtek switch */
-+#define SSB_BFL_ENETVLAN		0x0100	/* can do vlan */
-+#define SSB_BFL_AFTERBURNER		0x0200	/* supports Afterburner mode */
-+#define SSB_BFL_NOPCI			0x0400	/* board leaves PCI floating */
-+#define SSB_BFL_FEM			0x0800	/* supports the Front End Module */
-+#define SSB_BFL_EXTLNA			0x1000	/* has an external LNA */
-+#define SSB_BFL_HGPA			0x2000	/* had high gain PA */
-+#define SSB_BFL_BTCMOD			0x4000	/* BFL_BTCOEXIST is given in alternate GPIOs */
-+#define SSB_BFL_ALTIQ			0x8000	/* alternate I/Q settings */
-+
-+/* Values for boardflags_hi read from SPROM */
-+#define SSB_BFH_NOPA			0x0001	/* has no PA */
-+#define SSB_BFH_RSSIINV			0x0002	/* RSSI uses positive slope (not TSSI) */
-+#define SSB_BFH_PAREF			0x0004	/* uses the PARef LDO */
-+#define SSB_BFH_3TSWITCH		0x0008	/* uses a triple throw switch shared with bluetooth */
-+#define SSB_BFH_PHASESHIFT		0x0010	/* can support phase shifter */
-+#define SSB_BFH_BUCKBOOST		0x0020	/* has buck/booster */
-+#define SSB_BFH_FEM_BT			0x0040	/* has FEM and switch to share antenna with bluetooth */
-+
-+/* Values for boardflags2_lo read from SPROM */
-+#define SSB_BFL2_RXBB_INT_REG_DIS	0x0001	/* external RX BB regulator present */
-+#define SSB_BFL2_APLL_WAR		0x0002	/* alternative A-band PLL settings implemented */
-+#define SSB_BFL2_TXPWRCTRL_EN 		0x0004	/* permits enabling TX Power Control */
-+#define SSB_BFL2_2X4_DIV		0x0008	/* 2x4 diversity switch */
-+#define SSB_BFL2_5G_PWRGAIN		0x0010	/* supports 5G band power gain */
-+#define SSB_BFL2_PCIEWAR_OVR		0x0020	/* overrides ASPM and Clkreq settings */
-+#define SSB_BFL2_CAESERS_BRD		0x0040	/* is Caesers board (unused) */
-+#define SSB_BFL2_BTC3WIRE		0x0080	/* used 3-wire bluetooth coexist */
-+#define SSB_BFL2_SKWRKFEM_BRD		0x0100	/* 4321mcm93 uses Skyworks FEM */
-+#define SSB_BFL2_SPUR_WAR		0x0200	/* has a workaround for clock-harmonic spurs */
-+#define SSB_BFL2_GPLL_WAR		0x0400	/* altenative G-band PLL settings implemented */
-+
- /* Values for SSB_SPROM1_BINF_CCODE */
- enum {
- 	SSB_SPROM1CCODE_WORLD = 0,
---- a/drivers/ssb/driver_chipcommon.c
-+++ b/drivers/ssb/driver_chipcommon.c
-@@ -3,7 +3,7 @@
-  * Broadcom ChipCommon core driver
-  *
-  * Copyright 2005, Broadcom Corporation
-- * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
-@@ -46,40 +46,66 @@ void ssb_chipco_set_clockmode(struct ssb
- 	if (!ccdev)
- 		return;
- 	bus = ccdev->bus;
-+
-+	/* We support SLOW only on 6..9 */
-+	if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW)
-+		mode = SSB_CLKMODE_DYNAMIC;
-+
-+	if (cc->capabilities & SSB_CHIPCO_CAP_PMU)
-+		return; /* PMU controls clockmode, separated function needed */
-+	SSB_WARN_ON(ccdev->id.revision >= 20);
-+
- 	/* chipcommon cores prior to rev6 don't support dynamic clock control */
- 	if (ccdev->id.revision < 6)
- 		return;
--	/* chipcommon cores rev10 are a whole new ball game */
-+
-+	/* ChipCommon cores rev10+ need testing */
- 	if (ccdev->id.revision >= 10)
- 		return;
-+
- 	if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL))
- 		return;
- 
- 	switch (mode) {
--	case SSB_CLKMODE_SLOW:
-+	case SSB_CLKMODE_SLOW: /* For revs 6..9 only */
- 		tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
- 		tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW;
- 		chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
- 		break;
- 	case SSB_CLKMODE_FAST:
--		ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
--		tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
--		tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
--		tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
--		chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
-+		if (ccdev->id.revision < 10) {
-+			ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */
-+			tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
-+			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
-+			tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL;
-+			chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
-+		} else {
-+			chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
-+				(chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) |
-+				 SSB_CHIPCO_SYSCLKCTL_FORCEHT));
-+			/* udelay(150); TODO: not available in early init */
-+		}
- 		break;
- 	case SSB_CLKMODE_DYNAMIC:
--		tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
--		tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
--		tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
--		tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
--		if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
--			tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
--		chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
--
--		/* for dynamic control, we have to release our xtal_pu "force on" */
--		if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
--			ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
-+		if (ccdev->id.revision < 10) {
-+			tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL);
-+			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW;
-+			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL;
-+			tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
-+			if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) !=
-+			    SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL)
-+				tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL;
-+			chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp);
-+
-+			/* For dynamic control, we have to release our xtal_pu
-+			 * "force on" */
-+			if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL)
-+				ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0);
-+		} else {
-+			chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL,
-+				(chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) &
-+				 ~SSB_CHIPCO_SYSCLKCTL_FORCEHT));
-+		}
- 		break;
- 	default:
- 		SSB_WARN_ON(1);
-@@ -260,6 +286,12 @@ void ssb_chipcommon_init(struct ssb_chip
- 	if (cc->dev->id.revision >= 11)
- 		cc->status = chipco_read32(cc, SSB_CHIPCO_CHIPSTAT);
- 	ssb_dprintk(KERN_INFO PFX "chipcommon status is 0x%x\n", cc->status);
-+
-+	if (cc->dev->id.revision >= 20) {
-+		chipco_write32(cc, SSB_CHIPCO_GPIOPULLUP, 0);
-+		chipco_write32(cc, SSB_CHIPCO_GPIOPULLDOWN, 0);
-+	}
-+
- 	ssb_pmu_init(cc);
- 	chipco_powercontrol_init(cc);
- 	ssb_chipco_set_clockmode(cc, SSB_CLKMODE_FAST);
---- a/drivers/ssb/driver_chipcommon_pmu.c
-+++ b/drivers/ssb/driver_chipcommon_pmu.c
-@@ -2,7 +2,7 @@
-  * Sonics Silicon Backplane
-  * Broadcom ChipCommon Power Management Unit driver
-  *
-- * Copyright 2009, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2009, Michael Buesch <m@bues.ch>
-  * Copyright 2007, Broadcom Corporation
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-@@ -12,6 +12,9 @@
- #include <linux/ssb/ssb_regs.h>
- #include <linux/ssb/ssb_driver_chipcommon.h>
- #include <linux/delay.h>
-+#ifdef CONFIG_BCM47XX
-+#include <asm/mach-bcm47xx/nvram.h>
-+#endif
- 
- #include "ssb_private.h"
- 
-@@ -91,10 +94,6 @@ static void ssb_pmu0_pllinit_r0(struct s
- 	u32 pmuctl, tmp, pllctl;
- 	unsigned int i;
- 
--	if ((bus->chip_id == 0x5354) && !crystalfreq) {
--		/* The 5354 crystal freq is 25MHz */
--		crystalfreq = 25000;
--	}
- 	if (crystalfreq)
- 		e = pmu0_plltab_find_entry(crystalfreq);
- 	if (!e)
-@@ -320,7 +319,11 @@ static void ssb_pmu_pll_init(struct ssb_
- 	u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */
- 
- 	if (bus->bustype == SSB_BUSTYPE_SSB) {
--		/* TODO: The user may override the crystal frequency. */
-+#ifdef CONFIG_BCM47XX
-+		char buf[20];
-+		if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0)
-+			crystalfreq = simple_strtoul(buf, NULL, 0);
-+#endif
- 	}
- 
- 	switch (bus->chip_id) {
-@@ -329,7 +332,11 @@ static void ssb_pmu_pll_init(struct ssb_
- 		ssb_pmu1_pllinit_r0(cc, crystalfreq);
- 		break;
- 	case 0x4328:
-+		ssb_pmu0_pllinit_r0(cc, crystalfreq);
-+		break;
- 	case 0x5354:
-+		if (crystalfreq == 0)
-+			crystalfreq = 25000;
- 		ssb_pmu0_pllinit_r0(cc, crystalfreq);
- 		break;
- 	case 0x4322:
-@@ -417,12 +424,14 @@ static void ssb_pmu_resources_init(struc
- 	u32 min_msk = 0, max_msk = 0;
- 	unsigned int i;
- 	const struct pmu_res_updown_tab_entry *updown_tab = NULL;
--	unsigned int updown_tab_size;
-+	unsigned int updown_tab_size = 0;
- 	const struct pmu_res_depend_tab_entry *depend_tab = NULL;
--	unsigned int depend_tab_size;
-+	unsigned int depend_tab_size = 0;
- 
- 	switch (bus->chip_id) {
- 	case 0x4312:
-+		 min_msk = 0xCBB;
-+		 break;
- 	case 0x4322:
- 		/* We keep the default settings:
- 		 * min_msk = 0xCBB
-@@ -604,3 +613,34 @@ void ssb_pmu_set_ldo_paref(struct ssb_ch
- 
- EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage);
- EXPORT_SYMBOL(ssb_pmu_set_ldo_paref);
-+
-+u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc)
-+{
-+	struct ssb_bus *bus = cc->dev->bus;
-+
-+	switch (bus->chip_id) {
-+	case 0x5354:
-+		/* 5354 chip uses a non programmable PLL of frequency 240MHz */
-+		return 240000000;
-+	default:
-+		ssb_printk(KERN_ERR PFX
-+			   "ERROR: PMU cpu clock unknown for device %04X\n",
-+			   bus->chip_id);
-+		return 0;
-+	}
-+}
-+
-+u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc)
-+{
-+	struct ssb_bus *bus = cc->dev->bus;
-+
-+	switch (bus->chip_id) {
-+	case 0x5354:
-+		return 120000000;
-+	default:
-+		ssb_printk(KERN_ERR PFX
-+			   "ERROR: PMU controlclock unknown for device %04X\n",
-+			   bus->chip_id);
-+		return 0;
-+	}
-+}
---- a/drivers/ssb/driver_gige.c
-+++ b/drivers/ssb/driver_gige.c
-@@ -3,7 +3,7 @@
-  * Broadcom Gigabit Ethernet core driver
-  *
-  * Copyright 2008, Broadcom Corporation
-- * Copyright 2008, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2008, Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
-@@ -106,8 +106,9 @@ void gige_pcicfg_write32(struct ssb_gige
- 	gige_write32(dev, SSB_GIGE_PCICFG + offset, value);
- }
- 
--static int ssb_gige_pci_read_config(struct pci_bus *bus, unsigned int devfn,
--				    int reg, int size, u32 *val)
-+static int __devinit ssb_gige_pci_read_config(struct pci_bus *bus,
-+					      unsigned int devfn, int reg,
-+					      int size, u32 *val)
- {
- 	struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
- 	unsigned long flags;
-@@ -136,8 +137,9 @@ static int ssb_gige_pci_read_config(stru
- 	return PCIBIOS_SUCCESSFUL;
- }
- 
--static int ssb_gige_pci_write_config(struct pci_bus *bus, unsigned int devfn,
--				     int reg, int size, u32 val)
-+static int __devinit ssb_gige_pci_write_config(struct pci_bus *bus,
-+					       unsigned int devfn, int reg,
-+					       int size, u32 val)
- {
- 	struct ssb_gige *dev = container_of(bus->ops, struct ssb_gige, pci_ops);
- 	unsigned long flags;
-@@ -166,7 +168,8 @@ static int ssb_gige_pci_write_config(str
- 	return PCIBIOS_SUCCESSFUL;
- }
- 
--static int ssb_gige_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
-+static int __devinit ssb_gige_probe(struct ssb_device *sdev,
-+				    const struct ssb_device_id *id)
- {
- 	struct ssb_gige *dev;
- 	u32 base, tmslow, tmshigh;
---- a/drivers/ssb/driver_pcicore.c
-+++ b/drivers/ssb/driver_pcicore.c
-@@ -3,7 +3,7 @@
-  * Broadcom PCI-core driver
-  *
-  * Copyright 2005, Broadcom Corporation
-- * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
-@@ -15,6 +15,11 @@
- 
- #include "ssb_private.h"
- 
-+static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address);
-+static void ssb_pcie_write(struct ssb_pcicore *pc, u32 address, u32 data);
-+static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address);
-+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
-+				u8 address, u16 data);
- 
- static inline
- u32 pcicore_read32(struct ssb_pcicore *pc, u16 offset)
-@@ -69,7 +74,7 @@ static u32 get_cfgspace_addr(struct ssb_
- 	u32 tmp;
- 
- 	/* We do only have one cardbus device behind the bridge. */
--	if (pc->cardbusmode && (dev >= 1))
-+	if (pc->cardbusmode && (dev > 1))
- 		goto out;
- 
- 	if (bus == 0) {
-@@ -309,7 +314,7 @@ int ssb_pcicore_pcibios_map_irq(const st
- 	return ssb_mips_irq(extpci_core->dev) + 2;
- }
- 
--static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
-+static void __devinit ssb_pcicore_init_hostmode(struct ssb_pcicore *pc)
- {
- 	u32 val;
- 
-@@ -374,7 +379,7 @@ static void ssb_pcicore_init_hostmode(st
- 	register_pci_controller(&ssb_pcicore_controller);
- }
- 
--static int pcicore_is_in_hostmode(struct ssb_pcicore *pc)
-+static int __devinit pcicore_is_in_hostmode(struct ssb_pcicore *pc)
- {
- 	struct ssb_bus *bus = pc->dev->bus;
- 	u16 chipid_top;
-@@ -403,25 +408,137 @@ static int pcicore_is_in_hostmode(struct
- }
- #endif /* CONFIG_SSB_PCICORE_HOSTMODE */
- 
-+/**************************************************
-+ * Workarounds.
-+ **************************************************/
-+
-+static void __devinit ssb_pcicore_fix_sprom_core_index(struct ssb_pcicore *pc)
-+{
-+	u16 tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(0));
-+	if (((tmp & 0xF000) >> 12) != pc->dev->core_index) {
-+		tmp &= ~0xF000;
-+		tmp |= (pc->dev->core_index << 12);
-+		pcicore_write16(pc, SSB_PCICORE_SPROM(0), tmp);
-+	}
-+}
-+
-+static u8 ssb_pcicore_polarity_workaround(struct ssb_pcicore *pc)
-+{
-+	return (ssb_pcie_read(pc, 0x204) & 0x10) ? 0xC0 : 0x80;
-+}
-+
-+static void ssb_pcicore_serdes_workaround(struct ssb_pcicore *pc)
-+{
-+	const u8 serdes_pll_device = 0x1D;
-+	const u8 serdes_rx_device = 0x1F;
-+	u16 tmp;
-+
-+	ssb_pcie_mdio_write(pc, serdes_rx_device, 1 /* Control */,
-+			    ssb_pcicore_polarity_workaround(pc));
-+	tmp = ssb_pcie_mdio_read(pc, serdes_pll_device, 1 /* Control */);
-+	if (tmp & 0x4000)
-+		ssb_pcie_mdio_write(pc, serdes_pll_device, 1, tmp & ~0x4000);
-+}
-+
-+static void ssb_pcicore_pci_setup_workarounds(struct ssb_pcicore *pc)
-+{
-+	struct ssb_device *pdev = pc->dev;
-+	struct ssb_bus *bus = pdev->bus;
-+	u32 tmp;
-+
-+	tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
-+	tmp |= SSB_PCICORE_SBTOPCI_PREF;
-+	tmp |= SSB_PCICORE_SBTOPCI_BURST;
-+	pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
-+
-+	if (pdev->id.revision < 5) {
-+		tmp = ssb_read32(pdev, SSB_IMCFGLO);
-+		tmp &= ~SSB_IMCFGLO_SERTO;
-+		tmp |= 2;
-+		tmp &= ~SSB_IMCFGLO_REQTO;
-+		tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
-+		ssb_write32(pdev, SSB_IMCFGLO, tmp);
-+		ssb_commit_settings(bus);
-+	} else if (pdev->id.revision >= 11) {
-+		tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
-+		tmp |= SSB_PCICORE_SBTOPCI_MRM;
-+		pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
-+	}
-+}
-+
-+static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc)
-+{
-+	u32 tmp;
-+	u8 rev = pc->dev->id.revision;
-+
-+	if (rev == 0 || rev == 1) {
-+		/* TLP Workaround register. */
-+		tmp = ssb_pcie_read(pc, 0x4);
-+		tmp |= 0x8;
-+		ssb_pcie_write(pc, 0x4, tmp);
-+	}
-+	if (rev == 1) {
-+		/* DLLP Link Control register. */
-+		tmp = ssb_pcie_read(pc, 0x100);
-+		tmp |= 0x40;
-+		ssb_pcie_write(pc, 0x100, tmp);
-+	}
-+
-+	if (rev == 0) {
-+		const u8 serdes_rx_device = 0x1F;
-+
-+		ssb_pcie_mdio_write(pc, serdes_rx_device,
-+					2 /* Timer */, 0x8128);
-+		ssb_pcie_mdio_write(pc, serdes_rx_device,
-+					6 /* CDR */, 0x0100);
-+		ssb_pcie_mdio_write(pc, serdes_rx_device,
-+					7 /* CDR BW */, 0x1466);
-+	} else if (rev == 3 || rev == 4 || rev == 5) {
-+		/* TODO: DLLP Power Management Threshold */
-+		ssb_pcicore_serdes_workaround(pc);
-+		/* TODO: ASPM */
-+	} else if (rev == 7) {
-+		/* TODO: No PLL down */
-+	}
-+
-+	if (rev >= 6) {
-+		/* Miscellaneous Configuration Fixup */
-+		tmp = pcicore_read16(pc, SSB_PCICORE_SPROM(5));
-+		if (!(tmp & 0x8000))
-+			pcicore_write16(pc, SSB_PCICORE_SPROM(5),
-+					tmp | 0x8000);
-+	}
-+}
- 
- /**************************************************
-  * Generic and Clientmode operation code.
-  **************************************************/
- 
--static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
-+static void __devinit ssb_pcicore_init_clientmode(struct ssb_pcicore *pc)
- {
-+	struct ssb_device *pdev = pc->dev;
-+	struct ssb_bus *bus = pdev->bus;
-+
-+	if (bus->bustype == SSB_BUSTYPE_PCI)
-+		ssb_pcicore_fix_sprom_core_index(pc);
-+
- 	/* Disable PCI interrupts. */
--	ssb_write32(pc->dev, SSB_INTVEC, 0);
-+	ssb_write32(pdev, SSB_INTVEC, 0);
-+
-+	/* Additional PCIe always once-executed workarounds */
-+	if (pc->dev->id.coreid == SSB_DEV_PCIE) {
-+		ssb_pcicore_serdes_workaround(pc);
-+		/* TODO: ASPM */
-+		/* TODO: Clock Request Update */
-+	}
- }
- 
--void ssb_pcicore_init(struct ssb_pcicore *pc)
-+void __devinit ssb_pcicore_init(struct ssb_pcicore *pc)
- {
- 	struct ssb_device *dev = pc->dev;
--	struct ssb_bus *bus;
- 
- 	if (!dev)
- 		return;
--	bus = dev->bus;
- 	if (!ssb_device_is_enabled(dev))
- 		ssb_device_enable(dev, 0);
- 
-@@ -446,11 +563,35 @@ static void ssb_pcie_write(struct ssb_pc
- 	pcicore_write32(pc, 0x134, data);
- }
- 
--static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
--				u8 address, u16 data)
-+static void ssb_pcie_mdio_set_phy(struct ssb_pcicore *pc, u8 phy)
-+{
-+	const u16 mdio_control = 0x128;
-+	const u16 mdio_data = 0x12C;
-+	u32 v;
-+	int i;
-+
-+	v = (1 << 30); /* Start of Transaction */
-+	v |= (1 << 28); /* Write Transaction */
-+	v |= (1 << 17); /* Turnaround */
-+	v |= (0x1F << 18);
-+	v |= (phy << 4);
-+	pcicore_write32(pc, mdio_data, v);
-+
-+	udelay(10);
-+	for (i = 0; i < 200; i++) {
-+		v = pcicore_read32(pc, mdio_control);
-+		if (v & 0x100 /* Trans complete */)
-+			break;
-+		msleep(1);
-+	}
-+}
-+
-+static u16 ssb_pcie_mdio_read(struct ssb_pcicore *pc, u8 device, u8 address)
- {
- 	const u16 mdio_control = 0x128;
- 	const u16 mdio_data = 0x12C;
-+	int max_retries = 10;
-+	u16 ret = 0;
- 	u32 v;
- 	int i;
- 
-@@ -458,46 +599,68 @@ static void ssb_pcie_mdio_write(struct s
- 	v |= 0x2; /* MDIO Clock Divisor */
- 	pcicore_write32(pc, mdio_control, v);
- 
-+	if (pc->dev->id.revision >= 10) {
-+		max_retries = 200;
-+		ssb_pcie_mdio_set_phy(pc, device);
-+	}
-+
- 	v = (1 << 30); /* Start of Transaction */
--	v |= (1 << 28); /* Write Transaction */
-+	v |= (1 << 29); /* Read Transaction */
- 	v |= (1 << 17); /* Turnaround */
--	v |= (u32)device << 22;
-+	if (pc->dev->id.revision < 10)
-+		v |= (u32)device << 22;
- 	v |= (u32)address << 18;
--	v |= data;
- 	pcicore_write32(pc, mdio_data, v);
- 	/* Wait for the device to complete the transaction */
- 	udelay(10);
--	for (i = 0; i < 10; i++) {
-+	for (i = 0; i < max_retries; i++) {
- 		v = pcicore_read32(pc, mdio_control);
--		if (v & 0x100 /* Trans complete */)
-+		if (v & 0x100 /* Trans complete */) {
-+			udelay(10);
-+			ret = pcicore_read32(pc, mdio_data);
- 			break;
-+		}
- 		msleep(1);
- 	}
- 	pcicore_write32(pc, mdio_control, 0);
-+	return ret;
- }
- 
--static void ssb_broadcast_value(struct ssb_device *dev,
--				u32 address, u32 data)
-+static void ssb_pcie_mdio_write(struct ssb_pcicore *pc, u8 device,
-+				u8 address, u16 data)
- {
--	/* This is used for both, PCI and ChipCommon core, so be careful. */
--	BUILD_BUG_ON(SSB_PCICORE_BCAST_ADDR != SSB_CHIPCO_BCAST_ADDR);
--	BUILD_BUG_ON(SSB_PCICORE_BCAST_DATA != SSB_CHIPCO_BCAST_DATA);
-+	const u16 mdio_control = 0x128;
-+	const u16 mdio_data = 0x12C;
-+	int max_retries = 10;
-+	u32 v;
-+	int i;
- 
--	ssb_write32(dev, SSB_PCICORE_BCAST_ADDR, address);
--	ssb_read32(dev, SSB_PCICORE_BCAST_ADDR); /* flush */
--	ssb_write32(dev, SSB_PCICORE_BCAST_DATA, data);
--	ssb_read32(dev, SSB_PCICORE_BCAST_DATA); /* flush */
--}
-+	v = 0x80; /* Enable Preamble Sequence */
-+	v |= 0x2; /* MDIO Clock Divisor */
-+	pcicore_write32(pc, mdio_control, v);
- 
--static void ssb_commit_settings(struct ssb_bus *bus)
--{
--	struct ssb_device *dev;
-+	if (pc->dev->id.revision >= 10) {
-+		max_retries = 200;
-+		ssb_pcie_mdio_set_phy(pc, device);
-+	}
- 
--	dev = bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev;
--	if (WARN_ON(!dev))
--		return;
--	/* This forces an update of the cached registers. */
--	ssb_broadcast_value(dev, 0xFD8, 0);
-+	v = (1 << 30); /* Start of Transaction */
-+	v |= (1 << 28); /* Write Transaction */
-+	v |= (1 << 17); /* Turnaround */
-+	if (pc->dev->id.revision < 10)
-+		v |= (u32)device << 22;
-+	v |= (u32)address << 18;
-+	v |= data;
-+	pcicore_write32(pc, mdio_data, v);
-+	/* Wait for the device to complete the transaction */
-+	udelay(10);
-+	for (i = 0; i < max_retries; i++) {
-+		v = pcicore_read32(pc, mdio_control);
-+		if (v & 0x100 /* Trans complete */)
-+			break;
-+		msleep(1);
-+	}
-+	pcicore_write32(pc, mdio_control, 0);
- }
- 
- int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
-@@ -550,48 +713,10 @@ int ssb_pcicore_dev_irqvecs_enable(struc
- 	if (pc->setup_done)
- 		goto out;
- 	if (pdev->id.coreid == SSB_DEV_PCI) {
--		tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
--		tmp |= SSB_PCICORE_SBTOPCI_PREF;
--		tmp |= SSB_PCICORE_SBTOPCI_BURST;
--		pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
--
--		if (pdev->id.revision < 5) {
--			tmp = ssb_read32(pdev, SSB_IMCFGLO);
--			tmp &= ~SSB_IMCFGLO_SERTO;
--			tmp |= 2;
--			tmp &= ~SSB_IMCFGLO_REQTO;
--			tmp |= 3 << SSB_IMCFGLO_REQTO_SHIFT;
--			ssb_write32(pdev, SSB_IMCFGLO, tmp);
--			ssb_commit_settings(bus);
--		} else if (pdev->id.revision >= 11) {
--			tmp = pcicore_read32(pc, SSB_PCICORE_SBTOPCI2);
--			tmp |= SSB_PCICORE_SBTOPCI_MRM;
--			pcicore_write32(pc, SSB_PCICORE_SBTOPCI2, tmp);
--		}
-+		ssb_pcicore_pci_setup_workarounds(pc);
- 	} else {
- 		WARN_ON(pdev->id.coreid != SSB_DEV_PCIE);
--		//TODO: Better make defines for all these magic PCIE values.
--		if ((pdev->id.revision == 0) || (pdev->id.revision == 1)) {
--			/* TLP Workaround register. */
--			tmp = ssb_pcie_read(pc, 0x4);
--			tmp |= 0x8;
--			ssb_pcie_write(pc, 0x4, tmp);
--		}
--		if (pdev->id.revision == 0) {
--			const u8 serdes_rx_device = 0x1F;
--
--			ssb_pcie_mdio_write(pc, serdes_rx_device,
--					    2 /* Timer */, 0x8128);
--			ssb_pcie_mdio_write(pc, serdes_rx_device,
--					    6 /* CDR */, 0x0100);
--			ssb_pcie_mdio_write(pc, serdes_rx_device,
--					    7 /* CDR BW */, 0x1466);
--		} else if (pdev->id.revision == 1) {
--			/* DLLP Link Control register. */
--			tmp = ssb_pcie_read(pc, 0x100);
--			tmp |= 0x40;
--			ssb_pcie_write(pc, 0x100, tmp);
--		}
-+		ssb_pcicore_pcie_setup_workarounds(pc);
- 	}
- 	pc->setup_done = 1;
- out:
---- a/drivers/ssb/pcihost_wrapper.c
-+++ b/drivers/ssb/pcihost_wrapper.c
-@@ -6,7 +6,7 @@
-  * Copyright (c) 2005 Stefano Brivio <st3@riseup.net>
-  * Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
-  * Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
-- * Copyright (c) 2005-2007 Michael Buesch <mbuesch@freenet.de>
-+ * Copyright (c) 2005-2007 Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
-@@ -53,8 +53,8 @@ static int ssb_pcihost_resume(struct pci
- # define ssb_pcihost_resume	NULL
- #endif /* CONFIG_PM */
- 
--static int ssb_pcihost_probe(struct pci_dev *dev,
--			     const struct pci_device_id *id)
-+static int __devinit ssb_pcihost_probe(struct pci_dev *dev,
-+				       const struct pci_device_id *id)
- {
- 	struct ssb_bus *ssb;
- 	int err = -ENOMEM;
-@@ -110,7 +110,7 @@ static void ssb_pcihost_remove(struct pc
- 	pci_set_drvdata(dev, NULL);
- }
- 
--int ssb_pcihost_register(struct pci_driver *driver)
-+int __devinit ssb_pcihost_register(struct pci_driver *driver)
- {
- 	driver->probe = ssb_pcihost_probe;
- 	driver->remove = ssb_pcihost_remove;
---- a/drivers/ssb/scan.c
-+++ b/drivers/ssb/scan.c
-@@ -2,7 +2,7 @@
-  * Sonics Silicon Backplane
-  * Bus scanning
-  *
-- * Copyright (C) 2005-2007 Michael Buesch <mb@bu3sch.de>
-+ * Copyright (C) 2005-2007 Michael Buesch <m@bues.ch>
-  * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
-  * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
-  * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
-@@ -258,7 +258,10 @@ static int we_support_multiple_80211_cor
- #ifdef CONFIG_SSB_PCIHOST
- 	if (bus->bustype == SSB_BUSTYPE_PCI) {
- 		if (bus->host_pci->vendor == PCI_VENDOR_ID_BROADCOM &&
--		    bus->host_pci->device == 0x4324)
-+		    ((bus->host_pci->device == 0x4313) ||
-+		     (bus->host_pci->device == 0x431A) ||
-+		     (bus->host_pci->device == 0x4321) ||
-+		     (bus->host_pci->device == 0x4324)))
- 			return 1;
- 	}
- #endif /* CONFIG_SSB_PCIHOST */
-@@ -307,8 +310,7 @@ int ssb_bus_scan(struct ssb_bus *bus,
- 	} else {
- 		if (bus->bustype == SSB_BUSTYPE_PCI) {
- 			bus->chip_id = pcidev_to_chipid(bus->host_pci);
--			pci_read_config_word(bus->host_pci, PCI_REVISION_ID,
--					     &bus->chip_rev);
-+			bus->chip_rev = bus->host_pci->revision;
- 			bus->chip_package = 0;
- 		} else {
- 			bus->chip_id = 0x4710;
-@@ -316,6 +318,9 @@ int ssb_bus_scan(struct ssb_bus *bus,
- 			bus->chip_package = 0;
- 		}
- 	}
-+	ssb_printk(KERN_INFO PFX "Found chip with id 0x%04X, rev 0x%02X and "
-+		   "package 0x%02X\n", bus->chip_id, bus->chip_rev,
-+		   bus->chip_package);
- 	if (!bus->nr_devices)
- 		bus->nr_devices = chipid_to_nrcores(bus->chip_id);
- 	if (bus->nr_devices > ARRAY_SIZE(bus->devices)) {
---- a/drivers/ssb/sprom.c
-+++ b/drivers/ssb/sprom.c
-@@ -2,7 +2,7 @@
-  * Sonics Silicon Backplane
-  * Common SPROM support routines
-  *
-- * Copyright (C) 2005-2008 Michael Buesch <mb@bu3sch.de>
-+ * Copyright (C) 2005-2008 Michael Buesch <m@bues.ch>
-  * Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
-  * Copyright (C) 2005 Stefano Brivio <st3@riseup.net>
-  * Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
-@@ -17,7 +17,7 @@
- #include <linux/slab.h>
- 
- 
--static const struct ssb_sprom *fallback_sprom;
-+static int(*get_fallback_sprom)(struct ssb_bus *dev, struct ssb_sprom *out);
- 
- 
- static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len,
-@@ -145,36 +145,43 @@ out:
- }
- 
- /**
-- * ssb_arch_set_fallback_sprom - Set a fallback SPROM for use if no SPROM is found.
-+ * ssb_arch_register_fallback_sprom - Registers a method providing a
-+ * fallback SPROM if no SPROM is found.
-  *
-- * @sprom: The SPROM data structure to register.
-+ * @sprom_callback: The callback function.
-  *
-- * With this function the architecture implementation may register a fallback
-- * SPROM data structure. The fallback is only used for PCI based SSB devices,
-- * where no valid SPROM can be found in the shadow registers.
-+ * With this function the architecture implementation may register a
-+ * callback handler which fills the SPROM data structure. The fallback is
-+ * only used for PCI based SSB devices, where no valid SPROM can be found
-+ * in the shadow registers.
-+ *
-+ * This function is useful for weird architectures that have a half-assed
-+ * SSB device hardwired to their PCI bus.
-+ *
-+ * Note that it does only work with PCI attached SSB devices. PCMCIA
-+ * devices currently don't use this fallback.
-+ * Architectures must provide the SPROM for native SSB devices anyway, so
-+ * the fallback also isn't used for native devices.
-  *
-- * This function is useful for weird architectures that have a half-assed SSB device
-- * hardwired to their PCI bus.
-- *
-- * Note that it does only work with PCI attached SSB devices. PCMCIA devices currently
-- * don't use this fallback.
-- * Architectures must provide the SPROM for native SSB devices anyway,
-- * so the fallback also isn't used for native devices.
-- *
-- * This function is available for architecture code, only. So it is not exported.
-+ * This function is available for architecture code, only. So it is not
-+ * exported.
-  */
--int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom)
-+int ssb_arch_register_fallback_sprom(int (*sprom_callback)(struct ssb_bus *bus,
-+				     struct ssb_sprom *out))
- {
--	if (fallback_sprom)
-+	if (get_fallback_sprom)
- 		return -EEXIST;
--	fallback_sprom = sprom;
-+	get_fallback_sprom = sprom_callback;
- 
- 	return 0;
- }
- 
--const struct ssb_sprom *ssb_get_fallback_sprom(void)
-+int ssb_fill_sprom_with_fallback(struct ssb_bus *bus, struct ssb_sprom *out)
- {
--	return fallback_sprom;
-+	if (!get_fallback_sprom)
-+		return -ENOENT;
-+
-+	return get_fallback_sprom(bus, out);
- }
- 
- /* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
-@@ -185,7 +192,7 @@ bool ssb_is_sprom_available(struct ssb_b
- 	/* this routine differs from specs as we do not access SPROM directly
- 	   on PCMCIA */
- 	if (bus->bustype == SSB_BUSTYPE_PCI &&
--	    bus->chipco.dev &&	/* can be unavailible! */
-+	    bus->chipco.dev &&	/* can be unavailable! */
- 	    bus->chipco.dev->id.revision >= 31)
- 		return bus->chipco.capabilities & SSB_CHIPCO_CAP_SPROM;
- 
---- a/drivers/ssb/ssb_private.h
-+++ b/drivers/ssb/ssb_private.h
-@@ -171,7 +171,8 @@ ssize_t ssb_attr_sprom_store(struct ssb_
- 			     const char *buf, size_t count,
- 			     int (*sprom_check_crc)(const u16 *sprom, size_t size),
- 			     int (*sprom_write)(struct ssb_bus *bus, const u16 *sprom));
--extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
-+extern int ssb_fill_sprom_with_fallback(struct ssb_bus *bus,
-+					struct ssb_sprom *out);
- 
- 
- /* core.c */
-@@ -206,4 +207,8 @@ static inline void b43_pci_ssb_bridge_ex
- }
- #endif /* CONFIG_SSB_B43_PCI_BRIDGE */
- 
-+/* driver_chipcommon_pmu.c */
-+extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc);
-+extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc);
-+
- #endif /* LINUX_SSB_PRIVATE_H_ */
---- a/include/linux/ssb/ssb.h
-+++ b/include/linux/ssb/ssb.h
-@@ -16,6 +16,12 @@ struct pcmcia_device;
- struct ssb_bus;
- struct ssb_driver;
- 
-+struct ssb_sprom_core_pwr_info {
-+	u8 itssi_2g, itssi_5g;
-+	u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh;
-+	u16 pa_2g[4], pa_5gl[4], pa_5g[4], pa_5gh[4];
-+};
-+
- struct ssb_sprom {
- 	u8 revision;
- 	u8 il0mac[6];		/* MAC address for 802.11b/g */
-@@ -25,8 +31,13 @@ struct ssb_sprom {
- 	u8 et1phyaddr;		/* MII address for enet1 */
- 	u8 et0mdcport;		/* MDIO for enet0 */
- 	u8 et1mdcport;		/* MDIO for enet1 */
--	u8 board_rev;		/* Board revision number from SPROM. */
-+	u16 board_rev;		/* Board revision number from SPROM. */
-+	u16 board_num;		/* Board number from SPROM. */
-+	u16 board_type;		/* Board type from SPROM. */
- 	u8 country_code;	/* Country Code */
-+	char alpha2[2];		/* Country Code as two chars like EU or US */
-+	u8 leddc_on_time;	/* LED Powersave Duty Cycle On Count */
-+	u8 leddc_off_time;	/* LED Powersave Duty Cycle Off Count */
- 	u8 ant_available_a;	/* 2GHz antenna available bits (up to 4) */
- 	u8 ant_available_bg;	/* 5GHz antenna available bits (up to 4) */
- 	u16 pa0b0;
-@@ -45,10 +56,10 @@ struct ssb_sprom {
- 	u8 gpio1;		/* GPIO pin 1 */
- 	u8 gpio2;		/* GPIO pin 2 */
- 	u8 gpio3;		/* GPIO pin 3 */
--	u16 maxpwr_bg;		/* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
--	u16 maxpwr_al;		/* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
--	u16 maxpwr_a;		/* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
--	u16 maxpwr_ah;		/* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
-+	u8 maxpwr_bg;		/* 2.4GHz Amplifier Max Power (in dBm Q5.2) */
-+	u8 maxpwr_al;		/* 5.2GHz Amplifier Max Power (in dBm Q5.2) */
-+	u8 maxpwr_a;		/* 5.3GHz Amplifier Max Power (in dBm Q5.2) */
-+	u8 maxpwr_ah;		/* 5.8GHz Amplifier Max Power (in dBm Q5.2) */
- 	u8 itssi_a;		/* Idle TSSI Target for A-PHY */
- 	u8 itssi_bg;		/* Idle TSSI Target for B/G-PHY */
- 	u8 tri2g;		/* 2.4GHz TX isolation */
-@@ -59,8 +70,8 @@ struct ssb_sprom {
- 	u8 txpid5gl[4];		/* 4.9 - 5.1GHz TX power index */
- 	u8 txpid5g[4];		/* 5.1 - 5.5GHz TX power index */
- 	u8 txpid5gh[4];		/* 5.5 - ...GHz TX power index */
--	u8 rxpo2g;		/* 2GHz RX power offset */
--	u8 rxpo5g;		/* 5GHz RX power offset */
-+	s8 rxpo2g;		/* 2GHz RX power offset */
-+	s8 rxpo5g;		/* 5GHz RX power offset */
- 	u8 rssisav2g;		/* 2GHz RSSI params */
- 	u8 rssismc2g;
- 	u8 rssismf2g;
-@@ -80,26 +91,104 @@ struct ssb_sprom {
- 	u16 boardflags2_hi;	/* Board flags (bits 48-63) */
- 	/* TODO store board flags in a single u64 */
- 
-+	struct ssb_sprom_core_pwr_info core_pwr_info[4];
-+
- 	/* Antenna gain values for up to 4 antennas
- 	 * on each band. Values in dBm/4 (Q5.2). Negative gain means the
- 	 * loss in the connectors is bigger than the gain. */
- 	struct {
--		struct {
--			s8 a0, a1, a2, a3;
--		} ghz24;	/* 2.4GHz band */
--		struct {
--			s8 a0, a1, a2, a3;
--		} ghz5;		/* 5GHz band */
-+		s8 a0, a1, a2, a3;
- 	} antenna_gain;
- 
--	/* TODO - add any parameters needed from rev 2, 3, 4, 5 or 8 SPROMs */
-+	struct {
-+		struct {
-+			u8 tssipos, extpa_gain, pdet_range, tr_iso, antswlut;
-+		} ghz2;
-+		struct {
-+			u8 tssipos, extpa_gain, pdet_range, tr_iso, antswlut;
-+		} ghz5;
-+	} fem;
-+
-+	u16 mcs2gpo[8];
-+	u16 mcs5gpo[8];
-+	u16 mcs5glpo[8];
-+	u16 mcs5ghpo[8];
-+	u8 opo;
-+
-+	u8 rxgainerr2ga[3];
-+	u8 rxgainerr5gla[3];
-+	u8 rxgainerr5gma[3];
-+	u8 rxgainerr5gha[3];
-+	u8 rxgainerr5gua[3];
-+
-+	u8 noiselvl2ga[3];
-+	u8 noiselvl5gla[3];
-+	u8 noiselvl5gma[3];
-+	u8 noiselvl5gha[3];
-+	u8 noiselvl5gua[3];
-+
-+	u8 regrev;
-+	u8 txchain;
-+	u8 rxchain;
-+	u8 antswitch;
-+	u16 cddpo;
-+	u16 stbcpo;
-+	u16 bw40po;
-+	u16 bwduppo;
-+
-+	u8 tempthresh;
-+	u8 tempoffset;
-+	u16 rawtempsense;
-+	u8 measpower;
-+	u8 tempsense_slope;
-+	u8 tempcorrx;
-+	u8 tempsense_option;
-+	u8 freqoffset_corr;
-+	u8 iqcal_swp_dis;
-+	u8 hw_iqcal_en;
-+	u8 elna2g;
-+	u8 elna5g;
-+	u8 phycal_tempdelta;
-+	u8 temps_period;
-+	u8 temps_hysteresis;
-+	u8 measpower1;
-+	u8 measpower2;
-+	u8 pcieingress_war;
-+
-+	/* power per rate from sromrev 9 */
-+	u16 cckbw202gpo;
-+	u16 cckbw20ul2gpo;
-+	u32 legofdmbw202gpo;
-+	u32 legofdmbw20ul2gpo;
-+	u32 legofdmbw205glpo;
-+	u32 legofdmbw20ul5glpo;
-+	u32 legofdmbw205gmpo;
-+	u32 legofdmbw20ul5gmpo;
-+	u32 legofdmbw205ghpo;
-+	u32 legofdmbw20ul5ghpo;
-+	u32 mcsbw202gpo;
-+	u32 mcsbw20ul2gpo;
-+	u32 mcsbw402gpo;
-+	u32 mcsbw205glpo;
-+	u32 mcsbw20ul5glpo;
-+	u32 mcsbw405glpo;
-+	u32 mcsbw205gmpo;
-+	u32 mcsbw20ul5gmpo;
-+	u32 mcsbw405gmpo;
-+	u32 mcsbw205ghpo;
-+	u32 mcsbw20ul5ghpo;
-+	u32 mcsbw405ghpo;
-+	u16 mcs32po;
-+	u16 legofdm40duppo;
-+	u8 sar2g;
-+	u8 sar5g;
- };
- 
- /* Information about the PCB the circuitry is soldered on. */
- struct ssb_boardinfo {
- 	u16 vendor;
- 	u16 type;
--	u16 rev;
-+	u8  rev;
- };
- 
- 
-@@ -229,10 +318,9 @@ struct ssb_driver {
- #define drv_to_ssb_drv(_drv) container_of(_drv, struct ssb_driver, drv)
- 
- extern int __ssb_driver_register(struct ssb_driver *drv, struct module *owner);
--static inline int ssb_driver_register(struct ssb_driver *drv)
--{
--	return __ssb_driver_register(drv, THIS_MODULE);
--}
-+#define ssb_driver_register(drv) \
-+	__ssb_driver_register(drv, THIS_MODULE)
-+
- extern void ssb_driver_unregister(struct ssb_driver *drv);
- 
- 
-@@ -308,7 +396,7 @@ struct ssb_bus {
- 
- 	/* ID information about the Chip. */
- 	u16 chip_id;
--	u16 chip_rev;
-+	u8 chip_rev;
- 	u16 sprom_offset;
- 	u16 sprom_size;		/* number of words in sprom */
- 	u8 chip_package;
-@@ -404,7 +492,9 @@ extern bool ssb_is_sprom_available(struc
- 
- /* Set a fallback SPROM.
-  * See kdoc at the function definition for complete documentation. */
--extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
-+extern int ssb_arch_register_fallback_sprom(
-+		int (*sprom_callback)(struct ssb_bus *bus,
-+		struct ssb_sprom *out));
- 
- /* Suspend a SSB bus.
-  * Call this from the parent bus suspend routine. */
-@@ -518,6 +608,7 @@ extern int ssb_bus_may_powerdown(struct
-  * Otherwise static always-on powercontrol will be used. */
- extern int ssb_bus_powerup(struct ssb_bus *bus, bool dynamic_pctl);
- 
-+extern void ssb_commit_settings(struct ssb_bus *bus);
- 
- /* Various helper functions */
- extern u32 ssb_admatch_base(u32 adm);
---- a/include/linux/ssb/ssb_driver_chipcommon.h
-+++ b/include/linux/ssb/ssb_driver_chipcommon.h
-@@ -8,7 +8,7 @@
-  * gpio interface, extbus, and support for serial and parallel flashes.
-  *
-  * Copyright 2005, Broadcom Corporation
-- * Copyright 2006, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2006, Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GPL version 2. See COPYING for details.
-  */
-@@ -123,6 +123,8 @@
- #define SSB_CHIPCO_FLASHDATA		0x0048
- #define SSB_CHIPCO_BCAST_ADDR		0x0050
- #define SSB_CHIPCO_BCAST_DATA		0x0054
-+#define SSB_CHIPCO_GPIOPULLUP		0x0058		/* Rev >= 20 only */
-+#define SSB_CHIPCO_GPIOPULLDOWN		0x005C		/* Rev >= 20 only */
- #define SSB_CHIPCO_GPIOIN		0x0060
- #define SSB_CHIPCO_GPIOOUT		0x0064
- #define SSB_CHIPCO_GPIOOUTEN		0x0068
-@@ -131,6 +133,9 @@
- #define SSB_CHIPCO_GPIOIRQ		0x0074
- #define SSB_CHIPCO_WATCHDOG		0x0080
- #define SSB_CHIPCO_GPIOTIMER		0x0088		/* LED powersave (corerev >= 16) */
-+#define  SSB_CHIPCO_GPIOTIMER_OFFTIME	0x0000FFFF
-+#define  SSB_CHIPCO_GPIOTIMER_OFFTIME_SHIFT	0
-+#define  SSB_CHIPCO_GPIOTIMER_ONTIME	0xFFFF0000
- #define  SSB_CHIPCO_GPIOTIMER_ONTIME_SHIFT	16
- #define SSB_CHIPCO_GPIOTOUTM		0x008C		/* LED powersave (corerev >= 16) */
- #define SSB_CHIPCO_CLOCK_N		0x0090
-@@ -189,8 +194,10 @@
- #define  SSB_CHIPCO_CLKCTLST_HAVEALPREQ	0x00000008 /* ALP available request */
- #define  SSB_CHIPCO_CLKCTLST_HAVEHTREQ	0x00000010 /* HT available request */
- #define  SSB_CHIPCO_CLKCTLST_HWCROFF	0x00000020 /* Force HW clock request off */
--#define  SSB_CHIPCO_CLKCTLST_HAVEHT	0x00010000 /* HT available */
--#define  SSB_CHIPCO_CLKCTLST_HAVEALP	0x00020000 /* APL available */
-+#define  SSB_CHIPCO_CLKCTLST_HAVEALP	0x00010000 /* ALP available */
-+#define  SSB_CHIPCO_CLKCTLST_HAVEHT	0x00020000 /* HT available */
-+#define  SSB_CHIPCO_CLKCTLST_4328A0_HAVEHT	0x00010000 /* 4328a0 has reversed bits */
-+#define  SSB_CHIPCO_CLKCTLST_4328A0_HAVEALP	0x00020000 /* 4328a0 has reversed bits */
- #define SSB_CHIPCO_HW_WORKAROUND	0x01E4 /* Hardware workaround (rev >= 20) */
- #define SSB_CHIPCO_UART0_DATA		0x0300
- #define SSB_CHIPCO_UART0_IMR		0x0304
---- a/drivers/ssb/b43_pci_bridge.c
-+++ b/drivers/ssb/b43_pci_bridge.c
-@@ -5,12 +5,13 @@
-  * because of its small size we include it in the SSB core
-  * instead of creating a standalone module.
-  *
-- * Copyright 2007  Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2007  Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
- 
- #include <linux/pci.h>
-+#include <linux/module.h>
- #include <linux/ssb/ssb.h>
- 
- #include "ssb_private.h"
---- a/drivers/ssb/driver_extif.c
-+++ b/drivers/ssb/driver_extif.c
-@@ -3,7 +3,7 @@
-  * Broadcom EXTIF core driver
-  *
-  * Copyright 2005, Broadcom Corporation
-- * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
-  * Copyright 2006, 2007, Felix Fietkau <nbd@openwrt.org>
-  * Copyright 2007, Aurelien Jarno <aurelien@aurel32.net>
-  *
---- a/drivers/ssb/driver_mipscore.c
-+++ b/drivers/ssb/driver_mipscore.c
-@@ -3,7 +3,7 @@
-  * Broadcom MIPS core driver
-  *
-  * Copyright 2005, Broadcom Corporation
-- * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
-@@ -208,6 +208,9 @@ u32 ssb_cpu_clock(struct ssb_mipscore *m
- 	struct ssb_bus *bus = mcore->dev->bus;
- 	u32 pll_type, n, m, rate = 0;
- 
-+	if (bus->chipco.capabilities & SSB_CHIPCO_CAP_PMU)
-+		return ssb_pmu_get_cpu_clock(&bus->chipco);
-+
- 	if (bus->extif.dev) {
- 		ssb_extif_get_clockcontrol(&bus->extif, &pll_type, &n, &m);
- 	} else if (bus->chipco.dev) {
---- a/drivers/ssb/embedded.c
-+++ b/drivers/ssb/embedded.c
-@@ -3,7 +3,7 @@
-  * Embedded systems support code
-  *
-  * Copyright 2005-2008, Broadcom Corporation
-- * Copyright 2006-2008, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2006-2008, Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
---- a/drivers/ssb/pcmcia.c
-+++ b/drivers/ssb/pcmcia.c
-@@ -3,7 +3,7 @@
-  * PCMCIA-Hostbus related functions
-  *
-  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
-- * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2007-2008 Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  */
-@@ -676,14 +676,10 @@ static int ssb_pcmcia_do_get_invariants(
- 	case SSB_PCMCIA_CIS_ANTGAIN:
- 		GOTO_ERROR_ON(tuple->TupleDataLen != 2,
- 			"antg tpl size");
--		sprom->antenna_gain.ghz24.a0 = tuple->TupleData[1];
--		sprom->antenna_gain.ghz24.a1 = tuple->TupleData[1];
--		sprom->antenna_gain.ghz24.a2 = tuple->TupleData[1];
--		sprom->antenna_gain.ghz24.a3 = tuple->TupleData[1];
--		sprom->antenna_gain.ghz5.a0 = tuple->TupleData[1];
--		sprom->antenna_gain.ghz5.a1 = tuple->TupleData[1];
--		sprom->antenna_gain.ghz5.a2 = tuple->TupleData[1];
--		sprom->antenna_gain.ghz5.a3 = tuple->TupleData[1];
-+		sprom->antenna_gain.a0 = tuple->TupleData[1];
-+		sprom->antenna_gain.a1 = tuple->TupleData[1];
-+		sprom->antenna_gain.a2 = tuple->TupleData[1];
-+		sprom->antenna_gain.a3 = tuple->TupleData[1];
- 		break;
- 	case SSB_PCMCIA_CIS_BFLAGS:
- 		GOTO_ERROR_ON((tuple->TupleDataLen != 3) &&
---- a/drivers/ssb/sdio.c
-+++ b/drivers/ssb/sdio.c
-@@ -6,7 +6,7 @@
-  *
-  * Based on drivers/ssb/pcmcia.c
-  * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
-- * Copyright 2007-2008 Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2007-2008 Michael Buesch <m@bues.ch>
-  *
-  * Licensed under the GNU/GPL. See COPYING for details.
-  *
-@@ -551,14 +551,10 @@ int ssb_sdio_get_invariants(struct ssb_b
- 			case SSB_SDIO_CIS_ANTGAIN:
- 				GOTO_ERROR_ON(tuple->size != 2,
- 					      "antg tpl size");
--				sprom->antenna_gain.ghz24.a0 = tuple->data[1];
--				sprom->antenna_gain.ghz24.a1 = tuple->data[1];
--				sprom->antenna_gain.ghz24.a2 = tuple->data[1];
--				sprom->antenna_gain.ghz24.a3 = tuple->data[1];
--				sprom->antenna_gain.ghz5.a0 = tuple->data[1];
--				sprom->antenna_gain.ghz5.a1 = tuple->data[1];
--				sprom->antenna_gain.ghz5.a2 = tuple->data[1];
--				sprom->antenna_gain.ghz5.a3 = tuple->data[1];
-+				sprom->antenna_gain.a0 = tuple->data[1];
-+				sprom->antenna_gain.a1 = tuple->data[1];
-+				sprom->antenna_gain.a2 = tuple->data[1];
-+				sprom->antenna_gain.a3 = tuple->data[1];
- 				break;
- 			case SSB_SDIO_CIS_BFLAGS:
- 				GOTO_ERROR_ON((tuple->size != 3) &&
---- a/include/linux/ssb/ssb_driver_gige.h
-+++ b/include/linux/ssb/ssb_driver_gige.h
-@@ -2,6 +2,7 @@
- #define LINUX_SSB_DRIVER_GIGE_H_
- 
- #include <linux/ssb/ssb.h>
-+#include <linux/bug.h>
- #include <linux/pci.h>
- #include <linux/spinlock.h>
- 
diff --git a/target/linux/generic/patches-2.6.38/025-bcma_backport.patch b/target/linux/generic/patches-2.6.38/025-bcma_backport.patch
deleted file mode 100644
index db2292ad96..0000000000
--- a/target/linux/generic/patches-2.6.38/025-bcma_backport.patch
+++ /dev/null
@@ -1,4978 +0,0 @@
---- /dev/null
-+++ b/Documentation/ABI/testing/sysfs-bus-bcma
-@@ -0,0 +1,31 @@
-+What:		/sys/bus/bcma/devices/.../manuf
-+Date:		May 2011
-+KernelVersion:	2.6.40
-+Contact:	Rafał Miłecki <zajec5@gmail.com>
-+Description:
-+		Each BCMA core has it's manufacturer id. See
-+		include/linux/bcma/bcma.h for possible values.
-+
-+What:		/sys/bus/bcma/devices/.../id
-+Date:		May 2011
-+KernelVersion:	2.6.40
-+Contact:	Rafał Miłecki <zajec5@gmail.com>
-+Description:
-+		There are a few types of BCMA cores, they can be identified by
-+		id field.
-+
-+What:		/sys/bus/bcma/devices/.../rev
-+Date:		May 2011
-+KernelVersion:	2.6.40
-+Contact:	Rafał Miłecki <zajec5@gmail.com>
-+Description:
-+		BCMA cores of the same type can still slightly differ depending
-+		on their revision. Use it for detailed programming.
-+
-+What:		/sys/bus/bcma/devices/.../class
-+Date:		May 2011
-+KernelVersion:	2.6.40
-+Contact:	Rafał Miłecki <zajec5@gmail.com>
-+Description:
-+		Each BCMA core is identified by few fields, including class it
-+		belongs to. See include/linux/bcma/bcma.h for possible values.
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -5791,6 +5791,13 @@ S:	Maintained
- F:	drivers/ssb/
- F:	include/linux/ssb/
- 
-+BROADCOM SPECIFIC AMBA DRIVER (BCMA)
-+M:	Rafał Miłecki <zajec5@gmail.com>
-+L:	linux-wireless@vger.kernel.org
-+S:	Maintained
-+F:	drivers/bcma/
-+F:	include/linux/bcma/
-+
- SONY VAIO CONTROL DEVICE DRIVER
- M:	Mattia Dongili <malattia@linux.it>
- L:	platform-driver-x86@vger.kernel.org
---- a/drivers/Kconfig
-+++ b/drivers/Kconfig
-@@ -68,6 +68,8 @@ source "drivers/watchdog/Kconfig"
- 
- source "drivers/ssb/Kconfig"
- 
-+source "drivers/bcma/Kconfig"
-+
- source "drivers/mfd/Kconfig"
- 
- source "drivers/regulator/Kconfig"
---- a/drivers/Makefile
-+++ b/drivers/Makefile
-@@ -110,6 +110,7 @@ obj-$(CONFIG_HID)		+= hid/
- obj-$(CONFIG_PPC_PS3)		+= ps3/
- obj-$(CONFIG_OF)		+= of/
- obj-$(CONFIG_SSB)		+= ssb/
-+obj-$(CONFIG_BCMA)		+= bcma/
- obj-$(CONFIG_VHOST_NET)		+= vhost/
- obj-$(CONFIG_VLYNQ)		+= vlynq/
- obj-$(CONFIG_STAGING)		+= staging/
---- /dev/null
-+++ b/drivers/bcma/Kconfig
-@@ -0,0 +1,57 @@
-+config BCMA_POSSIBLE
-+	bool
-+	depends on HAS_IOMEM && HAS_DMA
-+	default y
-+
-+menu "Broadcom specific AMBA"
-+	depends on BCMA_POSSIBLE
-+
-+config BCMA
-+	tristate "BCMA support"
-+	depends on BCMA_POSSIBLE
-+	help
-+	  Bus driver for Broadcom specific Advanced Microcontroller Bus
-+	  Architecture.
-+
-+# Support for Block-I/O. SELECT this from the driver that needs it.
-+config BCMA_BLOCKIO
-+	bool
-+	depends on BCMA
-+
-+config BCMA_HOST_PCI_POSSIBLE
-+	bool
-+	depends on BCMA && PCI = y
-+	default y
-+
-+config BCMA_HOST_PCI
-+	bool "Support for BCMA on PCI-host bus"
-+	depends on BCMA_HOST_PCI_POSSIBLE
-+
-+config BCMA_DRIVER_PCI_HOSTMODE
-+	bool "Driver for PCI core working in hostmode"
-+	depends on BCMA && MIPS && BCMA_HOST_PCI
-+	help
-+	  PCI core hostmode operation (external PCI bus).
-+
-+config BCMA_HOST_SOC
-+	bool
-+	depends on BCMA_DRIVER_MIPS
-+
-+config BCMA_DRIVER_MIPS
-+	bool "BCMA Broadcom MIPS core driver"
-+	depends on BCMA && MIPS
-+	help
-+	  Driver for the Broadcom MIPS core attached to Broadcom specific
-+	  Advanced Microcontroller Bus.
-+
-+	  If unsure, say N
-+
-+config BCMA_DEBUG
-+	bool "BCMA debugging"
-+	depends on BCMA
-+	help
-+	  This turns on additional debugging messages.
-+
-+	  If unsure, say N
-+
-+endmenu
---- /dev/null
-+++ b/drivers/bcma/Makefile
-@@ -0,0 +1,10 @@
-+bcma-y					+= main.o scan.o core.o sprom.o
-+bcma-y					+= driver_chipcommon.o driver_chipcommon_pmu.o
-+bcma-y					+= driver_pci.o
-+bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)	+= driver_pci_host.o
-+bcma-$(CONFIG_BCMA_DRIVER_MIPS)		+= driver_mips.o
-+bcma-$(CONFIG_BCMA_HOST_PCI)		+= host_pci.o
-+bcma-$(CONFIG_BCMA_HOST_SOC)		+= host_soc.o
-+obj-$(CONFIG_BCMA)			+= bcma.o
-+
-+ccflags-$(CONFIG_BCMA_DEBUG)		:= -DDEBUG
---- /dev/null
-+++ b/drivers/bcma/README
-@@ -0,0 +1,19 @@
-+Broadcom introduced new bus as replacement for older SSB. It is based on AMBA,
-+however from programming point of view there is nothing AMBA specific we use.
-+
-+Standard AMBA drivers are platform specific, have hardcoded addresses and use
-+AMBA standard fields like CID and PID.
-+
-+In case of Broadcom's cards every device consists of:
-+1) Broadcom specific AMBA device. It is put on AMBA bus, but can not be treated
-+   as standard AMBA device. Reading it's CID or PID can cause machine lockup.
-+2) AMBA standard devices called ports or wrappers. They have CIDs (AMBA_CID)
-+   and PIDs (0x103BB369), but we do not use that info for anything. One of that
-+   devices is used for managing Broadcom specific core.
-+
-+Addresses of AMBA devices are not hardcoded in driver and have to be read from
-+EPROM.
-+
-+In this situation we decided to introduce separated bus. It can contain up to
-+16 devices identified by Broadcom specific fields: manufacturer, id, revision
-+and class.
---- /dev/null
-+++ b/drivers/bcma/TODO
-@@ -0,0 +1,3 @@
-+- Interrupts
-+- Defines for PCI core driver
-+- Create kernel Documentation (use info from README)
---- /dev/null
-+++ b/drivers/bcma/bcma_private.h
-@@ -0,0 +1,59 @@
-+#ifndef LINUX_BCMA_PRIVATE_H_
-+#define LINUX_BCMA_PRIVATE_H_
-+
-+#ifndef pr_fmt
-+#define pr_fmt(fmt)		KBUILD_MODNAME ": " fmt
-+#endif
-+
-+#include <linux/bcma/bcma.h>
-+#include <linux/delay.h>
-+
-+#define BCMA_CORE_SIZE		0x1000
-+
-+struct bcma_bus;
-+
-+/* main.c */
-+int __devinit bcma_bus_register(struct bcma_bus *bus);
-+void bcma_bus_unregister(struct bcma_bus *bus);
-+int __init bcma_bus_early_register(struct bcma_bus *bus,
-+				   struct bcma_device *core_cc,
-+				   struct bcma_device *core_mips);
-+#ifdef CONFIG_PM
-+int bcma_bus_suspend(struct bcma_bus *bus);
-+int bcma_bus_resume(struct bcma_bus *bus);
-+#endif
-+
-+/* scan.c */
-+int bcma_bus_scan(struct bcma_bus *bus);
-+int __init bcma_bus_scan_early(struct bcma_bus *bus,
-+			       struct bcma_device_id *match,
-+			       struct bcma_device *core);
-+void bcma_init_bus(struct bcma_bus *bus);
-+
-+/* sprom.c */
-+int bcma_sprom_get(struct bcma_bus *bus);
-+
-+/* driver_chipcommon.c */
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
-+#endif /* CONFIG_BCMA_DRIVER_MIPS */
-+
-+/* driver_chipcommon_pmu.c */
-+u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
-+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
-+
-+#ifdef CONFIG_BCMA_HOST_PCI
-+/* host_pci.c */
-+extern int __init bcma_host_pci_init(void);
-+extern void __exit bcma_host_pci_exit(void);
-+#endif /* CONFIG_BCMA_HOST_PCI */
-+
-+/* driver_pci.c */
-+u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
-+
-+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
-+bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc);
-+void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc);
-+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
-+
-+#endif
---- /dev/null
-+++ b/drivers/bcma/core.c
-@@ -0,0 +1,126 @@
-+/*
-+ * Broadcom specific AMBA
-+ * Core ops
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include <linux/bcma/bcma.h>
-+
-+bool bcma_core_is_enabled(struct bcma_device *core)
-+{
-+	if ((bcma_aread32(core, BCMA_IOCTL) & (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC))
-+	    != BCMA_IOCTL_CLK)
-+		return false;
-+	if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
-+		return false;
-+	return true;
-+}
-+EXPORT_SYMBOL_GPL(bcma_core_is_enabled);
-+
-+void bcma_core_disable(struct bcma_device *core, u32 flags)
-+{
-+	if (bcma_aread32(core, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET)
-+		return;
-+
-+	bcma_awrite32(core, BCMA_IOCTL, flags);
-+	bcma_aread32(core, BCMA_IOCTL);
-+	udelay(10);
-+
-+	bcma_awrite32(core, BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
-+	udelay(1);
-+}
-+EXPORT_SYMBOL_GPL(bcma_core_disable);
-+
-+int bcma_core_enable(struct bcma_device *core, u32 flags)
-+{
-+	bcma_core_disable(core, flags);
-+
-+	bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags));
-+	bcma_aread32(core, BCMA_IOCTL);
-+
-+	bcma_awrite32(core, BCMA_RESET_CTL, 0);
-+	udelay(1);
-+
-+	bcma_awrite32(core, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags));
-+	bcma_aread32(core, BCMA_IOCTL);
-+	udelay(1);
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL_GPL(bcma_core_enable);
-+
-+void bcma_core_set_clockmode(struct bcma_device *core,
-+			     enum bcma_clkmode clkmode)
-+{
-+	u16 i;
-+
-+	WARN_ON(core->id.id != BCMA_CORE_CHIPCOMMON &&
-+		core->id.id != BCMA_CORE_PCIE &&
-+		core->id.id != BCMA_CORE_80211);
-+
-+	switch (clkmode) {
-+	case BCMA_CLKMODE_FAST:
-+		bcma_set32(core, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT);
-+		udelay(64);
-+		for (i = 0; i < 1500; i++) {
-+			if (bcma_read32(core, BCMA_CLKCTLST) &
-+			    BCMA_CLKCTLST_HAVEHT) {
-+				i = 0;
-+				break;
-+			}
-+			udelay(10);
-+		}
-+		if (i)
-+			pr_err("HT force timeout\n");
-+		break;
-+	case BCMA_CLKMODE_DYNAMIC:
-+		pr_warn("Dynamic clockmode not supported yet!\n");
-+		break;
-+	}
-+}
-+EXPORT_SYMBOL_GPL(bcma_core_set_clockmode);
-+
-+void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on)
-+{
-+	u16 i;
-+
-+	WARN_ON(req & ~BCMA_CLKCTLST_EXTRESREQ);
-+	WARN_ON(status & ~BCMA_CLKCTLST_EXTRESST);
-+
-+	if (on) {
-+		bcma_set32(core, BCMA_CLKCTLST, req);
-+		for (i = 0; i < 10000; i++) {
-+			if ((bcma_read32(core, BCMA_CLKCTLST) & status) ==
-+			    status) {
-+				i = 0;
-+				break;
-+			}
-+			udelay(10);
-+		}
-+		if (i)
-+			pr_err("PLL enable timeout\n");
-+	} else {
-+		pr_warn("Disabling PLL not supported yet!\n");
-+	}
-+}
-+EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
-+
-+u32 bcma_core_dma_translation(struct bcma_device *core)
-+{
-+	switch (core->bus->hosttype) {
-+	case BCMA_HOSTTYPE_SOC:
-+		return 0;
-+	case BCMA_HOSTTYPE_PCI:
-+		if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
-+			return BCMA_DMA_TRANSLATION_DMA64_CMT;
-+		else
-+			return BCMA_DMA_TRANSLATION_DMA32_CMT;
-+	default:
-+		pr_err("DMA translation unknown for host %d\n",
-+		       core->bus->hosttype);
-+	}
-+	return BCMA_DMA_TRANSLATION_NONE;
-+}
-+EXPORT_SYMBOL(bcma_core_dma_translation);
---- /dev/null
-+++ b/drivers/bcma/driver_chipcommon.c
-@@ -0,0 +1,156 @@
-+/*
-+ * Broadcom specific AMBA
-+ * ChipCommon core driver
-+ *
-+ * Copyright 2005, Broadcom Corporation
-+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include <linux/bcma/bcma.h>
-+
-+static inline u32 bcma_cc_write32_masked(struct bcma_drv_cc *cc, u16 offset,
-+					 u32 mask, u32 value)
-+{
-+	value &= mask;
-+	value |= bcma_cc_read32(cc, offset) & ~mask;
-+	bcma_cc_write32(cc, offset, value);
-+
-+	return value;
-+}
-+
-+void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
-+{
-+	u32 leddc_on = 10;
-+	u32 leddc_off = 90;
-+
-+	if (cc->setup_done)
-+		return;
-+
-+	if (cc->core->id.rev >= 11)
-+		cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
-+	cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
-+	if (cc->core->id.rev >= 35)
-+		cc->capabilities_ext = bcma_cc_read32(cc, BCMA_CC_CAP_EXT);
-+
-+	if (cc->core->id.rev >= 20) {
-+		bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
-+		bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
-+	}
-+
-+	if (cc->capabilities & BCMA_CC_CAP_PMU)
-+		bcma_pmu_init(cc);
-+	if (cc->capabilities & BCMA_CC_CAP_PCTL)
-+		pr_err("Power control not implemented!\n");
-+
-+	if (cc->core->id.rev >= 16) {
-+		if (cc->core->bus->sprom.leddc_on_time &&
-+		    cc->core->bus->sprom.leddc_off_time) {
-+			leddc_on = cc->core->bus->sprom.leddc_on_time;
-+			leddc_off = cc->core->bus->sprom.leddc_off_time;
-+		}
-+		bcma_cc_write32(cc, BCMA_CC_GPIOTIMER,
-+			((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
-+			 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
-+	}
-+
-+	cc->setup_done = true;
-+}
-+
-+/* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
-+void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, u32 ticks)
-+{
-+	/* instant NMI */
-+	bcma_cc_write32(cc, BCMA_CC_WATCHDOG, ticks);
-+}
-+
-+void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value)
-+{
-+	bcma_cc_write32_masked(cc, BCMA_CC_IRQMASK, mask, value);
-+}
-+
-+u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask)
-+{
-+	return bcma_cc_read32(cc, BCMA_CC_IRQSTAT) & mask;
-+}
-+
-+u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask)
-+{
-+	return bcma_cc_read32(cc, BCMA_CC_GPIOIN) & mask;
-+}
-+
-+u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value)
-+{
-+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUT, mask, value);
-+}
-+
-+u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value)
-+{
-+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOOUTEN, mask, value);
-+}
-+
-+u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value)
-+{
-+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOCTL, mask, value);
-+}
-+EXPORT_SYMBOL_GPL(bcma_chipco_gpio_control);
-+
-+u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value)
-+{
-+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOIRQ, mask, value);
-+}
-+
-+u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
-+{
-+	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
-+}
-+
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
-+{
-+	unsigned int irq;
-+	u32 baud_base;
-+	u32 i;
-+	unsigned int ccrev = cc->core->id.rev;
-+	struct bcma_serial_port *ports = cc->serial_ports;
-+
-+	if (ccrev >= 11 && ccrev != 15) {
-+		/* Fixed ALP clock */
-+		baud_base = bcma_pmu_alp_clock(cc);
-+		if (ccrev >= 21) {
-+			/* Turn off UART clock before switching clocksource. */
-+			bcma_cc_write32(cc, BCMA_CC_CORECTL,
-+				       bcma_cc_read32(cc, BCMA_CC_CORECTL)
-+				       & ~BCMA_CC_CORECTL_UARTCLKEN);
-+		}
-+		/* Set the override bit so we don't divide it */
-+		bcma_cc_write32(cc, BCMA_CC_CORECTL,
-+			       bcma_cc_read32(cc, BCMA_CC_CORECTL)
-+			       | BCMA_CC_CORECTL_UARTCLK0);
-+		if (ccrev >= 21) {
-+			/* Re-enable the UART clock. */
-+			bcma_cc_write32(cc, BCMA_CC_CORECTL,
-+				       bcma_cc_read32(cc, BCMA_CC_CORECTL)
-+				       | BCMA_CC_CORECTL_UARTCLKEN);
-+		}
-+	} else {
-+		pr_err("serial not supported on this device ccrev: 0x%x\n",
-+		       ccrev);
-+		return;
-+	}
-+
-+	irq = bcma_core_mips_irq(cc->core);
-+
-+	/* Determine the registers of the UARTs */
-+	cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
-+	for (i = 0; i < cc->nr_serial_ports; i++) {
-+		ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
-+				(i * 256);
-+		ports[i].irq = irq;
-+		ports[i].baud_base = baud_base;
-+		ports[i].reg_shift = 0;
-+	}
-+}
-+#endif /* CONFIG_BCMA_DRIVER_MIPS */
---- /dev/null
-+++ b/drivers/bcma/driver_chipcommon_pmu.c
-@@ -0,0 +1,310 @@
-+/*
-+ * Broadcom specific AMBA
-+ * ChipCommon Power Management Unit driver
-+ *
-+ * Copyright 2009, Michael Buesch <m@bues.ch>
-+ * Copyright 2007, Broadcom Corporation
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include <linux/bcma/bcma.h>
-+
-+static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
-+{
-+	bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
-+	bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
-+	return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
-+}
-+
-+void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
-+{
-+	bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
-+	bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
-+	bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
-+}
-+EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
-+
-+void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
-+			     u32 set)
-+{
-+	bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
-+	bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
-+	bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
-+}
-+EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
-+
-+void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
-+				 u32 offset, u32 mask, u32 set)
-+{
-+	bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
-+	bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
-+	bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
-+}
-+EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
-+
-+void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
-+				u32 set)
-+{
-+	bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
-+	bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
-+	bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
-+}
-+EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
-+
-+static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
-+{
-+	struct bcma_bus *bus = cc->core->bus;
-+
-+	switch (bus->chipinfo.id) {
-+	case 0x4313:
-+	case 0x4331:
-+	case 43224:
-+	case 43225:
-+		break;
-+	default:
-+		pr_err("PLL init unknown for device 0x%04X\n",
-+			bus->chipinfo.id);
-+	}
-+}
-+
-+static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
-+{
-+	struct bcma_bus *bus = cc->core->bus;
-+	u32 min_msk = 0, max_msk = 0;
-+
-+	switch (bus->chipinfo.id) {
-+	case 0x4313:
-+		min_msk = 0x200D;
-+		max_msk = 0xFFFF;
-+		break;
-+	case 0x4331:
-+	case 43224:
-+	case 43225:
-+		break;
-+	default:
-+		pr_err("PMU resource config unknown for device 0x%04X\n",
-+			bus->chipinfo.id);
-+	}
-+
-+	/* Set the resource masks. */
-+	if (min_msk)
-+		bcma_cc_write32(cc, BCMA_CC_PMU_MINRES_MSK, min_msk);
-+	if (max_msk)
-+		bcma_cc_write32(cc, BCMA_CC_PMU_MAXRES_MSK, max_msk);
-+}
-+
-+void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
-+{
-+	struct bcma_bus *bus = cc->core->bus;
-+
-+	switch (bus->chipinfo.id) {
-+	case 0x4313:
-+	case 0x4331:
-+	case 43224:
-+	case 43225:
-+		break;
-+	default:
-+		pr_err("PMU switch/regulators init unknown for device "
-+			"0x%04X\n", bus->chipinfo.id);
-+	}
-+}
-+
-+/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
-+void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
-+{
-+	struct bcma_bus *bus = cc->core->bus;
-+	u32 val;
-+
-+	val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
-+	if (enable) {
-+		val |= BCMA_CHIPCTL_4331_EXTPA_EN;
-+		if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
-+			val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
-+	} else {
-+		val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
-+		val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
-+	}
-+	bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
-+}
-+
-+void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
-+{
-+	struct bcma_bus *bus = cc->core->bus;
-+
-+	switch (bus->chipinfo.id) {
-+	case 0x4313:
-+		bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
-+		break;
-+	case 0x4331:
-+		/* BCM4331 workaround is SPROM-related, we put it in sprom.c */
-+		break;
-+	case 43224:
-+		if (bus->chipinfo.rev == 0) {
-+			pr_err("Workarounds for 43224 rev 0 not fully "
-+				"implemented\n");
-+			bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x00F000F0);
-+		} else {
-+			bcma_chipco_chipctl_maskset(cc, 0, ~0, 0xF0);
-+		}
-+		break;
-+	case 43225:
-+		break;
-+	default:
-+		pr_err("Workarounds unknown for device 0x%04X\n",
-+			bus->chipinfo.id);
-+	}
-+}
-+
-+void bcma_pmu_init(struct bcma_drv_cc *cc)
-+{
-+	u32 pmucap;
-+
-+	pmucap = bcma_cc_read32(cc, BCMA_CC_PMU_CAP);
-+	cc->pmu.rev = (pmucap & BCMA_CC_PMU_CAP_REVISION);
-+
-+	pr_debug("Found rev %u PMU (capabilities 0x%08X)\n", cc->pmu.rev,
-+		 pmucap);
-+
-+	if (cc->pmu.rev == 1)
-+		bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
-+			      ~BCMA_CC_PMU_CTL_NOILPONW);
-+	else
-+		bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
-+			     BCMA_CC_PMU_CTL_NOILPONW);
-+
-+	if (cc->core->id.id == 0x4329 && cc->core->id.rev == 2)
-+		pr_err("Fix for 4329b0 bad LPOM state not implemented!\n");
-+
-+	bcma_pmu_pll_init(cc);
-+	bcma_pmu_resources_init(cc);
-+	bcma_pmu_swreg_init(cc);
-+	bcma_pmu_workarounds(cc);
-+}
-+
-+u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
-+{
-+	struct bcma_bus *bus = cc->core->bus;
-+
-+	switch (bus->chipinfo.id) {
-+	case 0x4716:
-+	case 0x4748:
-+	case 47162:
-+	case 0x4313:
-+	case 0x5357:
-+	case 0x4749:
-+	case 53572:
-+		/* always 20Mhz */
-+		return 20000 * 1000;
-+	case 0x5356:
-+	case 0x5300:
-+		/* always 25Mhz */
-+		return 25000 * 1000;
-+	default:
-+		pr_warn("No ALP clock specified for %04X device, "
-+			"pmu rev. %d, using default %d Hz\n",
-+			bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
-+	}
-+	return BCMA_CC_PMU_ALP_CLOCK;
-+}
-+
-+/* Find the output of the "m" pll divider given pll controls that start with
-+ * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
-+ */
-+static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
-+{
-+	u32 tmp, div, ndiv, p1, p2, fc;
-+	struct bcma_bus *bus = cc->core->bus;
-+
-+	BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
-+
-+	BUG_ON(!m || m > 4);
-+
-+	if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
-+		/* Detect failure in clock setting */
-+		tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
-+		if (tmp & 0x40000)
-+			return 133 * 1000000;
-+	}
-+
-+	tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
-+	p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
-+	p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
-+
-+	tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
-+	div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
-+		BCMA_CC_PPL_MDIV_MASK;
-+
-+	tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
-+	ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
-+
-+	/* Do calculation in Mhz */
-+	fc = bcma_pmu_alp_clock(cc) / 1000000;
-+	fc = (p1 * ndiv * fc) / p2;
-+
-+	/* Return clock in Hertz */
-+	return (fc / div) * 1000000;
-+}
-+
-+/* query bus clock frequency for PMU-enabled chipcommon */
-+u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
-+{
-+	struct bcma_bus *bus = cc->core->bus;
-+
-+	switch (bus->chipinfo.id) {
-+	case 0x4716:
-+	case 0x4748:
-+	case 47162:
-+		return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
-+				      BCMA_CC_PMU5_MAINPLL_SSB);
-+	case 0x5356:
-+		return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
-+				      BCMA_CC_PMU5_MAINPLL_SSB);
-+	case 0x5357:
-+	case 0x4749:
-+		return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
-+				      BCMA_CC_PMU5_MAINPLL_SSB);
-+	case 0x5300:
-+		return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
-+				      BCMA_CC_PMU5_MAINPLL_SSB);
-+	case 53572:
-+		return 75000000;
-+	default:
-+		pr_warn("No backplane clock specified for %04X device, "
-+			"pmu rev. %d, using default %d Hz\n",
-+			bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
-+	}
-+	return BCMA_CC_PMU_HT_CLOCK;
-+}
-+
-+/* query cpu clock frequency for PMU-enabled chipcommon */
-+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
-+{
-+	struct bcma_bus *bus = cc->core->bus;
-+
-+	if (bus->chipinfo.id == 53572)
-+		return 300000000;
-+
-+	if (cc->pmu.rev >= 5) {
-+		u32 pll;
-+		switch (bus->chipinfo.id) {
-+		case 0x5356:
-+			pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
-+			break;
-+		case 0x5357:
-+		case 0x4749:
-+			pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
-+			break;
-+		default:
-+			pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
-+			break;
-+		}
-+
-+		/* TODO: if (bus->chipinfo.id == 0x5300)
-+		  return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
-+		return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
-+	}
-+
-+	return bcma_pmu_get_clockcontrol(cc);
-+}
---- /dev/null
-+++ b/drivers/bcma/driver_pci.c
-@@ -0,0 +1,225 @@
-+/*
-+ * Broadcom specific AMBA
-+ * PCI Core
-+ *
-+ * Copyright 2005, 2011, Broadcom Corporation
-+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
-+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include <linux/bcma/bcma.h>
-+
-+/**************************************************
-+ * R/W ops.
-+ **************************************************/
-+
-+u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address)
-+{
-+	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
-+	pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
-+	return pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_DATA);
-+}
-+
-+#if 0
-+static void bcma_pcie_write(struct bcma_drv_pci *pc, u32 address, u32 data)
-+{
-+	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_ADDR, address);
-+	pcicore_read32(pc, BCMA_CORE_PCI_PCIEIND_ADDR);
-+	pcicore_write32(pc, BCMA_CORE_PCI_PCIEIND_DATA, data);
-+}
-+#endif
-+
-+static void bcma_pcie_mdio_set_phy(struct bcma_drv_pci *pc, u8 phy)
-+{
-+	u32 v;
-+	int i;
-+
-+	v = BCMA_CORE_PCI_MDIODATA_START;
-+	v |= BCMA_CORE_PCI_MDIODATA_WRITE;
-+	v |= (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
-+	      BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
-+	v |= (BCMA_CORE_PCI_MDIODATA_BLK_ADDR <<
-+	      BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
-+	v |= BCMA_CORE_PCI_MDIODATA_TA;
-+	v |= (phy << 4);
-+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
-+
-+	udelay(10);
-+	for (i = 0; i < 200; i++) {
-+		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
-+		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
-+			break;
-+		msleep(1);
-+	}
-+}
-+
-+static u16 bcma_pcie_mdio_read(struct bcma_drv_pci *pc, u8 device, u8 address)
-+{
-+	int max_retries = 10;
-+	u16 ret = 0;
-+	u32 v;
-+	int i;
-+
-+	/* enable mdio access to SERDES */
-+	v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
-+	v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
-+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
-+
-+	if (pc->core->id.rev >= 10) {
-+		max_retries = 200;
-+		bcma_pcie_mdio_set_phy(pc, device);
-+		v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
-+		     BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
-+		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
-+	} else {
-+		v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
-+		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
-+	}
-+
-+	v = BCMA_CORE_PCI_MDIODATA_START;
-+	v |= BCMA_CORE_PCI_MDIODATA_READ;
-+	v |= BCMA_CORE_PCI_MDIODATA_TA;
-+
-+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
-+	/* Wait for the device to complete the transaction */
-+	udelay(10);
-+	for (i = 0; i < max_retries; i++) {
-+		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
-+		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE) {
-+			udelay(10);
-+			ret = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_DATA);
-+			break;
-+		}
-+		msleep(1);
-+	}
-+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
-+	return ret;
-+}
-+
-+static void bcma_pcie_mdio_write(struct bcma_drv_pci *pc, u8 device,
-+				u8 address, u16 data)
-+{
-+	int max_retries = 10;
-+	u32 v;
-+	int i;
-+
-+	/* enable mdio access to SERDES */
-+	v = BCMA_CORE_PCI_MDIOCTL_PREAM_EN;
-+	v |= BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL;
-+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, v);
-+
-+	if (pc->core->id.rev >= 10) {
-+		max_retries = 200;
-+		bcma_pcie_mdio_set_phy(pc, device);
-+		v = (BCMA_CORE_PCI_MDIODATA_DEV_ADDR <<
-+		     BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF);
-+		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF);
-+	} else {
-+		v = (device << BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD);
-+		v |= (address << BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD);
-+	}
-+
-+	v = BCMA_CORE_PCI_MDIODATA_START;
-+	v |= BCMA_CORE_PCI_MDIODATA_WRITE;
-+	v |= BCMA_CORE_PCI_MDIODATA_TA;
-+	v |= data;
-+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_DATA, v);
-+	/* Wait for the device to complete the transaction */
-+	udelay(10);
-+	for (i = 0; i < max_retries; i++) {
-+		v = pcicore_read32(pc, BCMA_CORE_PCI_MDIO_CONTROL);
-+		if (v & BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE)
-+			break;
-+		msleep(1);
-+	}
-+	pcicore_write32(pc, BCMA_CORE_PCI_MDIO_CONTROL, 0);
-+}
-+
-+/**************************************************
-+ * Workarounds.
-+ **************************************************/
-+
-+static u8 bcma_pcicore_polarity_workaround(struct bcma_drv_pci *pc)
-+{
-+	u32 tmp;
-+
-+	tmp = bcma_pcie_read(pc, BCMA_CORE_PCI_PLP_STATUSREG);
-+	if (tmp & BCMA_CORE_PCI_PLP_POLARITYINV_STAT)
-+		return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE |
-+		       BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY;
-+	else
-+		return BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE;
-+}
-+
-+static void bcma_pcicore_serdes_workaround(struct bcma_drv_pci *pc)
-+{
-+	u16 tmp;
-+
-+	bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_RX,
-+	                     BCMA_CORE_PCI_SERDES_RX_CTRL,
-+			     bcma_pcicore_polarity_workaround(pc));
-+	tmp = bcma_pcie_mdio_read(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
-+	                          BCMA_CORE_PCI_SERDES_PLL_CTRL);
-+	if (tmp & BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN)
-+		bcma_pcie_mdio_write(pc, BCMA_CORE_PCI_MDIODATA_DEV_PLL,
-+		                     BCMA_CORE_PCI_SERDES_PLL_CTRL,
-+		                     tmp & ~BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN);
-+}
-+
-+/**************************************************
-+ * Init.
-+ **************************************************/
-+
-+static void __devinit bcma_core_pci_clientmode_init(struct bcma_drv_pci *pc)
-+{
-+	bcma_pcicore_serdes_workaround(pc);
-+}
-+
-+void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc)
-+{
-+	if (pc->setup_done)
-+		return;
-+
-+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
-+	pc->hostmode = bcma_core_pci_is_in_hostmode(pc);
-+	if (pc->hostmode)
-+		bcma_core_pci_hostmode_init(pc);
-+#endif /* CONFIG_BCMA_DRIVER_PCI_HOSTMODE */
-+
-+	if (!pc->hostmode)
-+		bcma_core_pci_clientmode_init(pc);
-+}
-+
-+int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
-+			  bool enable)
-+{
-+	struct pci_dev *pdev = pc->core->bus->host_pci;
-+	u32 coremask, tmp;
-+	int err = 0;
-+
-+	if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
-+		/* This bcma device is not on a PCI host-bus. So the IRQs are
-+		 * not routed through the PCI core.
-+		 * So we must not enable routing through the PCI core. */
-+		goto out;
-+	}
-+
-+	err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
-+	if (err)
-+		goto out;
-+
-+	coremask = BIT(core->core_index) << 8;
-+	if (enable)
-+		tmp |= coremask;
-+	else
-+		tmp &= ~coremask;
-+
-+	err = pci_write_config_dword(pdev, BCMA_PCI_IRQMASK, tmp);
-+
-+out:
-+	return err;
-+}
-+EXPORT_SYMBOL_GPL(bcma_core_pci_irq_ctl);
---- /dev/null
-+++ b/drivers/bcma/host_pci.c
-@@ -0,0 +1,292 @@
-+/*
-+ * Broadcom specific AMBA
-+ * PCI Host
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include <linux/slab.h>
-+#include <linux/bcma/bcma.h>
-+#include <linux/pci.h>
-+#include <linux/module.h>
-+
-+static void bcma_host_pci_switch_core(struct bcma_device *core)
-+{
-+	pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN,
-+			       core->addr);
-+	pci_write_config_dword(core->bus->host_pci, BCMA_PCI_BAR0_WIN2,
-+			       core->wrap);
-+	core->bus->mapped_core = core;
-+	pr_debug("Switched to core: 0x%X\n", core->id.id);
-+}
-+
-+/* Provides access to the requested core. Returns base offset that has to be
-+ * used. It makes use of fixed windows when possible. */
-+static u16 bcma_host_pci_provide_access_to_core(struct bcma_device *core)
-+{
-+	switch (core->id.id) {
-+	case BCMA_CORE_CHIPCOMMON:
-+		return 3 * BCMA_CORE_SIZE;
-+	case BCMA_CORE_PCIE:
-+		return 2 * BCMA_CORE_SIZE;
-+	}
-+
-+	if (core->bus->mapped_core != core)
-+		bcma_host_pci_switch_core(core);
-+	return 0;
-+}
-+
-+static u8 bcma_host_pci_read8(struct bcma_device *core, u16 offset)
-+{
-+	offset += bcma_host_pci_provide_access_to_core(core);
-+	return ioread8(core->bus->mmio + offset);
-+}
-+
-+static u16 bcma_host_pci_read16(struct bcma_device *core, u16 offset)
-+{
-+	offset += bcma_host_pci_provide_access_to_core(core);
-+	return ioread16(core->bus->mmio + offset);
-+}
-+
-+static u32 bcma_host_pci_read32(struct bcma_device *core, u16 offset)
-+{
-+	offset += bcma_host_pci_provide_access_to_core(core);
-+	return ioread32(core->bus->mmio + offset);
-+}
-+
-+static void bcma_host_pci_write8(struct bcma_device *core, u16 offset,
-+				 u8 value)
-+{
-+	offset += bcma_host_pci_provide_access_to_core(core);
-+	iowrite8(value, core->bus->mmio + offset);
-+}
-+
-+static void bcma_host_pci_write16(struct bcma_device *core, u16 offset,
-+				 u16 value)
-+{
-+	offset += bcma_host_pci_provide_access_to_core(core);
-+	iowrite16(value, core->bus->mmio + offset);
-+}
-+
-+static void bcma_host_pci_write32(struct bcma_device *core, u16 offset,
-+				 u32 value)
-+{
-+	offset += bcma_host_pci_provide_access_to_core(core);
-+	iowrite32(value, core->bus->mmio + offset);
-+}
-+
-+#ifdef CONFIG_BCMA_BLOCKIO
-+void bcma_host_pci_block_read(struct bcma_device *core, void *buffer,
-+			      size_t count, u16 offset, u8 reg_width)
-+{
-+	void __iomem *addr = core->bus->mmio + offset;
-+	if (core->bus->mapped_core != core)
-+		bcma_host_pci_switch_core(core);
-+	switch (reg_width) {
-+	case sizeof(u8):
-+		ioread8_rep(addr, buffer, count);
-+		break;
-+	case sizeof(u16):
-+		WARN_ON(count & 1);
-+		ioread16_rep(addr, buffer, count >> 1);
-+		break;
-+	case sizeof(u32):
-+		WARN_ON(count & 3);
-+		ioread32_rep(addr, buffer, count >> 2);
-+		break;
-+	default:
-+		WARN_ON(1);
-+	}
-+}
-+
-+void bcma_host_pci_block_write(struct bcma_device *core, const void *buffer,
-+			       size_t count, u16 offset, u8 reg_width)
-+{
-+	void __iomem *addr = core->bus->mmio + offset;
-+	if (core->bus->mapped_core != core)
-+		bcma_host_pci_switch_core(core);
-+	switch (reg_width) {
-+	case sizeof(u8):
-+		iowrite8_rep(addr, buffer, count);
-+		break;
-+	case sizeof(u16):
-+		WARN_ON(count & 1);
-+		iowrite16_rep(addr, buffer, count >> 1);
-+		break;
-+	case sizeof(u32):
-+		WARN_ON(count & 3);
-+		iowrite32_rep(addr, buffer, count >> 2);
-+		break;
-+	default:
-+		WARN_ON(1);
-+	}
-+}
-+#endif
-+
-+static u32 bcma_host_pci_aread32(struct bcma_device *core, u16 offset)
-+{
-+	if (core->bus->mapped_core != core)
-+		bcma_host_pci_switch_core(core);
-+	return ioread32(core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
-+}
-+
-+static void bcma_host_pci_awrite32(struct bcma_device *core, u16 offset,
-+				  u32 value)
-+{
-+	if (core->bus->mapped_core != core)
-+		bcma_host_pci_switch_core(core);
-+	iowrite32(value, core->bus->mmio + (1 * BCMA_CORE_SIZE) + offset);
-+}
-+
-+const struct bcma_host_ops bcma_host_pci_ops = {
-+	.read8		= bcma_host_pci_read8,
-+	.read16		= bcma_host_pci_read16,
-+	.read32		= bcma_host_pci_read32,
-+	.write8		= bcma_host_pci_write8,
-+	.write16	= bcma_host_pci_write16,
-+	.write32	= bcma_host_pci_write32,
-+#ifdef CONFIG_BCMA_BLOCKIO
-+	.block_read	= bcma_host_pci_block_read,
-+	.block_write	= bcma_host_pci_block_write,
-+#endif
-+	.aread32	= bcma_host_pci_aread32,
-+	.awrite32	= bcma_host_pci_awrite32,
-+};
-+
-+static int __devinit bcma_host_pci_probe(struct pci_dev *dev,
-+					 const struct pci_device_id *id)
-+{
-+	struct bcma_bus *bus;
-+	int err = -ENOMEM;
-+	const char *name;
-+	u32 val;
-+
-+	/* Alloc */
-+	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
-+	if (!bus)
-+		goto out;
-+
-+	/* Basic PCI configuration */
-+	err = pci_enable_device(dev);
-+	if (err)
-+		goto err_kfree_bus;
-+
-+	name = dev_name(&dev->dev);
-+	if (dev->driver && dev->driver->name)
-+		name = dev->driver->name;
-+	err = pci_request_regions(dev, name);
-+	if (err)
-+		goto err_pci_disable;
-+	pci_set_master(dev);
-+
-+	/* Disable the RETRY_TIMEOUT register (0x41) to keep
-+	 * PCI Tx retries from interfering with C3 CPU state */
-+	pci_read_config_dword(dev, 0x40, &val);
-+	if ((val & 0x0000ff00) != 0)
-+		pci_write_config_dword(dev, 0x40, val & 0xffff00ff);
-+
-+	/* SSB needed additional powering up, do we have any AMBA PCI cards? */
-+	if (!pci_is_pcie(dev))
-+		pr_err("PCI card detected, report problems.\n");
-+
-+	/* Map MMIO */
-+	err = -ENOMEM;
-+	bus->mmio = pci_iomap(dev, 0, ~0UL);
-+	if (!bus->mmio)
-+		goto err_pci_release_regions;
-+
-+	/* Host specific */
-+	bus->host_pci = dev;
-+	bus->hosttype = BCMA_HOSTTYPE_PCI;
-+	bus->ops = &bcma_host_pci_ops;
-+
-+	/* Register */
-+	err = bcma_bus_register(bus);
-+	if (err)
-+		goto err_pci_unmap_mmio;
-+
-+	pci_set_drvdata(dev, bus);
-+
-+out:
-+	return err;
-+
-+err_pci_unmap_mmio:
-+	pci_iounmap(dev, bus->mmio);
-+err_pci_release_regions:
-+	pci_release_regions(dev);
-+err_pci_disable:
-+	pci_disable_device(dev);
-+err_kfree_bus:
-+	kfree(bus);
-+	return err;
-+}
-+
-+static void bcma_host_pci_remove(struct pci_dev *dev)
-+{
-+	struct bcma_bus *bus = pci_get_drvdata(dev);
-+
-+	bcma_bus_unregister(bus);
-+	pci_iounmap(dev, bus->mmio);
-+	pci_release_regions(dev);
-+	pci_disable_device(dev);
-+	kfree(bus);
-+	pci_set_drvdata(dev, NULL);
-+}
-+
-+#ifdef CONFIG_PM
-+static int bcma_host_pci_suspend(struct device *dev)
-+{
-+	struct pci_dev *pdev = to_pci_dev(dev);
-+	struct bcma_bus *bus = pci_get_drvdata(pdev);
-+
-+	bus->mapped_core = NULL;
-+
-+	return bcma_bus_suspend(bus);
-+}
-+
-+static int bcma_host_pci_resume(struct device *dev)
-+{
-+	struct pci_dev *pdev = to_pci_dev(dev);
-+	struct bcma_bus *bus = pci_get_drvdata(pdev);
-+
-+	return bcma_bus_resume(bus);
-+}
-+
-+static SIMPLE_DEV_PM_OPS(bcma_pm_ops, bcma_host_pci_suspend,
-+			 bcma_host_pci_resume);
-+#define BCMA_PM_OPS	(&bcma_pm_ops)
-+
-+#else /* CONFIG_PM */
-+
-+#define BCMA_PM_OPS     NULL
-+
-+#endif /* CONFIG_PM */
-+
-+static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
-+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) },
-+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4331) },
-+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) },
-+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
-+	{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
-+	{ 0, },
-+};
-+MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
-+
-+static struct pci_driver bcma_pci_bridge_driver = {
-+	.name = "bcma-pci-bridge",
-+	.id_table = bcma_pci_bridge_tbl,
-+	.probe = bcma_host_pci_probe,
-+	.remove = bcma_host_pci_remove,
-+	.driver.pm = BCMA_PM_OPS,
-+};
-+
-+int __init bcma_host_pci_init(void)
-+{
-+	return pci_register_driver(&bcma_pci_bridge_driver);
-+}
-+
-+void __exit bcma_host_pci_exit(void)
-+{
-+	pci_unregister_driver(&bcma_pci_bridge_driver);
-+}
---- /dev/null
-+++ b/drivers/bcma/main.c
-@@ -0,0 +1,387 @@
-+/*
-+ * Broadcom specific AMBA
-+ * Bus subsystem
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include <linux/module.h>
-+#include <linux/bcma/bcma.h>
-+#include <linux/slab.h>
-+
-+MODULE_DESCRIPTION("Broadcom's specific AMBA driver");
-+MODULE_LICENSE("GPL");
-+
-+/* contains the number the next bus should get. */
-+static unsigned int bcma_bus_next_num = 0;
-+
-+/* bcma_buses_mutex locks the bcma_bus_next_num */
-+static DEFINE_MUTEX(bcma_buses_mutex);
-+
-+static int bcma_bus_match(struct device *dev, struct device_driver *drv);
-+static int bcma_device_probe(struct device *dev);
-+static int bcma_device_remove(struct device *dev);
-+static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env);
-+
-+static ssize_t manuf_show(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+	return sprintf(buf, "0x%03X\n", core->id.manuf);
-+}
-+static ssize_t id_show(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+	return sprintf(buf, "0x%03X\n", core->id.id);
-+}
-+static ssize_t rev_show(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+	return sprintf(buf, "0x%02X\n", core->id.rev);
-+}
-+static ssize_t class_show(struct device *dev, struct device_attribute *attr, char *buf)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+	return sprintf(buf, "0x%X\n", core->id.class);
-+}
-+static struct device_attribute bcma_device_attrs[] = {
-+	__ATTR_RO(manuf),
-+	__ATTR_RO(id),
-+	__ATTR_RO(rev),
-+	__ATTR_RO(class),
-+	__ATTR_NULL,
-+};
-+
-+static struct bus_type bcma_bus_type = {
-+	.name		= "bcma",
-+	.match		= bcma_bus_match,
-+	.probe		= bcma_device_probe,
-+	.remove		= bcma_device_remove,
-+	.uevent		= bcma_device_uevent,
-+	.dev_attrs	= bcma_device_attrs,
-+};
-+
-+struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
-+{
-+	struct bcma_device *core;
-+
-+	list_for_each_entry(core, &bus->cores, list) {
-+		if (core->id.id == coreid)
-+			return core;
-+	}
-+	return NULL;
-+}
-+EXPORT_SYMBOL_GPL(bcma_find_core);
-+
-+static void bcma_release_core_dev(struct device *dev)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+	if (core->io_addr)
-+		iounmap(core->io_addr);
-+	if (core->io_wrap)
-+		iounmap(core->io_wrap);
-+	kfree(core);
-+}
-+
-+static int bcma_register_cores(struct bcma_bus *bus)
-+{
-+	struct bcma_device *core;
-+	int err, dev_id = 0;
-+
-+	list_for_each_entry(core, &bus->cores, list) {
-+		/* We support that cores ourself */
-+		switch (core->id.id) {
-+		case BCMA_CORE_CHIPCOMMON:
-+		case BCMA_CORE_PCI:
-+		case BCMA_CORE_PCIE:
-+		case BCMA_CORE_MIPS_74K:
-+			continue;
-+		}
-+
-+		core->dev.release = bcma_release_core_dev;
-+		core->dev.bus = &bcma_bus_type;
-+		dev_set_name(&core->dev, "bcma%d:%d", bus->num, dev_id);
-+
-+		switch (bus->hosttype) {
-+		case BCMA_HOSTTYPE_PCI:
-+			core->dev.parent = &bus->host_pci->dev;
-+			core->dma_dev = &bus->host_pci->dev;
-+			core->irq = bus->host_pci->irq;
-+			break;
-+		case BCMA_HOSTTYPE_SOC:
-+			core->dev.dma_mask = &core->dev.coherent_dma_mask;
-+			core->dma_dev = &core->dev;
-+			break;
-+		case BCMA_HOSTTYPE_SDIO:
-+			break;
-+		}
-+
-+		err = device_register(&core->dev);
-+		if (err) {
-+			pr_err("Could not register dev for core 0x%03X\n",
-+			       core->id.id);
-+			continue;
-+		}
-+		core->dev_registered = true;
-+		dev_id++;
-+	}
-+
-+	return 0;
-+}
-+
-+static void bcma_unregister_cores(struct bcma_bus *bus)
-+{
-+	struct bcma_device *core;
-+
-+	list_for_each_entry(core, &bus->cores, list) {
-+		if (core->dev_registered)
-+			device_unregister(&core->dev);
-+	}
-+}
-+
-+int __devinit bcma_bus_register(struct bcma_bus *bus)
-+{
-+	int err;
-+	struct bcma_device *core;
-+
-+	mutex_lock(&bcma_buses_mutex);
-+	bus->num = bcma_bus_next_num++;
-+	mutex_unlock(&bcma_buses_mutex);
-+
-+	/* Scan for devices (cores) */
-+	err = bcma_bus_scan(bus);
-+	if (err) {
-+		pr_err("Failed to scan: %d\n", err);
-+		return -1;
-+	}
-+
-+	/* Init CC core */
-+	core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
-+	if (core) {
-+		bus->drv_cc.core = core;
-+		bcma_core_chipcommon_init(&bus->drv_cc);
-+	}
-+
-+	/* Init MIPS core */
-+	core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
-+	if (core) {
-+		bus->drv_mips.core = core;
-+		bcma_core_mips_init(&bus->drv_mips);
-+	}
-+
-+	/* Init PCIE core */
-+	core = bcma_find_core(bus, BCMA_CORE_PCIE);
-+	if (core) {
-+		bus->drv_pci.core = core;
-+		bcma_core_pci_init(&bus->drv_pci);
-+	}
-+
-+	/* Try to get SPROM */
-+	err = bcma_sprom_get(bus);
-+	if (err == -ENOENT) {
-+		pr_err("No SPROM available\n");
-+	} else if (err)
-+		pr_err("Failed to get SPROM: %d\n", err);
-+
-+	/* Register found cores */
-+	bcma_register_cores(bus);
-+
-+	pr_info("Bus registered\n");
-+
-+	return 0;
-+}
-+
-+void bcma_bus_unregister(struct bcma_bus *bus)
-+{
-+	bcma_unregister_cores(bus);
-+}
-+
-+int __init bcma_bus_early_register(struct bcma_bus *bus,
-+				   struct bcma_device *core_cc,
-+				   struct bcma_device *core_mips)
-+{
-+	int err;
-+	struct bcma_device *core;
-+	struct bcma_device_id match;
-+
-+	bcma_init_bus(bus);
-+
-+	match.manuf = BCMA_MANUF_BCM;
-+	match.id = BCMA_CORE_CHIPCOMMON;
-+	match.class = BCMA_CL_SIM;
-+	match.rev = BCMA_ANY_REV;
-+
-+	/* Scan for chip common core */
-+	err = bcma_bus_scan_early(bus, &match, core_cc);
-+	if (err) {
-+		pr_err("Failed to scan for common core: %d\n", err);
-+		return -1;
-+	}
-+
-+	match.manuf = BCMA_MANUF_MIPS;
-+	match.id = BCMA_CORE_MIPS_74K;
-+	match.class = BCMA_CL_SIM;
-+	match.rev = BCMA_ANY_REV;
-+
-+	/* Scan for mips core */
-+	err = bcma_bus_scan_early(bus, &match, core_mips);
-+	if (err) {
-+		pr_err("Failed to scan for mips core: %d\n", err);
-+		return -1;
-+	}
-+
-+	/* Init CC core */
-+	core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
-+	if (core) {
-+		bus->drv_cc.core = core;
-+		bcma_core_chipcommon_init(&bus->drv_cc);
-+	}
-+
-+	/* Init MIPS core */
-+	core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
-+	if (core) {
-+		bus->drv_mips.core = core;
-+		bcma_core_mips_init(&bus->drv_mips);
-+	}
-+
-+	pr_info("Early bus registered\n");
-+
-+	return 0;
-+}
-+
-+#ifdef CONFIG_PM
-+int bcma_bus_suspend(struct bcma_bus *bus)
-+{
-+	struct bcma_device *core;
-+
-+	list_for_each_entry(core, &bus->cores, list) {
-+		struct device_driver *drv = core->dev.driver;
-+		if (drv) {
-+			struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
-+			if (adrv->suspend)
-+				adrv->suspend(core);
-+		}
-+	}
-+	return 0;
-+}
-+
-+int bcma_bus_resume(struct bcma_bus *bus)
-+{
-+	struct bcma_device *core;
-+
-+	/* Init CC core */
-+	core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
-+	if (core) {
-+		bus->drv_cc.setup_done = false;
-+		bcma_core_chipcommon_init(&bus->drv_cc);
-+	}
-+
-+	list_for_each_entry(core, &bus->cores, list) {
-+		struct device_driver *drv = core->dev.driver;
-+		if (drv) {
-+			struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
-+			if (adrv->resume)
-+				adrv->resume(core);
-+		}
-+	}
-+
-+	return 0;
-+}
-+#endif
-+
-+int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
-+{
-+	drv->drv.name = drv->name;
-+	drv->drv.bus = &bcma_bus_type;
-+	drv->drv.owner = owner;
-+
-+	return driver_register(&drv->drv);
-+}
-+EXPORT_SYMBOL_GPL(__bcma_driver_register);
-+
-+void bcma_driver_unregister(struct bcma_driver *drv)
-+{
-+	driver_unregister(&drv->drv);
-+}
-+EXPORT_SYMBOL_GPL(bcma_driver_unregister);
-+
-+static int bcma_bus_match(struct device *dev, struct device_driver *drv)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+	struct bcma_driver *adrv = container_of(drv, struct bcma_driver, drv);
-+	const struct bcma_device_id *cid = &core->id;
-+	const struct bcma_device_id *did;
-+
-+	for (did = adrv->id_table; did->manuf || did->id || did->rev; did++) {
-+	    if ((did->manuf == cid->manuf || did->manuf == BCMA_ANY_MANUF) &&
-+		(did->id == cid->id || did->id == BCMA_ANY_ID) &&
-+		(did->rev == cid->rev || did->rev == BCMA_ANY_REV) &&
-+		(did->class == cid->class || did->class == BCMA_ANY_CLASS))
-+			return 1;
-+	}
-+	return 0;
-+}
-+
-+static int bcma_device_probe(struct device *dev)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+	struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
-+					       drv);
-+	int err = 0;
-+
-+	if (adrv->probe)
-+		err = adrv->probe(core);
-+
-+	return err;
-+}
-+
-+static int bcma_device_remove(struct device *dev)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+	struct bcma_driver *adrv = container_of(dev->driver, struct bcma_driver,
-+					       drv);
-+
-+	if (adrv->remove)
-+		adrv->remove(core);
-+
-+	return 0;
-+}
-+
-+static int bcma_device_uevent(struct device *dev, struct kobj_uevent_env *env)
-+{
-+	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
-+
-+	return add_uevent_var(env,
-+			      "MODALIAS=bcma:m%04Xid%04Xrev%02Xcl%02X",
-+			      core->id.manuf, core->id.id,
-+			      core->id.rev, core->id.class);
-+}
-+
-+static int __init bcma_modinit(void)
-+{
-+	int err;
-+
-+	err = bus_register(&bcma_bus_type);
-+	if (err)
-+		return err;
-+
-+#ifdef CONFIG_BCMA_HOST_PCI
-+	err = bcma_host_pci_init();
-+	if (err) {
-+		pr_err("PCI host initialization failed\n");
-+		err = 0;
-+	}
-+#endif
-+
-+	return err;
-+}
-+fs_initcall(bcma_modinit);
-+
-+static void __exit bcma_modexit(void)
-+{
-+#ifdef CONFIG_BCMA_HOST_PCI
-+	bcma_host_pci_exit();
-+#endif
-+	bus_unregister(&bcma_bus_type);
-+}
-+module_exit(bcma_modexit)
---- /dev/null
-+++ b/drivers/bcma/scan.c
-@@ -0,0 +1,507 @@
-+/*
-+ * Broadcom specific AMBA
-+ * Bus scanning
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "scan.h"
-+#include "bcma_private.h"
-+
-+#include <linux/bcma/bcma.h>
-+#include <linux/bcma/bcma_regs.h>
-+#include <linux/pci.h>
-+#include <linux/io.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/slab.h>
-+
-+struct bcma_device_id_name {
-+	u16 id;
-+	const char *name;
-+};
-+struct bcma_device_id_name bcma_device_names[] = {
-+	{ BCMA_CORE_OOB_ROUTER, "OOB Router" },
-+	{ BCMA_CORE_INVALID, "Invalid" },
-+	{ BCMA_CORE_CHIPCOMMON, "ChipCommon" },
-+	{ BCMA_CORE_ILINE20, "ILine 20" },
-+	{ BCMA_CORE_SRAM, "SRAM" },
-+	{ BCMA_CORE_SDRAM, "SDRAM" },
-+	{ BCMA_CORE_PCI, "PCI" },
-+	{ BCMA_CORE_MIPS, "MIPS" },
-+	{ BCMA_CORE_ETHERNET, "Fast Ethernet" },
-+	{ BCMA_CORE_V90, "V90" },
-+	{ BCMA_CORE_USB11_HOSTDEV, "USB 1.1 Hostdev" },
-+	{ BCMA_CORE_ADSL, "ADSL" },
-+	{ BCMA_CORE_ILINE100, "ILine 100" },
-+	{ BCMA_CORE_IPSEC, "IPSEC" },
-+	{ BCMA_CORE_UTOPIA, "UTOPIA" },
-+	{ BCMA_CORE_PCMCIA, "PCMCIA" },
-+	{ BCMA_CORE_INTERNAL_MEM, "Internal Memory" },
-+	{ BCMA_CORE_MEMC_SDRAM, "MEMC SDRAM" },
-+	{ BCMA_CORE_OFDM, "OFDM" },
-+	{ BCMA_CORE_EXTIF, "EXTIF" },
-+	{ BCMA_CORE_80211, "IEEE 802.11" },
-+	{ BCMA_CORE_PHY_A, "PHY A" },
-+	{ BCMA_CORE_PHY_B, "PHY B" },
-+	{ BCMA_CORE_PHY_G, "PHY G" },
-+	{ BCMA_CORE_MIPS_3302, "MIPS 3302" },
-+	{ BCMA_CORE_USB11_HOST, "USB 1.1 Host" },
-+	{ BCMA_CORE_USB11_DEV, "USB 1.1 Device" },
-+	{ BCMA_CORE_USB20_HOST, "USB 2.0 Host" },
-+	{ BCMA_CORE_USB20_DEV, "USB 2.0 Device" },
-+	{ BCMA_CORE_SDIO_HOST, "SDIO Host" },
-+	{ BCMA_CORE_ROBOSWITCH, "Roboswitch" },
-+	{ BCMA_CORE_PARA_ATA, "PATA" },
-+	{ BCMA_CORE_SATA_XORDMA, "SATA XOR-DMA" },
-+	{ BCMA_CORE_ETHERNET_GBIT, "GBit Ethernet" },
-+	{ BCMA_CORE_PCIE, "PCIe" },
-+	{ BCMA_CORE_PHY_N, "PHY N" },
-+	{ BCMA_CORE_SRAM_CTL, "SRAM Controller" },
-+	{ BCMA_CORE_MINI_MACPHY, "Mini MACPHY" },
-+	{ BCMA_CORE_ARM_1176, "ARM 1176" },
-+	{ BCMA_CORE_ARM_7TDMI, "ARM 7TDMI" },
-+	{ BCMA_CORE_PHY_LP, "PHY LP" },
-+	{ BCMA_CORE_PMU, "PMU" },
-+	{ BCMA_CORE_PHY_SSN, "PHY SSN" },
-+	{ BCMA_CORE_SDIO_DEV, "SDIO Device" },
-+	{ BCMA_CORE_ARM_CM3, "ARM CM3" },
-+	{ BCMA_CORE_PHY_HT, "PHY HT" },
-+	{ BCMA_CORE_MIPS_74K, "MIPS 74K" },
-+	{ BCMA_CORE_MAC_GBIT, "GBit MAC" },
-+	{ BCMA_CORE_DDR12_MEM_CTL, "DDR1/DDR2 Memory Controller" },
-+	{ BCMA_CORE_PCIE_RC, "PCIe Root Complex" },
-+	{ BCMA_CORE_OCP_OCP_BRIDGE, "OCP to OCP Bridge" },
-+	{ BCMA_CORE_SHARED_COMMON, "Common Shared" },
-+	{ BCMA_CORE_OCP_AHB_BRIDGE, "OCP to AHB Bridge" },
-+	{ BCMA_CORE_SPI_HOST, "SPI Host" },
-+	{ BCMA_CORE_I2S, "I2S" },
-+	{ BCMA_CORE_SDR_DDR1_MEM_CTL, "SDR/DDR1 Memory Controller" },
-+	{ BCMA_CORE_SHIM, "SHIM" },
-+	{ BCMA_CORE_DEFAULT, "Default" },
-+};
-+const char *bcma_device_name(struct bcma_device_id *id)
-+{
-+	int i;
-+
-+	if (id->manuf == BCMA_MANUF_BCM) {
-+		for (i = 0; i < ARRAY_SIZE(bcma_device_names); i++) {
-+			if (bcma_device_names[i].id == id->id)
-+				return bcma_device_names[i].name;
-+		}
-+	}
-+	return "UNKNOWN";
-+}
-+
-+static u32 bcma_scan_read32(struct bcma_bus *bus, u8 current_coreidx,
-+		       u16 offset)
-+{
-+	return readl(bus->mmio + offset);
-+}
-+
-+static void bcma_scan_switch_core(struct bcma_bus *bus, u32 addr)
-+{
-+	if (bus->hosttype == BCMA_HOSTTYPE_PCI)
-+		pci_write_config_dword(bus->host_pci, BCMA_PCI_BAR0_WIN,
-+				       addr);
-+}
-+
-+static u32 bcma_erom_get_ent(struct bcma_bus *bus, u32 **eromptr)
-+{
-+	u32 ent = readl(*eromptr);
-+	(*eromptr)++;
-+	return ent;
-+}
-+
-+static void bcma_erom_push_ent(u32 **eromptr)
-+{
-+	(*eromptr)--;
-+}
-+
-+static s32 bcma_erom_get_ci(struct bcma_bus *bus, u32 **eromptr)
-+{
-+	u32 ent = bcma_erom_get_ent(bus, eromptr);
-+	if (!(ent & SCAN_ER_VALID))
-+		return -ENOENT;
-+	if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_CI)
-+		return -ENOENT;
-+	return ent;
-+}
-+
-+static bool bcma_erom_is_end(struct bcma_bus *bus, u32 **eromptr)
-+{
-+	u32 ent = bcma_erom_get_ent(bus, eromptr);
-+	bcma_erom_push_ent(eromptr);
-+	return (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID));
-+}
-+
-+static bool bcma_erom_is_bridge(struct bcma_bus *bus, u32 **eromptr)
-+{
-+	u32 ent = bcma_erom_get_ent(bus, eromptr);
-+	bcma_erom_push_ent(eromptr);
-+	return (((ent & SCAN_ER_VALID)) &&
-+		((ent & SCAN_ER_TAGX) == SCAN_ER_TAG_ADDR) &&
-+		((ent & SCAN_ADDR_TYPE) == SCAN_ADDR_TYPE_BRIDGE));
-+}
-+
-+static void bcma_erom_skip_component(struct bcma_bus *bus, u32 **eromptr)
-+{
-+	u32 ent;
-+	while (1) {
-+		ent = bcma_erom_get_ent(bus, eromptr);
-+		if ((ent & SCAN_ER_VALID) &&
-+		    ((ent & SCAN_ER_TAG) == SCAN_ER_TAG_CI))
-+			break;
-+		if (ent == (SCAN_ER_TAG_END | SCAN_ER_VALID))
-+			break;
-+	}
-+	bcma_erom_push_ent(eromptr);
-+}
-+
-+static s32 bcma_erom_get_mst_port(struct bcma_bus *bus, u32 **eromptr)
-+{
-+	u32 ent = bcma_erom_get_ent(bus, eromptr);
-+	if (!(ent & SCAN_ER_VALID))
-+		return -ENOENT;
-+	if ((ent & SCAN_ER_TAG) != SCAN_ER_TAG_MP)
-+		return -ENOENT;
-+	return ent;
-+}
-+
-+static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
-+				  u32 type, u8 port)
-+{
-+	u32 addrl, addrh, sizel, sizeh = 0;
-+	u32 size;
-+
-+	u32 ent = bcma_erom_get_ent(bus, eromptr);
-+	if ((!(ent & SCAN_ER_VALID)) ||
-+	    ((ent & SCAN_ER_TAGX) != SCAN_ER_TAG_ADDR) ||
-+	    ((ent & SCAN_ADDR_TYPE) != type) ||
-+	    (((ent & SCAN_ADDR_PORT) >> SCAN_ADDR_PORT_SHIFT) != port)) {
-+		bcma_erom_push_ent(eromptr);
-+		return -EINVAL;
-+	}
-+
-+	addrl = ent & SCAN_ADDR_ADDR;
-+	if (ent & SCAN_ADDR_AG32)
-+		addrh = bcma_erom_get_ent(bus, eromptr);
-+	else
-+		addrh = 0;
-+
-+	if ((ent & SCAN_ADDR_SZ) == SCAN_ADDR_SZ_SZD) {
-+		size = bcma_erom_get_ent(bus, eromptr);
-+		sizel = size & SCAN_SIZE_SZ;
-+		if (size & SCAN_SIZE_SG32)
-+			sizeh = bcma_erom_get_ent(bus, eromptr);
-+	} else
-+		sizel = SCAN_ADDR_SZ_BASE <<
-+				((ent & SCAN_ADDR_SZ) >> SCAN_ADDR_SZ_SHIFT);
-+
-+	return addrl;
-+}
-+
-+static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
-+						   u16 index)
-+{
-+	struct bcma_device *core;
-+
-+	list_for_each_entry(core, &bus->cores, list) {
-+		if (core->core_index == index)
-+			return core;
-+	}
-+	return NULL;
-+}
-+
-+static struct bcma_device *bcma_find_core_reverse(struct bcma_bus *bus, u16 coreid)
-+{
-+	struct bcma_device *core;
-+
-+	list_for_each_entry_reverse(core, &bus->cores, list) {
-+		if (core->id.id == coreid)
-+			return core;
-+	}
-+	return NULL;
-+}
-+
-+static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
-+			      struct bcma_device_id *match, int core_num,
-+			      struct bcma_device *core)
-+{
-+	s32 tmp;
-+	u8 i, j;
-+	s32 cia, cib;
-+	u8 ports[2], wrappers[2];
-+
-+	/* get CIs */
-+	cia = bcma_erom_get_ci(bus, eromptr);
-+	if (cia < 0) {
-+		bcma_erom_push_ent(eromptr);
-+		if (bcma_erom_is_end(bus, eromptr))
-+			return -ESPIPE;
-+		return -EILSEQ;
-+	}
-+	cib = bcma_erom_get_ci(bus, eromptr);
-+	if (cib < 0)
-+		return -EILSEQ;
-+
-+	/* parse CIs */
-+	core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
-+	core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
-+	core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
-+	ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
-+	ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
-+	wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
-+	wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
-+	core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
-+
-+	if (((core->id.manuf == BCMA_MANUF_ARM) &&
-+	     (core->id.id == 0xFFF)) ||
-+	    (ports[1] == 0)) {
-+		bcma_erom_skip_component(bus, eromptr);
-+		return -ENXIO;
-+	}
-+
-+	/* check if component is a core at all */
-+	if (wrappers[0] + wrappers[1] == 0) {
-+		/* we could save addrl of the router
-+		if (cid == BCMA_CORE_OOB_ROUTER)
-+		 */
-+		bcma_erom_skip_component(bus, eromptr);
-+		return -ENXIO;
-+	}
-+
-+	if (bcma_erom_is_bridge(bus, eromptr)) {
-+		bcma_erom_skip_component(bus, eromptr);
-+		return -ENXIO;
-+	}
-+
-+	if (bcma_find_core_by_index(bus, core_num)) {
-+		bcma_erom_skip_component(bus, eromptr);
-+		return -ENODEV;
-+	}
-+
-+	if (match && ((match->manuf != BCMA_ANY_MANUF &&
-+	      match->manuf != core->id.manuf) ||
-+	     (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
-+	     (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
-+	     (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
-+	    )) {
-+		bcma_erom_skip_component(bus, eromptr);
-+		return -ENODEV;
-+	}
-+
-+	/* get & parse master ports */
-+	for (i = 0; i < ports[0]; i++) {
-+		s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
-+		if (mst_port_d < 0)
-+			return -EILSEQ;
-+	}
-+
-+	/* get & parse slave ports */
-+	for (i = 0; i < ports[1]; i++) {
-+		for (j = 0; ; j++) {
-+			tmp = bcma_erom_get_addr_desc(bus, eromptr,
-+				SCAN_ADDR_TYPE_SLAVE, i);
-+			if (tmp < 0) {
-+				/* no more entries for port _i_ */
-+				/* pr_debug("erom: slave port %d "
-+				 * "has %d descriptors\n", i, j); */
-+				break;
-+			} else {
-+				if (i == 0 && j == 0)
-+					core->addr = tmp;
-+			}
-+		}
-+	}
-+
-+	/* get & parse master wrappers */
-+	for (i = 0; i < wrappers[0]; i++) {
-+		for (j = 0; ; j++) {
-+			tmp = bcma_erom_get_addr_desc(bus, eromptr,
-+				SCAN_ADDR_TYPE_MWRAP, i);
-+			if (tmp < 0) {
-+				/* no more entries for port _i_ */
-+				/* pr_debug("erom: master wrapper %d "
-+				 * "has %d descriptors\n", i, j); */
-+				break;
-+			} else {
-+				if (i == 0 && j == 0)
-+					core->wrap = tmp;
-+			}
-+		}
-+	}
-+
-+	/* get & parse slave wrappers */
-+	for (i = 0; i < wrappers[1]; i++) {
-+		u8 hack = (ports[1] == 1) ? 0 : 1;
-+		for (j = 0; ; j++) {
-+			tmp = bcma_erom_get_addr_desc(bus, eromptr,
-+				SCAN_ADDR_TYPE_SWRAP, i + hack);
-+			if (tmp < 0) {
-+				/* no more entries for port _i_ */
-+				/* pr_debug("erom: master wrapper %d "
-+				 * has %d descriptors\n", i, j); */
-+				break;
-+			} else {
-+				if (wrappers[0] == 0 && !i && !j)
-+					core->wrap = tmp;
-+			}
-+		}
-+	}
-+	if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
-+		core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
-+		if (!core->io_addr)
-+			return -ENOMEM;
-+		core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
-+		if (!core->io_wrap) {
-+			iounmap(core->io_addr);
-+			return -ENOMEM;
-+		}
-+	}
-+	return 0;
-+}
-+
-+void bcma_init_bus(struct bcma_bus *bus)
-+{
-+	s32 tmp;
-+	struct bcma_chipinfo *chipinfo = &(bus->chipinfo);
-+
-+	if (bus->init_done)
-+		return;
-+
-+	INIT_LIST_HEAD(&bus->cores);
-+	bus->nr_cores = 0;
-+
-+	bcma_scan_switch_core(bus, BCMA_ADDR_BASE);
-+
-+	tmp = bcma_scan_read32(bus, 0, BCMA_CC_ID);
-+	chipinfo->id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
-+	chipinfo->rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
-+	chipinfo->pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
-+	pr_info("Found chip with id 0x%04X, rev 0x%02X and package 0x%02X\n",
-+		chipinfo->id, chipinfo->rev, chipinfo->pkg);
-+
-+	bus->init_done = true;
-+}
-+
-+int bcma_bus_scan(struct bcma_bus *bus)
-+{
-+	u32 erombase;
-+	u32 __iomem *eromptr, *eromend;
-+
-+	int err, core_num = 0;
-+
-+	bcma_init_bus(bus);
-+
-+	erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
-+	if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
-+		eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
-+		if (!eromptr)
-+			return -ENOMEM;
-+	} else {
-+		eromptr = bus->mmio;
-+	}
-+
-+	eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
-+
-+	bcma_scan_switch_core(bus, erombase);
-+
-+	while (eromptr < eromend) {
-+		struct bcma_device *other_core;
-+		struct bcma_device *core = kzalloc(sizeof(*core), GFP_KERNEL);
-+		if (!core)
-+			return -ENOMEM;
-+		INIT_LIST_HEAD(&core->list);
-+		core->bus = bus;
-+
-+		err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
-+		if (err < 0) {
-+			kfree(core);
-+			if (err == -ENODEV) {
-+				core_num++;
-+				continue;
-+			} else if (err == -ENXIO) {
-+				continue;
-+			} else if (err == -ESPIPE) {
-+				break;
-+			}
-+			return err;
-+		}
-+
-+		core->core_index = core_num++;
-+		bus->nr_cores++;
-+		other_core = bcma_find_core_reverse(bus, core->id.id);
-+		core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
-+
-+		pr_info("Core %d found: %s "
-+			"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
-+			core->core_index, bcma_device_name(&core->id),
-+			core->id.manuf, core->id.id, core->id.rev,
-+			core->id.class);
-+
-+		list_add(&core->list, &bus->cores);
-+	}
-+
-+	if (bus->hosttype == BCMA_HOSTTYPE_SOC)
-+		iounmap(eromptr);
-+
-+	return 0;
-+}
-+
-+int __init bcma_bus_scan_early(struct bcma_bus *bus,
-+			       struct bcma_device_id *match,
-+			       struct bcma_device *core)
-+{
-+	u32 erombase;
-+	u32 __iomem *eromptr, *eromend;
-+
-+	int err = -ENODEV;
-+	int core_num = 0;
-+
-+	erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
-+	if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
-+		eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
-+		if (!eromptr)
-+			return -ENOMEM;
-+	} else {
-+		eromptr = bus->mmio;
-+	}
-+
-+	eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
-+
-+	bcma_scan_switch_core(bus, erombase);
-+
-+	while (eromptr < eromend) {
-+		memset(core, 0, sizeof(*core));
-+		INIT_LIST_HEAD(&core->list);
-+		core->bus = bus;
-+
-+		err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
-+		if (err == -ENODEV) {
-+			core_num++;
-+			continue;
-+		} else if (err == -ENXIO)
-+			continue;
-+		else if (err == -ESPIPE)
-+			break;
-+		else if (err < 0)
-+			return err;
-+
-+		core->core_index = core_num++;
-+		bus->nr_cores++;
-+		pr_info("Core %d found: %s "
-+			"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
-+			core->core_index, bcma_device_name(&core->id),
-+			core->id.manuf, core->id.id, core->id.rev,
-+			core->id.class);
-+
-+		list_add(&core->list, &bus->cores);
-+		err = 0;
-+		break;
-+	}
-+
-+	if (bus->hosttype == BCMA_HOSTTYPE_SOC)
-+		iounmap(eromptr);
-+
-+	return err;
-+}
---- /dev/null
-+++ b/drivers/bcma/scan.h
-@@ -0,0 +1,56 @@
-+#ifndef BCMA_SCAN_H_
-+#define BCMA_SCAN_H_
-+
-+#define BCMA_ADDR_BASE		0x18000000
-+#define BCMA_WRAP_BASE		0x18100000
-+
-+#define SCAN_ER_VALID		0x00000001
-+#define SCAN_ER_TAGX		0x00000006 /* we have to ignore 0x8 bit when checking tag for SCAN_ER_TAG_ADDR */
-+#define SCAN_ER_TAG		0x0000000E
-+#define  SCAN_ER_TAG_CI		0x00000000
-+#define  SCAN_ER_TAG_MP		0x00000002
-+#define  SCAN_ER_TAG_ADDR	0x00000004
-+#define  SCAN_ER_TAG_END	0x0000000E
-+#define SCAN_ER_BAD		0xFFFFFFFF
-+
-+#define SCAN_CIA_CLASS		0x000000F0
-+#define SCAN_CIA_CLASS_SHIFT	4
-+#define SCAN_CIA_ID		0x000FFF00
-+#define SCAN_CIA_ID_SHIFT	8
-+#define SCAN_CIA_MANUF		0xFFF00000
-+#define SCAN_CIA_MANUF_SHIFT	20
-+
-+#define SCAN_CIB_NMP		0x000001F0
-+#define SCAN_CIB_NMP_SHIFT	4
-+#define SCAN_CIB_NSP		0x00003E00
-+#define SCAN_CIB_NSP_SHIFT	9
-+#define SCAN_CIB_NMW		0x0007C000
-+#define SCAN_CIB_NMW_SHIFT	14
-+#define SCAN_CIB_NSW		0x00F80000
-+#define SCAN_CIB_NSW_SHIFT	17
-+#define SCAN_CIB_REV		0xFF000000
-+#define SCAN_CIB_REV_SHIFT	24
-+
-+#define SCAN_ADDR_AG32		0x00000008
-+#define SCAN_ADDR_SZ		0x00000030
-+#define SCAN_ADDR_SZ_SHIFT	4
-+#define  SCAN_ADDR_SZ_4K	0x00000000
-+#define  SCAN_ADDR_SZ_8K	0x00000010
-+#define  SCAN_ADDR_SZ_16K	0x00000020
-+#define  SCAN_ADDR_SZ_SZD	0x00000030
-+#define SCAN_ADDR_TYPE		0x000000C0
-+#define  SCAN_ADDR_TYPE_SLAVE	0x00000000
-+#define  SCAN_ADDR_TYPE_BRIDGE	0x00000040
-+#define  SCAN_ADDR_TYPE_SWRAP	0x00000080
-+#define  SCAN_ADDR_TYPE_MWRAP	0x000000C0
-+#define SCAN_ADDR_PORT		0x00000F00
-+#define SCAN_ADDR_PORT_SHIFT	8
-+#define SCAN_ADDR_ADDR		0xFFFFF000
-+
-+#define SCAN_ADDR_SZ_BASE	0x00001000	/* 4KB */
-+
-+#define SCAN_SIZE_SZ_ALIGN	0x00000FFF
-+#define SCAN_SIZE_SZ		0xFFFFF000
-+#define SCAN_SIZE_SG32		0x00000008
-+
-+#endif /* BCMA_SCAN_H_ */
---- /dev/null
-+++ b/include/linux/bcma/bcma.h
-@@ -0,0 +1,307 @@
-+#ifndef LINUX_BCMA_H_
-+#define LINUX_BCMA_H_
-+
-+#include <linux/pci.h>
-+#include <linux/mod_devicetable.h>
-+
-+#include <linux/bcma/bcma_driver_chipcommon.h>
-+#include <linux/bcma/bcma_driver_pci.h>
-+#include <linux/bcma/bcma_driver_mips.h>
-+#include <linux/ssb/ssb.h> /* SPROM sharing */
-+
-+#include "bcma_regs.h"
-+
-+struct bcma_device;
-+struct bcma_bus;
-+
-+enum bcma_hosttype {
-+	BCMA_HOSTTYPE_PCI,
-+	BCMA_HOSTTYPE_SDIO,
-+	BCMA_HOSTTYPE_SOC,
-+};
-+
-+struct bcma_chipinfo {
-+	u16 id;
-+	u8 rev;
-+	u8 pkg;
-+};
-+
-+enum bcma_clkmode {
-+	BCMA_CLKMODE_FAST,
-+	BCMA_CLKMODE_DYNAMIC,
-+};
-+
-+struct bcma_host_ops {
-+	u8 (*read8)(struct bcma_device *core, u16 offset);
-+	u16 (*read16)(struct bcma_device *core, u16 offset);
-+	u32 (*read32)(struct bcma_device *core, u16 offset);
-+	void (*write8)(struct bcma_device *core, u16 offset, u8 value);
-+	void (*write16)(struct bcma_device *core, u16 offset, u16 value);
-+	void (*write32)(struct bcma_device *core, u16 offset, u32 value);
-+#ifdef CONFIG_BCMA_BLOCKIO
-+	void (*block_read)(struct bcma_device *core, void *buffer,
-+			   size_t count, u16 offset, u8 reg_width);
-+	void (*block_write)(struct bcma_device *core, const void *buffer,
-+			    size_t count, u16 offset, u8 reg_width);
-+#endif
-+	/* Agent ops */
-+	u32 (*aread32)(struct bcma_device *core, u16 offset);
-+	void (*awrite32)(struct bcma_device *core, u16 offset, u32 value);
-+};
-+
-+/* Core manufacturers */
-+#define BCMA_MANUF_ARM			0x43B
-+#define BCMA_MANUF_MIPS			0x4A7
-+#define BCMA_MANUF_BCM			0x4BF
-+
-+/* Core class values. */
-+#define BCMA_CL_SIM			0x0
-+#define BCMA_CL_EROM			0x1
-+#define BCMA_CL_CORESIGHT		0x9
-+#define BCMA_CL_VERIF			0xB
-+#define BCMA_CL_OPTIMO			0xD
-+#define BCMA_CL_GEN			0xE
-+#define BCMA_CL_PRIMECELL		0xF
-+
-+/* Core-ID values. */
-+#define BCMA_CORE_OOB_ROUTER		0x367	/* Out of band */
-+#define BCMA_CORE_INVALID		0x700
-+#define BCMA_CORE_CHIPCOMMON		0x800
-+#define BCMA_CORE_ILINE20		0x801
-+#define BCMA_CORE_SRAM			0x802
-+#define BCMA_CORE_SDRAM			0x803
-+#define BCMA_CORE_PCI			0x804
-+#define BCMA_CORE_MIPS			0x805
-+#define BCMA_CORE_ETHERNET		0x806
-+#define BCMA_CORE_V90			0x807
-+#define BCMA_CORE_USB11_HOSTDEV		0x808
-+#define BCMA_CORE_ADSL			0x809
-+#define BCMA_CORE_ILINE100		0x80A
-+#define BCMA_CORE_IPSEC			0x80B
-+#define BCMA_CORE_UTOPIA		0x80C
-+#define BCMA_CORE_PCMCIA		0x80D
-+#define BCMA_CORE_INTERNAL_MEM		0x80E
-+#define BCMA_CORE_MEMC_SDRAM		0x80F
-+#define BCMA_CORE_OFDM			0x810
-+#define BCMA_CORE_EXTIF			0x811
-+#define BCMA_CORE_80211			0x812
-+#define BCMA_CORE_PHY_A			0x813
-+#define BCMA_CORE_PHY_B			0x814
-+#define BCMA_CORE_PHY_G			0x815
-+#define BCMA_CORE_MIPS_3302		0x816
-+#define BCMA_CORE_USB11_HOST		0x817
-+#define BCMA_CORE_USB11_DEV		0x818
-+#define BCMA_CORE_USB20_HOST		0x819
-+#define BCMA_CORE_USB20_DEV		0x81A
-+#define BCMA_CORE_SDIO_HOST		0x81B
-+#define BCMA_CORE_ROBOSWITCH		0x81C
-+#define BCMA_CORE_PARA_ATA		0x81D
-+#define BCMA_CORE_SATA_XORDMA		0x81E
-+#define BCMA_CORE_ETHERNET_GBIT		0x81F
-+#define BCMA_CORE_PCIE			0x820
-+#define BCMA_CORE_PHY_N			0x821
-+#define BCMA_CORE_SRAM_CTL		0x822
-+#define BCMA_CORE_MINI_MACPHY		0x823
-+#define BCMA_CORE_ARM_1176		0x824
-+#define BCMA_CORE_ARM_7TDMI		0x825
-+#define BCMA_CORE_PHY_LP		0x826
-+#define BCMA_CORE_PMU			0x827
-+#define BCMA_CORE_PHY_SSN		0x828
-+#define BCMA_CORE_SDIO_DEV		0x829
-+#define BCMA_CORE_ARM_CM3		0x82A
-+#define BCMA_CORE_PHY_HT		0x82B
-+#define BCMA_CORE_MIPS_74K		0x82C
-+#define BCMA_CORE_MAC_GBIT		0x82D
-+#define BCMA_CORE_DDR12_MEM_CTL		0x82E
-+#define BCMA_CORE_PCIE_RC		0x82F	/* PCIe Root Complex */
-+#define BCMA_CORE_OCP_OCP_BRIDGE	0x830
-+#define BCMA_CORE_SHARED_COMMON		0x831
-+#define BCMA_CORE_OCP_AHB_BRIDGE	0x832
-+#define BCMA_CORE_SPI_HOST		0x833
-+#define BCMA_CORE_I2S			0x834
-+#define BCMA_CORE_SDR_DDR1_MEM_CTL	0x835	/* SDR/DDR1 memory controller core */
-+#define BCMA_CORE_SHIM			0x837	/* SHIM component in ubus/6362 */
-+#define BCMA_CORE_DEFAULT		0xFFF
-+
-+#define BCMA_MAX_NR_CORES		16
-+
-+struct bcma_device {
-+	struct bcma_bus *bus;
-+	struct bcma_device_id id;
-+
-+	struct device dev;
-+	struct device *dma_dev;
-+
-+	unsigned int irq;
-+	bool dev_registered;
-+
-+	u8 core_index;
-+	u8 core_unit;
-+
-+	u32 addr;
-+	u32 wrap;
-+
-+	void __iomem *io_addr;
-+	void __iomem *io_wrap;
-+
-+	void *drvdata;
-+	struct list_head list;
-+};
-+
-+static inline void *bcma_get_drvdata(struct bcma_device *core)
-+{
-+	return core->drvdata;
-+}
-+static inline void bcma_set_drvdata(struct bcma_device *core, void *drvdata)
-+{
-+	core->drvdata = drvdata;
-+}
-+
-+struct bcma_driver {
-+	const char *name;
-+	const struct bcma_device_id *id_table;
-+
-+	int (*probe)(struct bcma_device *dev);
-+	void (*remove)(struct bcma_device *dev);
-+	int (*suspend)(struct bcma_device *dev);
-+	int (*resume)(struct bcma_device *dev);
-+	void (*shutdown)(struct bcma_device *dev);
-+
-+	struct device_driver drv;
-+};
-+extern
-+int __bcma_driver_register(struct bcma_driver *drv, struct module *owner);
-+#define bcma_driver_register(drv) \
-+	__bcma_driver_register(drv, THIS_MODULE)
-+
-+extern void bcma_driver_unregister(struct bcma_driver *drv);
-+
-+/* Set a fallback SPROM.
-+ * See kdoc at the function definition for complete documentation. */
-+extern int bcma_arch_register_fallback_sprom(
-+		int (*sprom_callback)(struct bcma_bus *bus,
-+		struct ssb_sprom *out));
-+
-+struct bcma_bus {
-+	/* The MMIO area. */
-+	void __iomem *mmio;
-+
-+	const struct bcma_host_ops *ops;
-+
-+	enum bcma_hosttype hosttype;
-+	union {
-+		/* Pointer to the PCI bus (only for BCMA_HOSTTYPE_PCI) */
-+		struct pci_dev *host_pci;
-+		/* Pointer to the SDIO device (only for BCMA_HOSTTYPE_SDIO) */
-+		struct sdio_func *host_sdio;
-+	};
-+
-+	struct bcma_chipinfo chipinfo;
-+
-+	struct bcma_device *mapped_core;
-+	struct list_head cores;
-+	u8 nr_cores;
-+	u8 init_done:1;
-+	u8 num;
-+
-+	struct bcma_drv_cc drv_cc;
-+	struct bcma_drv_pci drv_pci;
-+	struct bcma_drv_mips drv_mips;
-+
-+	/* We decided to share SPROM struct with SSB as long as we do not need
-+	 * any hacks for BCMA. This simplifies drivers code. */
-+	struct ssb_sprom sprom;
-+};
-+
-+static inline u32 bcma_read8(struct bcma_device *core, u16 offset)
-+{
-+	return core->bus->ops->read8(core, offset);
-+}
-+static inline u32 bcma_read16(struct bcma_device *core, u16 offset)
-+{
-+	return core->bus->ops->read16(core, offset);
-+}
-+static inline u32 bcma_read32(struct bcma_device *core, u16 offset)
-+{
-+	return core->bus->ops->read32(core, offset);
-+}
-+static inline
-+void bcma_write8(struct bcma_device *core, u16 offset, u32 value)
-+{
-+	core->bus->ops->write8(core, offset, value);
-+}
-+static inline
-+void bcma_write16(struct bcma_device *core, u16 offset, u32 value)
-+{
-+	core->bus->ops->write16(core, offset, value);
-+}
-+static inline
-+void bcma_write32(struct bcma_device *core, u16 offset, u32 value)
-+{
-+	core->bus->ops->write32(core, offset, value);
-+}
-+#ifdef CONFIG_BCMA_BLOCKIO
-+static inline void bcma_block_read(struct bcma_device *core, void *buffer,
-+				   size_t count, u16 offset, u8 reg_width)
-+{
-+	core->bus->ops->block_read(core, buffer, count, offset, reg_width);
-+}
-+static inline void bcma_block_write(struct bcma_device *core,
-+				    const void *buffer, size_t count,
-+				    u16 offset, u8 reg_width)
-+{
-+	core->bus->ops->block_write(core, buffer, count, offset, reg_width);
-+}
-+#endif
-+static inline u32 bcma_aread32(struct bcma_device *core, u16 offset)
-+{
-+	return core->bus->ops->aread32(core, offset);
-+}
-+static inline
-+void bcma_awrite32(struct bcma_device *core, u16 offset, u32 value)
-+{
-+	core->bus->ops->awrite32(core, offset, value);
-+}
-+
-+static inline void bcma_mask32(struct bcma_device *cc, u16 offset, u32 mask)
-+{
-+	bcma_write32(cc, offset, bcma_read32(cc, offset) & mask);
-+}
-+static inline void bcma_set32(struct bcma_device *cc, u16 offset, u32 set)
-+{
-+	bcma_write32(cc, offset, bcma_read32(cc, offset) | set);
-+}
-+static inline void bcma_maskset32(struct bcma_device *cc,
-+				  u16 offset, u32 mask, u32 set)
-+{
-+	bcma_write32(cc, offset, (bcma_read32(cc, offset) & mask) | set);
-+}
-+static inline void bcma_mask16(struct bcma_device *cc, u16 offset, u16 mask)
-+{
-+	bcma_write16(cc, offset, bcma_read16(cc, offset) & mask);
-+}
-+static inline void bcma_set16(struct bcma_device *cc, u16 offset, u16 set)
-+{
-+	bcma_write16(cc, offset, bcma_read16(cc, offset) | set);
-+}
-+static inline void bcma_maskset16(struct bcma_device *cc,
-+				  u16 offset, u16 mask, u16 set)
-+{
-+	bcma_write16(cc, offset, (bcma_read16(cc, offset) & mask) | set);
-+}
-+
-+extern struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid);
-+extern bool bcma_core_is_enabled(struct bcma_device *core);
-+extern void bcma_core_disable(struct bcma_device *core, u32 flags);
-+extern int bcma_core_enable(struct bcma_device *core, u32 flags);
-+extern void bcma_core_set_clockmode(struct bcma_device *core,
-+				    enum bcma_clkmode clkmode);
-+extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status,
-+			      bool on);
-+#define BCMA_DMA_TRANSLATION_MASK	0xC0000000
-+#define  BCMA_DMA_TRANSLATION_NONE	0x00000000
-+#define  BCMA_DMA_TRANSLATION_DMA32_CMT	0x40000000 /* Client Mode Translation for 32-bit DMA */
-+#define  BCMA_DMA_TRANSLATION_DMA64_CMT	0x80000000 /* Client Mode Translation for 64-bit DMA */
-+extern u32 bcma_core_dma_translation(struct bcma_device *core);
-+
-+#endif /* LINUX_BCMA_H_ */
---- /dev/null
-+++ b/include/linux/bcma/bcma_driver_chipcommon.h
-@@ -0,0 +1,415 @@
-+#ifndef LINUX_BCMA_DRIVER_CC_H_
-+#define LINUX_BCMA_DRIVER_CC_H_
-+
-+/** ChipCommon core registers. **/
-+#define BCMA_CC_ID			0x0000
-+#define  BCMA_CC_ID_ID			0x0000FFFF
-+#define  BCMA_CC_ID_ID_SHIFT		0
-+#define  BCMA_CC_ID_REV			0x000F0000
-+#define  BCMA_CC_ID_REV_SHIFT		16
-+#define  BCMA_CC_ID_PKG			0x00F00000
-+#define  BCMA_CC_ID_PKG_SHIFT		20
-+#define  BCMA_CC_ID_NRCORES		0x0F000000
-+#define  BCMA_CC_ID_NRCORES_SHIFT	24
-+#define  BCMA_CC_ID_TYPE		0xF0000000
-+#define  BCMA_CC_ID_TYPE_SHIFT		28
-+#define BCMA_CC_CAP			0x0004		/* Capabilities */
-+#define  BCMA_CC_CAP_NRUART		0x00000003	/* # of UARTs */
-+#define  BCMA_CC_CAP_MIPSEB		0x00000004	/* MIPS in BigEndian Mode */
-+#define  BCMA_CC_CAP_UARTCLK		0x00000018	/* UART clock select */
-+#define   BCMA_CC_CAP_UARTCLK_INT	0x00000008	/* UARTs are driven by internal divided clock */
-+#define  BCMA_CC_CAP_UARTGPIO		0x00000020	/* UARTs on GPIO 15-12 */
-+#define  BCMA_CC_CAP_EXTBUS		0x000000C0	/* External buses present */
-+#define  BCMA_CC_CAP_FLASHT		0x00000700	/* Flash Type */
-+#define   BCMA_CC_FLASHT_NONE		0x00000000	/* No flash */
-+#define   BCMA_CC_FLASHT_STSER		0x00000100	/* ST serial flash */
-+#define   BCMA_CC_FLASHT_ATSER		0x00000200	/* Atmel serial flash */
-+#define   BCMA_CC_FLASHT_NFLASH		0x00000200
-+#define	  BCMA_CC_FLASHT_PARA		0x00000700	/* Parallel flash */
-+#define  BCMA_CC_CAP_PLLT		0x00038000	/* PLL Type */
-+#define   BCMA_PLLTYPE_NONE		0x00000000
-+#define   BCMA_PLLTYPE_1		0x00010000	/* 48Mhz base, 3 dividers */
-+#define   BCMA_PLLTYPE_2		0x00020000	/* 48Mhz, 4 dividers */
-+#define   BCMA_PLLTYPE_3		0x00030000	/* 25Mhz, 2 dividers */
-+#define   BCMA_PLLTYPE_4		0x00008000	/* 48Mhz, 4 dividers */
-+#define   BCMA_PLLTYPE_5		0x00018000	/* 25Mhz, 4 dividers */
-+#define   BCMA_PLLTYPE_6		0x00028000	/* 100/200 or 120/240 only */
-+#define   BCMA_PLLTYPE_7		0x00038000	/* 25Mhz, 4 dividers */
-+#define  BCMA_CC_CAP_PCTL		0x00040000	/* Power Control */
-+#define  BCMA_CC_CAP_OTPS		0x00380000	/* OTP size */
-+#define  BCMA_CC_CAP_OTPS_SHIFT		19
-+#define  BCMA_CC_CAP_OTPS_BASE		5
-+#define  BCMA_CC_CAP_JTAGM		0x00400000	/* JTAG master present */
-+#define  BCMA_CC_CAP_BROM		0x00800000	/* Internal boot ROM active */
-+#define  BCMA_CC_CAP_64BIT		0x08000000	/* 64-bit Backplane */
-+#define  BCMA_CC_CAP_PMU		0x10000000	/* PMU available (rev >= 20) */
-+#define  BCMA_CC_CAP_ECI		0x20000000	/* ECI available (rev >= 20) */
-+#define  BCMA_CC_CAP_SPROM		0x40000000	/* SPROM present */
-+#define BCMA_CC_CORECTL			0x0008
-+#define  BCMA_CC_CORECTL_UARTCLK0	0x00000001	/* Drive UART with internal clock */
-+#define	 BCMA_CC_CORECTL_SE		0x00000002	/* sync clk out enable (corerev >= 3) */
-+#define  BCMA_CC_CORECTL_UARTCLKEN	0x00000008	/* UART clock enable (rev >= 21) */
-+#define BCMA_CC_BIST			0x000C
-+#define BCMA_CC_OTPS			0x0010		/* OTP status */
-+#define	 BCMA_CC_OTPS_PROGFAIL		0x80000000
-+#define	 BCMA_CC_OTPS_PROTECT		0x00000007
-+#define	 BCMA_CC_OTPS_HW_PROTECT	0x00000001
-+#define	 BCMA_CC_OTPS_SW_PROTECT	0x00000002
-+#define	 BCMA_CC_OTPS_CID_PROTECT	0x00000004
-+#define  BCMA_CC_OTPS_GU_PROG_IND	0x00000F00	/* General Use programmed indication */
-+#define  BCMA_CC_OTPS_GU_PROG_IND_SHIFT	8
-+#define  BCMA_CC_OTPS_GU_PROG_HW	0x00000100	/* HW region programmed */
-+#define BCMA_CC_OTPC			0x0014		/* OTP control */
-+#define	 BCMA_CC_OTPC_RECWAIT		0xFF000000
-+#define	 BCMA_CC_OTPC_PROGWAIT		0x00FFFF00
-+#define	 BCMA_CC_OTPC_PRW_SHIFT		8
-+#define	 BCMA_CC_OTPC_MAXFAIL		0x00000038
-+#define	 BCMA_CC_OTPC_VSEL		0x00000006
-+#define	 BCMA_CC_OTPC_SELVL		0x00000001
-+#define BCMA_CC_OTPP			0x0018		/* OTP prog */
-+#define	 BCMA_CC_OTPP_COL		0x000000FF
-+#define	 BCMA_CC_OTPP_ROW		0x0000FF00
-+#define	 BCMA_CC_OTPP_ROW_SHIFT		8
-+#define	 BCMA_CC_OTPP_READERR		0x10000000
-+#define	 BCMA_CC_OTPP_VALUE		0x20000000
-+#define	 BCMA_CC_OTPP_READ		0x40000000
-+#define	 BCMA_CC_OTPP_START		0x80000000
-+#define	 BCMA_CC_OTPP_BUSY		0x80000000
-+#define BCMA_CC_OTPL			0x001C		/* OTP layout */
-+#define  BCMA_CC_OTPL_GURGN_OFFSET	0x00000FFF	/* offset of general use region */
-+#define BCMA_CC_IRQSTAT			0x0020
-+#define BCMA_CC_IRQMASK			0x0024
-+#define	 BCMA_CC_IRQ_GPIO		0x00000001	/* gpio intr */
-+#define	 BCMA_CC_IRQ_EXT		0x00000002	/* ro: ext intr pin (corerev >= 3) */
-+#define	 BCMA_CC_IRQ_WDRESET		0x80000000	/* watchdog reset occurred */
-+#define BCMA_CC_CHIPCTL			0x0028		/* Rev >= 11 only */
-+#define BCMA_CC_CHIPSTAT		0x002C		/* Rev >= 11 only */
-+#define  BCMA_CC_CHIPST_4313_SPROM_PRESENT	1
-+#define  BCMA_CC_CHIPST_4313_OTP_PRESENT	2
-+#define  BCMA_CC_CHIPST_4331_SPROM_PRESENT	2
-+#define  BCMA_CC_CHIPST_4331_OTP_PRESENT	4
-+#define BCMA_CC_JCMD			0x0030		/* Rev >= 10 only */
-+#define  BCMA_CC_JCMD_START		0x80000000
-+#define  BCMA_CC_JCMD_BUSY		0x80000000
-+#define  BCMA_CC_JCMD_PAUSE		0x40000000
-+#define  BCMA_CC_JCMD0_ACC_MASK		0x0000F000
-+#define  BCMA_CC_JCMD0_ACC_IRDR		0x00000000
-+#define  BCMA_CC_JCMD0_ACC_DR		0x00001000
-+#define  BCMA_CC_JCMD0_ACC_IR		0x00002000
-+#define  BCMA_CC_JCMD0_ACC_RESET	0x00003000
-+#define  BCMA_CC_JCMD0_ACC_IRPDR	0x00004000
-+#define  BCMA_CC_JCMD0_ACC_PDR		0x00005000
-+#define  BCMA_CC_JCMD0_IRW_MASK		0x00000F00
-+#define  BCMA_CC_JCMD_ACC_MASK		0x000F0000	/* Changes for corerev 11 */
-+#define  BCMA_CC_JCMD_ACC_IRDR		0x00000000
-+#define  BCMA_CC_JCMD_ACC_DR		0x00010000
-+#define  BCMA_CC_JCMD_ACC_IR		0x00020000
-+#define  BCMA_CC_JCMD_ACC_RESET		0x00030000
-+#define  BCMA_CC_JCMD_ACC_IRPDR		0x00040000
-+#define  BCMA_CC_JCMD_ACC_PDR		0x00050000
-+#define  BCMA_CC_JCMD_IRW_MASK		0x00001F00
-+#define  BCMA_CC_JCMD_IRW_SHIFT		8
-+#define  BCMA_CC_JCMD_DRW_MASK		0x0000003F
-+#define BCMA_CC_JIR			0x0034		/* Rev >= 10 only */
-+#define BCMA_CC_JDR			0x0038		/* Rev >= 10 only */
-+#define BCMA_CC_JCTL			0x003C		/* Rev >= 10 only */
-+#define  BCMA_CC_JCTL_FORCE_CLK		4		/* Force clock */
-+#define  BCMA_CC_JCTL_EXT_EN		2		/* Enable external targets */
-+#define  BCMA_CC_JCTL_EN		1		/* Enable Jtag master */
-+#define BCMA_CC_FLASHCTL		0x0040
-+#define  BCMA_CC_FLASHCTL_START		0x80000000
-+#define  BCMA_CC_FLASHCTL_BUSY		BCMA_CC_FLASHCTL_START
-+#define BCMA_CC_FLASHADDR		0x0044
-+#define BCMA_CC_FLASHDATA		0x0048
-+#define BCMA_CC_BCAST_ADDR		0x0050
-+#define BCMA_CC_BCAST_DATA		0x0054
-+#define BCMA_CC_GPIOPULLUP		0x0058		/* Rev >= 20 only */
-+#define BCMA_CC_GPIOPULLDOWN		0x005C		/* Rev >= 20 only */
-+#define BCMA_CC_GPIOIN			0x0060
-+#define BCMA_CC_GPIOOUT			0x0064
-+#define BCMA_CC_GPIOOUTEN		0x0068
-+#define BCMA_CC_GPIOCTL			0x006C
-+#define BCMA_CC_GPIOPOL			0x0070
-+#define BCMA_CC_GPIOIRQ			0x0074
-+#define BCMA_CC_WATCHDOG		0x0080
-+#define BCMA_CC_GPIOTIMER		0x0088		/* LED powersave (corerev >= 16) */
-+#define  BCMA_CC_GPIOTIMER_OFFTIME	0x0000FFFF
-+#define  BCMA_CC_GPIOTIMER_OFFTIME_SHIFT	0
-+#define  BCMA_CC_GPIOTIMER_ONTIME	0xFFFF0000
-+#define  BCMA_CC_GPIOTIMER_ONTIME_SHIFT	16
-+#define BCMA_CC_GPIOTOUTM		0x008C		/* LED powersave (corerev >= 16) */
-+#define BCMA_CC_CLOCK_N			0x0090
-+#define BCMA_CC_CLOCK_SB		0x0094
-+#define BCMA_CC_CLOCK_PCI		0x0098
-+#define BCMA_CC_CLOCK_M2		0x009C
-+#define BCMA_CC_CLOCK_MIPS		0x00A0
-+#define BCMA_CC_CLKDIV			0x00A4		/* Rev >= 3 only */
-+#define	 BCMA_CC_CLKDIV_SFLASH		0x0F000000
-+#define	 BCMA_CC_CLKDIV_SFLASH_SHIFT	24
-+#define	 BCMA_CC_CLKDIV_OTP		0x000F0000
-+#define	 BCMA_CC_CLKDIV_OTP_SHIFT	16
-+#define	 BCMA_CC_CLKDIV_JTAG		0x00000F00
-+#define	 BCMA_CC_CLKDIV_JTAG_SHIFT	8
-+#define	 BCMA_CC_CLKDIV_UART		0x000000FF
-+#define BCMA_CC_CAP_EXT			0x00AC		/* Capabilities */
-+#define BCMA_CC_PLLONDELAY		0x00B0		/* Rev >= 4 only */
-+#define BCMA_CC_FREFSELDELAY		0x00B4		/* Rev >= 4 only */
-+#define BCMA_CC_SLOWCLKCTL		0x00B8		/* 6 <= Rev <= 9 only */
-+#define  BCMA_CC_SLOWCLKCTL_SRC		0x00000007	/* slow clock source mask */
-+#define	  BCMA_CC_SLOWCLKCTL_SRC_LPO	0x00000000	/* source of slow clock is LPO */
-+#define   BCMA_CC_SLOWCLKCTL_SRC_XTAL	0x00000001	/* source of slow clock is crystal */
-+#define	  BCMA_CC_SLOECLKCTL_SRC_PCI	0x00000002	/* source of slow clock is PCI */
-+#define  BCMA_CC_SLOWCLKCTL_LPOFREQ	0x00000200	/* LPOFreqSel, 1: 160Khz, 0: 32KHz */
-+#define  BCMA_CC_SLOWCLKCTL_LPOPD	0x00000400	/* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */
-+#define  BCMA_CC_SLOWCLKCTL_FSLOW	0x00000800	/* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */
-+#define  BCMA_CC_SLOWCLKCTL_IPLL	0x00001000	/* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */
-+#define  BCMA_CC_SLOWCLKCTL_ENXTAL	0x00002000	/* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */
-+#define  BCMA_CC_SLOWCLKCTL_XTALPU	0x00004000	/* XtalPU (RO), 1/0: crystal running/disabled */
-+#define  BCMA_CC_SLOWCLKCTL_CLKDIV	0xFFFF0000	/* ClockDivider (SlowClk = 1/(4+divisor)) */
-+#define  BCMA_CC_SLOWCLKCTL_CLKDIV_SHIFT	16
-+#define BCMA_CC_SYSCLKCTL		0x00C0		/* Rev >= 3 only */
-+#define	 BCMA_CC_SYSCLKCTL_IDLPEN	0x00000001	/* ILPen: Enable Idle Low Power */
-+#define	 BCMA_CC_SYSCLKCTL_ALPEN	0x00000002	/* ALPen: Enable Active Low Power */
-+#define	 BCMA_CC_SYSCLKCTL_PLLEN	0x00000004	/* ForcePLLOn */
-+#define	 BCMA_CC_SYSCLKCTL_FORCEALP	0x00000008	/* Force ALP (or HT if ALPen is not set */
-+#define	 BCMA_CC_SYSCLKCTL_FORCEHT	0x00000010	/* Force HT */
-+#define  BCMA_CC_SYSCLKCTL_CLKDIV	0xFFFF0000	/* ClkDiv  (ILP = 1/(4+divisor)) */
-+#define  BCMA_CC_SYSCLKCTL_CLKDIV_SHIFT	16
-+#define BCMA_CC_CLKSTSTR		0x00C4		/* Rev >= 3 only */
-+#define BCMA_CC_EROM			0x00FC
-+#define BCMA_CC_PCMCIA_CFG		0x0100
-+#define BCMA_CC_PCMCIA_MEMWAIT		0x0104
-+#define BCMA_CC_PCMCIA_ATTRWAIT		0x0108
-+#define BCMA_CC_PCMCIA_IOWAIT		0x010C
-+#define BCMA_CC_IDE_CFG			0x0110
-+#define BCMA_CC_IDE_MEMWAIT		0x0114
-+#define BCMA_CC_IDE_ATTRWAIT		0x0118
-+#define BCMA_CC_IDE_IOWAIT		0x011C
-+#define BCMA_CC_PROG_CFG		0x0120
-+#define BCMA_CC_PROG_WAITCNT		0x0124
-+#define BCMA_CC_FLASH_CFG		0x0128
-+#define  BCMA_CC_FLASH_CFG_DS		0x0010	/* Data size, 0=8bit, 1=16bit */
-+#define BCMA_CC_FLASH_WAITCNT		0x012C
-+#define BCMA_CC_SROM_CONTROL		0x0190
-+#define  BCMA_CC_SROM_CONTROL_START	0x80000000
-+#define  BCMA_CC_SROM_CONTROL_BUSY	0x80000000
-+#define  BCMA_CC_SROM_CONTROL_OPCODE	0x60000000
-+#define  BCMA_CC_SROM_CONTROL_OP_READ	0x00000000
-+#define  BCMA_CC_SROM_CONTROL_OP_WRITE	0x20000000
-+#define  BCMA_CC_SROM_CONTROL_OP_WRDIS	0x40000000
-+#define  BCMA_CC_SROM_CONTROL_OP_WREN	0x60000000
-+#define  BCMA_CC_SROM_CONTROL_OTPSEL	0x00000010
-+#define  BCMA_CC_SROM_CONTROL_LOCK	0x00000008
-+#define  BCMA_CC_SROM_CONTROL_SIZE_MASK	0x00000006
-+#define  BCMA_CC_SROM_CONTROL_SIZE_1K	0x00000000
-+#define  BCMA_CC_SROM_CONTROL_SIZE_4K	0x00000002
-+#define  BCMA_CC_SROM_CONTROL_SIZE_16K	0x00000004
-+#define  BCMA_CC_SROM_CONTROL_SIZE_SHIFT	1
-+#define  BCMA_CC_SROM_CONTROL_PRESENT	0x00000001
-+/* 0x1E0 is defined as shared BCMA_CLKCTLST */
-+#define BCMA_CC_HW_WORKAROUND		0x01E4 /* Hardware workaround (rev >= 20) */
-+#define BCMA_CC_UART0_DATA		0x0300
-+#define BCMA_CC_UART0_IMR		0x0304
-+#define BCMA_CC_UART0_FCR		0x0308
-+#define BCMA_CC_UART0_LCR		0x030C
-+#define BCMA_CC_UART0_MCR		0x0310
-+#define BCMA_CC_UART0_LSR		0x0314
-+#define BCMA_CC_UART0_MSR		0x0318
-+#define BCMA_CC_UART0_SCRATCH		0x031C
-+#define BCMA_CC_UART1_DATA		0x0400
-+#define BCMA_CC_UART1_IMR		0x0404
-+#define BCMA_CC_UART1_FCR		0x0408
-+#define BCMA_CC_UART1_LCR		0x040C
-+#define BCMA_CC_UART1_MCR		0x0410
-+#define BCMA_CC_UART1_LSR		0x0414
-+#define BCMA_CC_UART1_MSR		0x0418
-+#define BCMA_CC_UART1_SCRATCH		0x041C
-+/* PMU registers (rev >= 20) */
-+#define BCMA_CC_PMU_CTL			0x0600 /* PMU control */
-+#define  BCMA_CC_PMU_CTL_ILP_DIV	0xFFFF0000 /* ILP div mask */
-+#define  BCMA_CC_PMU_CTL_ILP_DIV_SHIFT	16
-+#define  BCMA_CC_PMU_CTL_PLL_UPD	0x00000400
-+#define  BCMA_CC_PMU_CTL_NOILPONW	0x00000200 /* No ILP on wait */
-+#define  BCMA_CC_PMU_CTL_HTREQEN	0x00000100 /* HT req enable */
-+#define  BCMA_CC_PMU_CTL_ALPREQEN	0x00000080 /* ALP req enable */
-+#define  BCMA_CC_PMU_CTL_XTALFREQ	0x0000007C /* Crystal freq */
-+#define  BCMA_CC_PMU_CTL_XTALFREQ_SHIFT	2
-+#define  BCMA_CC_PMU_CTL_ILPDIVEN	0x00000002 /* ILP div enable */
-+#define  BCMA_CC_PMU_CTL_LPOSEL		0x00000001 /* LPO sel */
-+#define BCMA_CC_PMU_CAP			0x0604 /* PMU capabilities */
-+#define  BCMA_CC_PMU_CAP_REVISION	0x000000FF /* Revision mask */
-+#define BCMA_CC_PMU_STAT		0x0608 /* PMU status */
-+#define  BCMA_CC_PMU_STAT_INTPEND	0x00000040 /* Interrupt pending */
-+#define  BCMA_CC_PMU_STAT_SBCLKST	0x00000030 /* Backplane clock status? */
-+#define  BCMA_CC_PMU_STAT_HAVEALP	0x00000008 /* ALP available */
-+#define  BCMA_CC_PMU_STAT_HAVEHT	0x00000004 /* HT available */
-+#define  BCMA_CC_PMU_STAT_RESINIT	0x00000003 /* Res init */
-+#define BCMA_CC_PMU_RES_STAT		0x060C /* PMU res status */
-+#define BCMA_CC_PMU_RES_PEND		0x0610 /* PMU res pending */
-+#define BCMA_CC_PMU_TIMER		0x0614 /* PMU timer */
-+#define BCMA_CC_PMU_MINRES_MSK		0x0618 /* PMU min res mask */
-+#define BCMA_CC_PMU_MAXRES_MSK		0x061C /* PMU max res mask */
-+#define BCMA_CC_PMU_RES_TABSEL		0x0620 /* PMU res table sel */
-+#define BCMA_CC_PMU_RES_DEPMSK		0x0624 /* PMU res dep mask */
-+#define BCMA_CC_PMU_RES_UPDNTM		0x0628 /* PMU res updown timer */
-+#define BCMA_CC_PMU_RES_TIMER		0x062C /* PMU res timer */
-+#define BCMA_CC_PMU_CLKSTRETCH		0x0630 /* PMU clockstretch */
-+#define BCMA_CC_PMU_WATCHDOG		0x0634 /* PMU watchdog */
-+#define BCMA_CC_PMU_RES_REQTS		0x0640 /* PMU res req timer sel */
-+#define BCMA_CC_PMU_RES_REQT		0x0644 /* PMU res req timer */
-+#define BCMA_CC_PMU_RES_REQM		0x0648 /* PMU res req mask */
-+#define BCMA_CC_CHIPCTL_ADDR		0x0650
-+#define BCMA_CC_CHIPCTL_DATA		0x0654
-+#define BCMA_CC_REGCTL_ADDR		0x0658
-+#define BCMA_CC_REGCTL_DATA		0x065C
-+#define BCMA_CC_PLLCTL_ADDR		0x0660
-+#define BCMA_CC_PLLCTL_DATA		0x0664
-+#define BCMA_CC_SPROM			0x0800 /* SPROM beginning */
-+
-+/* Divider allocation in 4716/47162/5356 */
-+#define BCMA_CC_PMU5_MAINPLL_CPU	1
-+#define BCMA_CC_PMU5_MAINPLL_MEM	2
-+#define BCMA_CC_PMU5_MAINPLL_SSB	3
-+
-+/* PLL usage in 4716/47162 */
-+#define BCMA_CC_PMU4716_MAINPLL_PLL0	12
-+
-+/* PLL usage in 5356/5357 */
-+#define BCMA_CC_PMU5356_MAINPLL_PLL0	0
-+#define BCMA_CC_PMU5357_MAINPLL_PLL0	0
-+
-+/* 4706 PMU */
-+#define BCMA_CC_PMU4706_MAINPLL_PLL0	0
-+
-+/* ALP clock on pre-PMU chips */
-+#define BCMA_CC_PMU_ALP_CLOCK		20000000
-+/* HT clock for systems with PMU-enabled chipcommon */
-+#define BCMA_CC_PMU_HT_CLOCK		80000000
-+
-+/* PMU rev 5 (& 6) */
-+#define BCMA_CC_PPL_P1P2_OFF		0
-+#define BCMA_CC_PPL_P1_MASK		0x0f000000
-+#define BCMA_CC_PPL_P1_SHIFT		24
-+#define BCMA_CC_PPL_P2_MASK		0x00f00000
-+#define BCMA_CC_PPL_P2_SHIFT		20
-+#define BCMA_CC_PPL_M14_OFF		1
-+#define BCMA_CC_PPL_MDIV_MASK		0x000000ff
-+#define BCMA_CC_PPL_MDIV_WIDTH		8
-+#define BCMA_CC_PPL_NM5_OFF		2
-+#define BCMA_CC_PPL_NDIV_MASK		0xfff00000
-+#define BCMA_CC_PPL_NDIV_SHIFT		20
-+#define BCMA_CC_PPL_FMAB_OFF		3
-+#define BCMA_CC_PPL_MRAT_MASK		0xf0000000
-+#define BCMA_CC_PPL_MRAT_SHIFT		28
-+#define BCMA_CC_PPL_ABRAT_MASK		0x08000000
-+#define BCMA_CC_PPL_ABRAT_SHIFT		27
-+#define BCMA_CC_PPL_FDIV_MASK		0x07ffffff
-+#define BCMA_CC_PPL_PLLCTL_OFF		4
-+#define BCMA_CC_PPL_PCHI_OFF		5
-+#define BCMA_CC_PPL_PCHI_MASK		0x0000003f
-+
-+/* BCM4331 ChipControl numbers. */
-+#define BCMA_CHIPCTL_4331_BT_COEXIST		BIT(0)	/* 0 disable */
-+#define BCMA_CHIPCTL_4331_SECI			BIT(1)	/* 0 SECI is disabled (JATG functional) */
-+#define BCMA_CHIPCTL_4331_EXT_LNA		BIT(2)	/* 0 disable */
-+#define BCMA_CHIPCTL_4331_SPROM_GPIO13_15	BIT(3)	/* sprom/gpio13-15 mux */
-+#define BCMA_CHIPCTL_4331_EXTPA_EN		BIT(4)	/* 0 ext pa disable, 1 ext pa enabled */
-+#define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS	BIT(5)	/* set drive out GPIO_CLK on sprom_cs pin */
-+#define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS	BIT(6)	/* use sprom_cs pin as PCIE mdio interface */
-+#define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5	BIT(7)	/* aband extpa will be at gpio2/5 and sprom_dout */
-+#define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN	BIT(8)	/* override core control on pipe_AuxClkEnable */
-+#define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN	BIT(9)	/* override core control on pipe_AuxPowerDown */
-+#define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN		BIT(10)	/* pcie_auxclkenable */
-+#define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN	BIT(11)	/* pcie_pipe_pllpowerdown */
-+#define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4	BIT(16)	/* enable bt_shd0 at gpio4 */
-+#define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5	BIT(17)	/* enable bt_shd1 at gpio5 */
-+
-+/* Data for the PMU, if available.
-+ * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
-+ */
-+struct bcma_chipcommon_pmu {
-+	u8 rev;			/* PMU revision */
-+	u32 crystalfreq;	/* The active crystal frequency (in kHz) */
-+};
-+
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+struct bcma_pflash {
-+	u8 buswidth;
-+	u32 window;
-+	u32 window_size;
-+};
-+
-+struct bcma_serial_port {
-+	void *regs;
-+	unsigned long clockspeed;
-+	unsigned int irq;
-+	unsigned int baud_base;
-+	unsigned int reg_shift;
-+};
-+#endif /* CONFIG_BCMA_DRIVER_MIPS */
-+
-+struct bcma_drv_cc {
-+	struct bcma_device *core;
-+	u32 status;
-+	u32 capabilities;
-+	u32 capabilities_ext;
-+	u8 setup_done:1;
-+	/* Fast Powerup Delay constant */
-+	u16 fast_pwrup_delay;
-+	struct bcma_chipcommon_pmu pmu;
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+	struct bcma_pflash pflash;
-+
-+	int nr_serial_ports;
-+	struct bcma_serial_port serial_ports[4];
-+#endif /* CONFIG_BCMA_DRIVER_MIPS */
-+};
-+
-+/* Register access */
-+#define bcma_cc_read32(cc, offset) \
-+	bcma_read32((cc)->core, offset)
-+#define bcma_cc_write32(cc, offset, val) \
-+	bcma_write32((cc)->core, offset, val)
-+
-+#define bcma_cc_mask32(cc, offset, mask) \
-+	bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) & (mask))
-+#define bcma_cc_set32(cc, offset, set) \
-+	bcma_cc_write32(cc, offset, bcma_cc_read32(cc, offset) | (set))
-+#define bcma_cc_maskset32(cc, offset, mask, set) \
-+	bcma_cc_write32(cc, offset, (bcma_cc_read32(cc, offset) & (mask)) | (set))
-+
-+extern void bcma_core_chipcommon_init(struct bcma_drv_cc *cc);
-+
-+extern void bcma_chipco_suspend(struct bcma_drv_cc *cc);
-+extern void bcma_chipco_resume(struct bcma_drv_cc *cc);
-+
-+void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable);
-+
-+extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc,
-+					  u32 ticks);
-+
-+void bcma_chipco_irq_mask(struct bcma_drv_cc *cc, u32 mask, u32 value);
-+
-+u32 bcma_chipco_irq_status(struct bcma_drv_cc *cc, u32 mask);
-+
-+/* Chipcommon GPIO pin access. */
-+u32 bcma_chipco_gpio_in(struct bcma_drv_cc *cc, u32 mask);
-+u32 bcma_chipco_gpio_out(struct bcma_drv_cc *cc, u32 mask, u32 value);
-+u32 bcma_chipco_gpio_outen(struct bcma_drv_cc *cc, u32 mask, u32 value);
-+u32 bcma_chipco_gpio_control(struct bcma_drv_cc *cc, u32 mask, u32 value);
-+u32 bcma_chipco_gpio_intmask(struct bcma_drv_cc *cc, u32 mask, u32 value);
-+u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value);
-+
-+/* PMU support */
-+extern void bcma_pmu_init(struct bcma_drv_cc *cc);
-+
-+extern void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset,
-+				  u32 value);
-+extern void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset,
-+				    u32 mask, u32 set);
-+extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
-+					u32 offset, u32 mask, u32 set);
-+extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc,
-+				       u32 offset, u32 mask, u32 set);
-+
-+#endif /* LINUX_BCMA_DRIVER_CC_H_ */
---- /dev/null
-+++ b/include/linux/bcma/bcma_driver_pci.h
-@@ -0,0 +1,214 @@
-+#ifndef LINUX_BCMA_DRIVER_PCI_H_
-+#define LINUX_BCMA_DRIVER_PCI_H_
-+
-+#include <linux/types.h>
-+
-+struct pci_dev;
-+
-+/** PCI core registers. **/
-+#define BCMA_CORE_PCI_CTL			0x0000	/* PCI Control */
-+#define  BCMA_CORE_PCI_CTL_RST_OE		0x00000001 /* PCI_RESET Output Enable */
-+#define  BCMA_CORE_PCI_CTL_RST			0x00000002 /* PCI_RESET driven out to pin */
-+#define  BCMA_CORE_PCI_CTL_CLK_OE		0x00000004 /* Clock gate Output Enable */
-+#define  BCMA_CORE_PCI_CTL_CLK			0x00000008 /* Gate for clock driven out to pin */
-+#define BCMA_CORE_PCI_ARBCTL			0x0010	/* PCI Arbiter Control */
-+#define  BCMA_CORE_PCI_ARBCTL_INTERN		0x00000001 /* Use internal arbiter */
-+#define  BCMA_CORE_PCI_ARBCTL_EXTERN		0x00000002 /* Use external arbiter */
-+#define  BCMA_CORE_PCI_ARBCTL_PARKID		0x00000006 /* Mask, selects which agent is parked on an idle bus */
-+#define   BCMA_CORE_PCI_ARBCTL_PARKID_LAST	0x00000000 /* Last requestor */
-+#define   BCMA_CORE_PCI_ARBCTL_PARKID_4710	0x00000002 /* 4710 */
-+#define   BCMA_CORE_PCI_ARBCTL_PARKID_EXT0	0x00000004 /* External requestor 0 */
-+#define   BCMA_CORE_PCI_ARBCTL_PARKID_EXT1	0x00000006 /* External requestor 1 */
-+#define BCMA_CORE_PCI_ISTAT			0x0020	/* Interrupt status */
-+#define  BCMA_CORE_PCI_ISTAT_INTA		0x00000001 /* PCI INTA# */
-+#define  BCMA_CORE_PCI_ISTAT_INTB		0x00000002 /* PCI INTB# */
-+#define  BCMA_CORE_PCI_ISTAT_SERR		0x00000004 /* PCI SERR# (write to clear) */
-+#define  BCMA_CORE_PCI_ISTAT_PERR		0x00000008 /* PCI PERR# (write to clear) */
-+#define  BCMA_CORE_PCI_ISTAT_PME		0x00000010 /* PCI PME# */
-+#define BCMA_CORE_PCI_IMASK			0x0024	/* Interrupt mask */
-+#define  BCMA_CORE_PCI_IMASK_INTA		0x00000001 /* PCI INTA# */
-+#define  BCMA_CORE_PCI_IMASK_INTB		0x00000002 /* PCI INTB# */
-+#define  BCMA_CORE_PCI_IMASK_SERR		0x00000004 /* PCI SERR# */
-+#define  BCMA_CORE_PCI_IMASK_PERR		0x00000008 /* PCI PERR# */
-+#define  BCMA_CORE_PCI_IMASK_PME		0x00000010 /* PCI PME# */
-+#define BCMA_CORE_PCI_MBOX			0x0028	/* Backplane to PCI Mailbox */
-+#define  BCMA_CORE_PCI_MBOX_F0_0		0x00000100 /* PCI function 0, INT 0 */
-+#define  BCMA_CORE_PCI_MBOX_F0_1		0x00000200 /* PCI function 0, INT 1 */
-+#define  BCMA_CORE_PCI_MBOX_F1_0		0x00000400 /* PCI function 1, INT 0 */
-+#define  BCMA_CORE_PCI_MBOX_F1_1		0x00000800 /* PCI function 1, INT 1 */
-+#define  BCMA_CORE_PCI_MBOX_F2_0		0x00001000 /* PCI function 2, INT 0 */
-+#define  BCMA_CORE_PCI_MBOX_F2_1		0x00002000 /* PCI function 2, INT 1 */
-+#define  BCMA_CORE_PCI_MBOX_F3_0		0x00004000 /* PCI function 3, INT 0 */
-+#define  BCMA_CORE_PCI_MBOX_F3_1		0x00008000 /* PCI function 3, INT 1 */
-+#define BCMA_CORE_PCI_BCAST_ADDR		0x0050	/* Backplane Broadcast Address */
-+#define  BCMA_CORE_PCI_BCAST_ADDR_MASK		0x000000FF
-+#define BCMA_CORE_PCI_BCAST_DATA		0x0054	/* Backplane Broadcast Data */
-+#define BCMA_CORE_PCI_GPIO_IN			0x0060	/* rev >= 2 only */
-+#define BCMA_CORE_PCI_GPIO_OUT			0x0064	/* rev >= 2 only */
-+#define BCMA_CORE_PCI_GPIO_ENABLE		0x0068	/* rev >= 2 only */
-+#define BCMA_CORE_PCI_GPIO_CTL			0x006C	/* rev >= 2 only */
-+#define BCMA_CORE_PCI_SBTOPCI0			0x0100	/* Backplane to PCI translation 0 (sbtopci0) */
-+#define  BCMA_CORE_PCI_SBTOPCI0_MASK		0xFC000000
-+#define BCMA_CORE_PCI_SBTOPCI1			0x0104	/* Backplane to PCI translation 1 (sbtopci1) */
-+#define  BCMA_CORE_PCI_SBTOPCI1_MASK		0xFC000000
-+#define BCMA_CORE_PCI_SBTOPCI2			0x0108	/* Backplane to PCI translation 2 (sbtopci2) */
-+#define  BCMA_CORE_PCI_SBTOPCI2_MASK		0xC0000000
-+#define BCMA_CORE_PCI_CONFIG_ADDR		0x0120	/* pcie config space access */
-+#define BCMA_CORE_PCI_CONFIG_DATA		0x0124	/* pcie config space access */
-+#define BCMA_CORE_PCI_MDIO_CONTROL		0x0128	/* controls the mdio access */
-+#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_MASK	0x7f	/* clock to be used on MDIO */
-+#define  BCMA_CORE_PCI_MDIOCTL_DIVISOR_VAL	0x2
-+#define  BCMA_CORE_PCI_MDIOCTL_PREAM_EN		0x80	/* Enable preamble sequnce */
-+#define  BCMA_CORE_PCI_MDIOCTL_ACCESS_DONE	0x100	/* Tranaction complete */
-+#define BCMA_CORE_PCI_MDIO_DATA			0x012c	/* Data to the mdio access */
-+#define  BCMA_CORE_PCI_MDIODATA_MASK		0x0000ffff /* data 2 bytes */
-+#define  BCMA_CORE_PCI_MDIODATA_TA		0x00020000 /* Turnaround */
-+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF_OLD	18	/* Regaddr shift (rev < 10) */
-+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK_OLD	0x003c0000 /* Regaddr Mask (rev < 10) */
-+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF_OLD	22	/* Physmedia devaddr shift (rev < 10) */
-+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK_OLD	0x0fc00000 /* Physmedia devaddr Mask (rev < 10) */
-+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_SHF	18	/* Regaddr shift */
-+#define  BCMA_CORE_PCI_MDIODATA_REGADDR_MASK	0x007c0000 /* Regaddr Mask */
-+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_SHF	23	/* Physmedia devaddr shift */
-+#define  BCMA_CORE_PCI_MDIODATA_DEVADDR_MASK	0x0f800000 /* Physmedia devaddr Mask */
-+#define  BCMA_CORE_PCI_MDIODATA_WRITE		0x10000000 /* write Transaction */
-+#define  BCMA_CORE_PCI_MDIODATA_READ		0x20000000 /* Read Transaction */
-+#define  BCMA_CORE_PCI_MDIODATA_START		0x40000000 /* start of Transaction */
-+#define  BCMA_CORE_PCI_MDIODATA_DEV_ADDR	0x0	/* dev address for serdes */
-+#define  BCMA_CORE_PCI_MDIODATA_BLK_ADDR	0x1F	/* blk address for serdes */
-+#define  BCMA_CORE_PCI_MDIODATA_DEV_PLL		0x1d	/* SERDES PLL Dev */
-+#define  BCMA_CORE_PCI_MDIODATA_DEV_TX		0x1e	/* SERDES TX Dev */
-+#define  BCMA_CORE_PCI_MDIODATA_DEV_RX		0x1f	/* SERDES RX Dev */
-+#define BCMA_CORE_PCI_PCIEIND_ADDR		0x0130	/* indirect access to the internal register */
-+#define BCMA_CORE_PCI_PCIEIND_DATA		0x0134	/* Data to/from the internal regsiter */
-+#define BCMA_CORE_PCI_CLKREQENCTRL		0x0138	/*  >= rev 6, Clkreq rdma control */
-+#define BCMA_CORE_PCI_PCICFG0			0x0400	/* PCI config space 0 (rev >= 8) */
-+#define BCMA_CORE_PCI_PCICFG1			0x0500	/* PCI config space 1 (rev >= 8) */
-+#define BCMA_CORE_PCI_PCICFG2			0x0600	/* PCI config space 2 (rev >= 8) */
-+#define BCMA_CORE_PCI_PCICFG3			0x0700	/* PCI config space 3 (rev >= 8) */
-+#define BCMA_CORE_PCI_SPROM(wordoffset)		(0x0800 + ((wordoffset) * 2)) /* SPROM shadow area (72 bytes) */
-+
-+/* SBtoPCIx */
-+#define BCMA_CORE_PCI_SBTOPCI_MEM		0x00000000
-+#define BCMA_CORE_PCI_SBTOPCI_IO		0x00000001
-+#define BCMA_CORE_PCI_SBTOPCI_CFG0		0x00000002
-+#define BCMA_CORE_PCI_SBTOPCI_CFG1		0x00000003
-+#define BCMA_CORE_PCI_SBTOPCI_PREF		0x00000004 /* Prefetch enable */
-+#define BCMA_CORE_PCI_SBTOPCI_BURST		0x00000008 /* Burst enable */
-+#define BCMA_CORE_PCI_SBTOPCI_MRM		0x00000020 /* Memory Read Multiple */
-+#define BCMA_CORE_PCI_SBTOPCI_RC		0x00000030 /* Read Command mask (rev >= 11) */
-+#define  BCMA_CORE_PCI_SBTOPCI_RC_READ		0x00000000 /* Memory read */
-+#define  BCMA_CORE_PCI_SBTOPCI_RC_READL		0x00000010 /* Memory read line */
-+#define  BCMA_CORE_PCI_SBTOPCI_RC_READM		0x00000020 /* Memory read multiple */
-+
-+/* PCIE protocol PHY diagnostic registers */
-+#define BCMA_CORE_PCI_PLP_MODEREG		0x200	/* Mode */
-+#define BCMA_CORE_PCI_PLP_STATUSREG		0x204	/* Status */
-+#define  BCMA_CORE_PCI_PLP_POLARITYINV_STAT	0x10	/* Status reg PCIE_PLP_STATUSREG */
-+#define BCMA_CORE_PCI_PLP_LTSSMCTRLREG		0x208	/* LTSSM control */
-+#define BCMA_CORE_PCI_PLP_LTLINKNUMREG		0x20c	/* Link Training Link number */
-+#define BCMA_CORE_PCI_PLP_LTLANENUMREG		0x210	/* Link Training Lane number */
-+#define BCMA_CORE_PCI_PLP_LTNFTSREG		0x214	/* Link Training N_FTS */
-+#define BCMA_CORE_PCI_PLP_ATTNREG		0x218	/* Attention */
-+#define BCMA_CORE_PCI_PLP_ATTNMASKREG		0x21C	/* Attention Mask */
-+#define BCMA_CORE_PCI_PLP_RXERRCTR		0x220	/* Rx Error */
-+#define BCMA_CORE_PCI_PLP_RXFRMERRCTR		0x224	/* Rx Framing Error */
-+#define BCMA_CORE_PCI_PLP_RXERRTHRESHREG	0x228	/* Rx Error threshold */
-+#define BCMA_CORE_PCI_PLP_TESTCTRLREG		0x22C	/* Test Control reg */
-+#define BCMA_CORE_PCI_PLP_SERDESCTRLOVRDREG	0x230	/* SERDES Control Override */
-+#define BCMA_CORE_PCI_PLP_TIMINGOVRDREG		0x234	/* Timing param override */
-+#define BCMA_CORE_PCI_PLP_RXTXSMDIAGREG		0x238	/* RXTX State Machine Diag */
-+#define BCMA_CORE_PCI_PLP_LTSSMDIAGREG		0x23C	/* LTSSM State Machine Diag */
-+
-+/* PCIE protocol DLLP diagnostic registers */
-+#define BCMA_CORE_PCI_DLLP_LCREG		0x100	/* Link Control */
-+#define BCMA_CORE_PCI_DLLP_LSREG		0x104	/* Link Status */
-+#define BCMA_CORE_PCI_DLLP_LAREG		0x108	/* Link Attention */
-+#define  BCMA_CORE_PCI_DLLP_LSREG_LINKUP	(1 << 16)
-+#define BCMA_CORE_PCI_DLLP_LAMASKREG		0x10C	/* Link Attention Mask */
-+#define BCMA_CORE_PCI_DLLP_NEXTTXSEQNUMREG	0x110	/* Next Tx Seq Num */
-+#define BCMA_CORE_PCI_DLLP_ACKEDTXSEQNUMREG	0x114	/* Acked Tx Seq Num */
-+#define BCMA_CORE_PCI_DLLP_PURGEDTXSEQNUMREG	0x118	/* Purged Tx Seq Num */
-+#define BCMA_CORE_PCI_DLLP_RXSEQNUMREG		0x11C	/* Rx Sequence Number */
-+#define BCMA_CORE_PCI_DLLP_LRREG		0x120	/* Link Replay */
-+#define BCMA_CORE_PCI_DLLP_LACKTOREG		0x124	/* Link Ack Timeout */
-+#define BCMA_CORE_PCI_DLLP_PMTHRESHREG		0x128	/* Power Management Threshold */
-+#define BCMA_CORE_PCI_DLLP_RTRYWPREG		0x12C	/* Retry buffer write ptr */
-+#define BCMA_CORE_PCI_DLLP_RTRYRPREG		0x130	/* Retry buffer Read ptr */
-+#define BCMA_CORE_PCI_DLLP_RTRYPPREG		0x134	/* Retry buffer Purged ptr */
-+#define BCMA_CORE_PCI_DLLP_RTRRWREG		0x138	/* Retry buffer Read/Write */
-+#define BCMA_CORE_PCI_DLLP_ECTHRESHREG		0x13C	/* Error Count Threshold */
-+#define BCMA_CORE_PCI_DLLP_TLPERRCTRREG		0x140	/* TLP Error Counter */
-+#define BCMA_CORE_PCI_DLLP_ERRCTRREG		0x144	/* Error Counter */
-+#define BCMA_CORE_PCI_DLLP_NAKRXCTRREG		0x148	/* NAK Received Counter */
-+#define BCMA_CORE_PCI_DLLP_TESTREG		0x14C	/* Test */
-+#define BCMA_CORE_PCI_DLLP_PKTBIST		0x150	/* Packet BIST */
-+#define BCMA_CORE_PCI_DLLP_PCIE11		0x154	/* DLLP PCIE 1.1 reg */
-+
-+/* SERDES RX registers */
-+#define BCMA_CORE_PCI_SERDES_RX_CTRL		1	/* Rx cntrl */
-+#define  BCMA_CORE_PCI_SERDES_RX_CTRL_FORCE	0x80	/* rxpolarity_force */
-+#define  BCMA_CORE_PCI_SERDES_RX_CTRL_POLARITY	0x40	/* rxpolarity_value */
-+#define BCMA_CORE_PCI_SERDES_RX_TIMER1		2	/* Rx Timer1 */
-+#define BCMA_CORE_PCI_SERDES_RX_CDR		6	/* CDR */
-+#define BCMA_CORE_PCI_SERDES_RX_CDRBW		7	/* CDR BW */
-+
-+/* SERDES PLL registers */
-+#define BCMA_CORE_PCI_SERDES_PLL_CTRL		1	/* PLL control reg */
-+#define BCMA_CORE_PCI_PLL_CTRL_FREQDET_EN	0x4000	/* bit 14 is FREQDET on */
-+
-+/* PCIcore specific boardflags */
-+#define BCMA_CORE_PCI_BFL_NOPCI			0x00000400 /* Board leaves PCI floating */
-+
-+/* PCIE Config space accessing MACROS */
-+#define BCMA_CORE_PCI_CFG_BUS_SHIFT		24	/* Bus shift */
-+#define BCMA_CORE_PCI_CFG_SLOT_SHIFT		19	/* Slot/Device shift */
-+#define BCMA_CORE_PCI_CFG_FUN_SHIFT		16	/* Function shift */
-+#define BCMA_CORE_PCI_CFG_OFF_SHIFT		0	/* Register shift */
-+
-+#define BCMA_CORE_PCI_CFG_BUS_MASK		0xff	/* Bus mask */
-+#define BCMA_CORE_PCI_CFG_SLOT_MASK		0x1f	/* Slot/Device mask */
-+#define BCMA_CORE_PCI_CFG_FUN_MASK		7	/* Function mask */
-+#define BCMA_CORE_PCI_CFG_OFF_MASK		0xfff	/* Register mask */
-+
-+/* PCIE Root Capability Register bits (Host mode only) */
-+#define BCMA_CORE_PCI_RC_CRS_VISIBILITY		0x0001
-+
-+struct bcma_drv_pci;
-+
-+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
-+struct bcma_drv_pci_host {
-+	struct bcma_drv_pci *pdev;
-+
-+	u32 host_cfg_addr;
-+	spinlock_t cfgspace_lock;
-+
-+	struct pci_controller pci_controller;
-+	struct pci_ops pci_ops;
-+	struct resource mem_resource;
-+	struct resource io_resource;
-+};
-+#endif
-+
-+struct bcma_drv_pci {
-+	struct bcma_device *core;
-+	u8 setup_done:1;
-+	u8 hostmode:1;
-+
-+#ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
-+	struct bcma_drv_pci_host *host_controller;
-+#endif
-+};
-+
-+/* Register access */
-+#define pcicore_read32(pc, offset)		bcma_read32((pc)->core, offset)
-+#define pcicore_write32(pc, offset, val)	bcma_write32((pc)->core, offset, val)
-+
-+extern void __devinit bcma_core_pci_init(struct bcma_drv_pci *pc);
-+extern int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc,
-+				 struct bcma_device *core, bool enable);
-+
-+extern int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev);
-+extern int bcma_core_pci_plat_dev_init(struct pci_dev *dev);
-+
-+#endif /* LINUX_BCMA_DRIVER_PCI_H_ */
---- /dev/null
-+++ b/include/linux/bcma/bcma_regs.h
-@@ -0,0 +1,86 @@
-+#ifndef LINUX_BCMA_REGS_H_
-+#define LINUX_BCMA_REGS_H_
-+
-+/* Some single registers are shared between many cores */
-+/* BCMA_CLKCTLST: ChipCommon (rev >= 20), PCIe, 80211 */
-+#define BCMA_CLKCTLST			0x01E0 /* Clock control and status */
-+#define  BCMA_CLKCTLST_FORCEALP		0x00000001 /* Force ALP request */
-+#define  BCMA_CLKCTLST_FORCEHT		0x00000002 /* Force HT request */
-+#define  BCMA_CLKCTLST_FORCEILP		0x00000004 /* Force ILP request */
-+#define  BCMA_CLKCTLST_HAVEALPREQ	0x00000008 /* ALP available request */
-+#define  BCMA_CLKCTLST_HAVEHTREQ	0x00000010 /* HT available request */
-+#define  BCMA_CLKCTLST_HWCROFF		0x00000020 /* Force HW clock request off */
-+#define  BCMA_CLKCTLST_EXTRESREQ	0x00000700 /* Mask of external resource requests */
-+#define  BCMA_CLKCTLST_HAVEALP		0x00010000 /* ALP available */
-+#define  BCMA_CLKCTLST_HAVEHT		0x00020000 /* HT available */
-+#define  BCMA_CLKCTLST_BP_ON_ALP	0x00040000 /* RO: running on ALP clock */
-+#define  BCMA_CLKCTLST_BP_ON_HT		0x00080000 /* RO: running on HT clock */
-+#define  BCMA_CLKCTLST_EXTRESST		0x07000000 /* Mask of external resource status */
-+/* Is there any BCM4328 on BCMA bus? */
-+#define  BCMA_CLKCTLST_4328A0_HAVEHT	0x00010000 /* 4328a0 has reversed bits */
-+#define  BCMA_CLKCTLST_4328A0_HAVEALP	0x00020000 /* 4328a0 has reversed bits */
-+
-+/* Agent registers (common for every core) */
-+#define BCMA_IOCTL			0x0408 /* IO control */
-+#define  BCMA_IOCTL_CLK			0x0001
-+#define  BCMA_IOCTL_FGC			0x0002
-+#define  BCMA_IOCTL_CORE_BITS		0x3FFC
-+#define  BCMA_IOCTL_PME_EN		0x4000
-+#define  BCMA_IOCTL_BIST_EN		0x8000
-+#define BCMA_IOST			0x0500 /* IO status */
-+#define  BCMA_IOST_CORE_BITS		0x0FFF
-+#define  BCMA_IOST_DMA64		0x1000
-+#define  BCMA_IOST_GATED_CLK		0x2000
-+#define  BCMA_IOST_BIST_ERROR		0x4000
-+#define  BCMA_IOST_BIST_DONE		0x8000
-+#define BCMA_RESET_CTL			0x0800
-+#define  BCMA_RESET_CTL_RESET		0x0001
-+
-+/* BCMA PCI config space registers. */
-+#define BCMA_PCI_PMCSR			0x44
-+#define  BCMA_PCI_PE			0x100
-+#define BCMA_PCI_BAR0_WIN		0x80	/* Backplane address space 0 */
-+#define BCMA_PCI_BAR1_WIN		0x84	/* Backplane address space 1 */
-+#define BCMA_PCI_SPROMCTL		0x88	/* SPROM control */
-+#define  BCMA_PCI_SPROMCTL_WE		0x10	/* SPROM write enable */
-+#define BCMA_PCI_BAR1_CONTROL		0x8c	/* Address space 1 burst control */
-+#define BCMA_PCI_IRQS			0x90	/* PCI interrupts */
-+#define BCMA_PCI_IRQMASK		0x94	/* PCI IRQ control and mask (pcirev >= 6 only) */
-+#define BCMA_PCI_BACKPLANE_IRQS		0x98	/* Backplane Interrupts */
-+#define BCMA_PCI_BAR0_WIN2		0xAC
-+#define BCMA_PCI_GPIO_IN		0xB0	/* GPIO Input (pcirev >= 3 only) */
-+#define BCMA_PCI_GPIO_OUT		0xB4	/* GPIO Output (pcirev >= 3 only) */
-+#define BCMA_PCI_GPIO_OUT_ENABLE	0xB8	/* GPIO Output Enable/Disable (pcirev >= 3 only) */
-+#define  BCMA_PCI_GPIO_SCS		0x10	/* PCI config space bit 4 for 4306c0 slow clock source */
-+#define  BCMA_PCI_GPIO_HWRAD		0x20	/* PCI config space GPIO 13 for hw radio disable */
-+#define  BCMA_PCI_GPIO_XTAL		0x40	/* PCI config space GPIO 14 for Xtal powerup */
-+#define  BCMA_PCI_GPIO_PLL		0x80	/* PCI config space GPIO 15 for PLL powerdown */
-+
-+/* SiliconBackplane Address Map.
-+ * All regions may not exist on all chips.
-+ */
-+#define BCMA_SOC_SDRAM_BASE		0x00000000U	/* Physical SDRAM */
-+#define BCMA_SOC_PCI_MEM		0x08000000U	/* Host Mode sb2pcitranslation0 (64 MB) */
-+#define BCMA_SOC_PCI_MEM_SZ		(64 * 1024 * 1024)
-+#define BCMA_SOC_PCI_CFG		0x0c000000U	/* Host Mode sb2pcitranslation1 (64 MB) */
-+#define BCMA_SOC_SDRAM_SWAPPED		0x10000000U	/* Byteswapped Physical SDRAM */
-+#define BCMA_SOC_SDRAM_R2		0x80000000U	/* Region 2 for sdram (512 MB) */
-+
-+
-+#define BCMA_SOC_PCI_DMA		0x40000000U	/* Client Mode sb2pcitranslation2 (1 GB) */
-+#define BCMA_SOC_PCI_DMA2		0x80000000U	/* Client Mode sb2pcitranslation2 (1 GB) */
-+#define BCMA_SOC_PCI_DMA_SZ		0x40000000U	/* Client Mode sb2pcitranslation2 size in bytes */
-+#define BCMA_SOC_PCIE_DMA_L32		0x00000000U	/* PCIE Client Mode sb2pcitranslation2
-+							 * (2 ZettaBytes), low 32 bits
-+							 */
-+#define BCMA_SOC_PCIE_DMA_H32		0x80000000U	/* PCIE Client Mode sb2pcitranslation2
-+							 * (2 ZettaBytes), high 32 bits
-+							 */
-+
-+#define BCMA_SOC_PCI1_MEM		0x40000000U	/* Host Mode sb2pcitranslation0 (64 MB) */
-+#define BCMA_SOC_PCI1_CFG		0x44000000U	/* Host Mode sb2pcitranslation1 (64 MB) */
-+#define BCMA_SOC_PCIE1_DMA_H32		0xc0000000U	/* PCIE Client Mode sb2pcitranslation2
-+							 * (2 ZettaBytes), high 32 bits
-+							 */
-+
-+#endif /* LINUX_BCMA_REGS_H_ */
---- a/include/linux/mod_devicetable.h
-+++ b/include/linux/mod_devicetable.h
-@@ -382,6 +382,23 @@ struct ssb_device_id {
- #define SSB_ANY_ID		0xFFFF
- #define SSB_ANY_REV		0xFF
- 
-+/* Broadcom's specific AMBA core, see drivers/bcma/ */
-+struct bcma_device_id {
-+	__u16	manuf;
-+	__u16	id;
-+	__u8	rev;
-+	__u8	class;
-+};
-+#define BCMA_CORE(_manuf, _id, _rev, _class)  \
-+	{ .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, }
-+#define BCMA_CORETABLE_END  \
-+	{ 0, },
-+
-+#define BCMA_ANY_MANUF		0xFFFF
-+#define BCMA_ANY_ID		0xFFFF
-+#define BCMA_ANY_REV		0xFF
-+#define BCMA_ANY_CLASS		0xFF
-+
- struct virtio_device_id {
- 	__u32 device;
- 	__u32 vendor;
---- a/scripts/mod/file2alias.c
-+++ b/scripts/mod/file2alias.c
-@@ -702,6 +702,24 @@ static int do_ssb_entry(const char *file
- 	return 1;
- }
- 
-+/* Looks like: bcma:mNidNrevNclN. */
-+static int do_bcma_entry(const char *filename,
-+			 struct bcma_device_id *id, char *alias)
-+{
-+	id->manuf = TO_NATIVE(id->manuf);
-+	id->id = TO_NATIVE(id->id);
-+	id->rev = TO_NATIVE(id->rev);
-+	id->class = TO_NATIVE(id->class);
-+
-+	strcpy(alias, "bcma:");
-+	ADD(alias, "m", id->manuf != BCMA_ANY_MANUF, id->manuf);
-+	ADD(alias, "id", id->id != BCMA_ANY_ID, id->id);
-+	ADD(alias, "rev", id->rev != BCMA_ANY_REV, id->rev);
-+	ADD(alias, "cl", id->class != BCMA_ANY_CLASS, id->class);
-+	add_wildcard(alias);
-+	return 1;
-+}
-+
- /* Looks like: virtio:dNvN */
- static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
- 			   char *alias)
-@@ -968,6 +986,10 @@ void handle_moddevtable(struct module *m
- 		do_table(symval, sym->st_size,
- 			 sizeof(struct ssb_device_id), "ssb",
- 			 do_ssb_entry, mod);
-+	else if (sym_is(symname, "__mod_bcma_device_table"))
-+		do_table(symval, sym->st_size,
-+			 sizeof(struct bcma_device_id), "bcma",
-+			 do_bcma_entry, mod);
- 	else if (sym_is(symname, "__mod_virtio_device_table"))
- 		do_table(symval, sym->st_size,
- 			 sizeof(struct virtio_device_id), "virtio",
---- /dev/null
-+++ b/drivers/bcma/sprom.c
-@@ -0,0 +1,450 @@
-+/*
-+ * Broadcom specific AMBA
-+ * SPROM reading
-+ *
-+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+
-+#include <linux/bcma/bcma.h>
-+#include <linux/bcma/bcma_regs.h>
-+#include <linux/pci.h>
-+#include <linux/io.h>
-+#include <linux/dma-mapping.h>
-+#include <linux/slab.h>
-+
-+static int(*get_fallback_sprom)(struct bcma_bus *dev, struct ssb_sprom *out);
-+
-+/**
-+ * bcma_arch_register_fallback_sprom - Registers a method providing a
-+ * fallback SPROM if no SPROM is found.
-+ *
-+ * @sprom_callback: The callback function.
-+ *
-+ * With this function the architecture implementation may register a
-+ * callback handler which fills the SPROM data structure. The fallback is
-+ * used for PCI based BCMA devices, where no valid SPROM can be found
-+ * in the shadow registers and to provide the SPROM for SoCs where BCMA is
-+ * to controll the system bus.
-+ *
-+ * This function is useful for weird architectures that have a half-assed
-+ * BCMA device hardwired to their PCI bus.
-+ *
-+ * This function is available for architecture code, only. So it is not
-+ * exported.
-+ */
-+int bcma_arch_register_fallback_sprom(int (*sprom_callback)(struct bcma_bus *bus,
-+				     struct ssb_sprom *out))
-+{
-+	if (get_fallback_sprom)
-+		return -EEXIST;
-+	get_fallback_sprom = sprom_callback;
-+
-+	return 0;
-+}
-+
-+static int bcma_fill_sprom_with_fallback(struct bcma_bus *bus,
-+					 struct ssb_sprom *out)
-+{
-+	int err;
-+
-+	if (!get_fallback_sprom) {
-+		err = -ENOENT;
-+		goto fail;
-+	}
-+
-+	err = get_fallback_sprom(bus, out);
-+	if (err)
-+		goto fail;
-+
-+	pr_debug("Using SPROM revision %d provided by"
-+		 " platform.\n", bus->sprom.revision);
-+	return 0;
-+fail:
-+	pr_warn("Using fallback SPROM failed (err %d)\n", err);
-+	return err;
-+}
-+
-+/**************************************************
-+ * R/W ops.
-+ **************************************************/
-+
-+static void bcma_sprom_read(struct bcma_bus *bus, u16 offset, u16 *sprom)
-+{
-+	int i;
-+	for (i = 0; i < SSB_SPROMSIZE_WORDS_R4; i++)
-+		sprom[i] = bcma_read16(bus->drv_cc.core,
-+				       offset + (i * 2));
-+}
-+
-+/**************************************************
-+ * Validation.
-+ **************************************************/
-+
-+static inline u8 bcma_crc8(u8 crc, u8 data)
-+{
-+	/* Polynomial:   x^8 + x^7 + x^6 + x^4 + x^2 + 1   */
-+	static const u8 t[] = {
-+		0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
-+		0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
-+		0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
-+		0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
-+		0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
-+		0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
-+		0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
-+		0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
-+		0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
-+		0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
-+		0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
-+		0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
-+		0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
-+		0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
-+		0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
-+		0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
-+		0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
-+		0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
-+		0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
-+		0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
-+		0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
-+		0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
-+		0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
-+		0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
-+		0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
-+		0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
-+		0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
-+		0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
-+		0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
-+		0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
-+		0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
-+		0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F,
-+	};
-+	return t[crc ^ data];
-+}
-+
-+static u8 bcma_sprom_crc(const u16 *sprom)
-+{
-+	int word;
-+	u8 crc = 0xFF;
-+
-+	for (word = 0; word < SSB_SPROMSIZE_WORDS_R4 - 1; word++) {
-+		crc = bcma_crc8(crc, sprom[word] & 0x00FF);
-+		crc = bcma_crc8(crc, (sprom[word] & 0xFF00) >> 8);
-+	}
-+	crc = bcma_crc8(crc, sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & 0x00FF);
-+	crc ^= 0xFF;
-+
-+	return crc;
-+}
-+
-+static int bcma_sprom_check_crc(const u16 *sprom)
-+{
-+	u8 crc;
-+	u8 expected_crc;
-+	u16 tmp;
-+
-+	crc = bcma_sprom_crc(sprom);
-+	tmp = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_CRC;
-+	expected_crc = tmp >> SSB_SPROM_REVISION_CRC_SHIFT;
-+	if (crc != expected_crc)
-+		return -EPROTO;
-+
-+	return 0;
-+}
-+
-+static int bcma_sprom_valid(const u16 *sprom)
-+{
-+	u16 revision;
-+	int err;
-+
-+	err = bcma_sprom_check_crc(sprom);
-+	if (err)
-+		return err;
-+
-+	revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV;
-+	if (revision != 8 && revision != 9) {
-+		pr_err("Unsupported SPROM revision: %d\n", revision);
-+		return -ENOENT;
-+	}
-+
-+	return 0;
-+}
-+
-+/**************************************************
-+ * SPROM extraction.
-+ **************************************************/
-+
-+#define SPOFF(offset)	((offset) / sizeof(u16))
-+
-+#define SPEX(_field, _offset, _mask, _shift)	\
-+	bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift))
-+
-+static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
-+{
-+	u16 v, o;
-+	int i;
-+	u16 pwr_info_offset[] = {
-+		SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1,
-+		SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3
-+	};
-+	BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) !=
-+			ARRAY_SIZE(bus->sprom.core_pwr_info));
-+
-+	bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] &
-+		SSB_SPROM_REVISION_REV;
-+
-+	for (i = 0; i < 3; i++) {
-+		v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
-+		*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
-+	}
-+
-+	SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0);
-+
-+	SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0,
-+	     SSB_SPROM4_TXPID2G0_SHIFT);
-+	SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1,
-+	     SSB_SPROM4_TXPID2G1_SHIFT);
-+	SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2,
-+	     SSB_SPROM4_TXPID2G2_SHIFT);
-+	SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3,
-+	     SSB_SPROM4_TXPID2G3_SHIFT);
-+
-+	SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0,
-+	     SSB_SPROM4_TXPID5GL0_SHIFT);
-+	SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1,
-+	     SSB_SPROM4_TXPID5GL1_SHIFT);
-+	SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2,
-+	     SSB_SPROM4_TXPID5GL2_SHIFT);
-+	SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3,
-+	     SSB_SPROM4_TXPID5GL3_SHIFT);
-+
-+	SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0,
-+	     SSB_SPROM4_TXPID5G0_SHIFT);
-+	SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1,
-+	     SSB_SPROM4_TXPID5G1_SHIFT);
-+	SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2,
-+	     SSB_SPROM4_TXPID5G2_SHIFT);
-+	SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3,
-+	     SSB_SPROM4_TXPID5G3_SHIFT);
-+
-+	SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0,
-+	     SSB_SPROM4_TXPID5GH0_SHIFT);
-+	SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1,
-+	     SSB_SPROM4_TXPID5GH1_SHIFT);
-+	SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2,
-+	     SSB_SPROM4_TXPID5GH2_SHIFT);
-+	SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3,
-+	     SSB_SPROM4_TXPID5GH3_SHIFT);
-+
-+	SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0);
-+	SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0);
-+	SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0);
-+	SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0);
-+
-+	SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0);
-+
-+	/* Extract cores power info info */
-+	for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) {
-+		o = pwr_info_offset[i];
-+		SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
-+			SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT);
-+		SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI,
-+			SSB_SPROM8_2G_MAXP, 0);
-+
-+		SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0);
-+
-+		SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
-+			SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT);
-+		SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI,
-+			SSB_SPROM8_5G_MAXP, 0);
-+		SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP,
-+			SSB_SPROM8_5GH_MAXP, 0);
-+		SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP,
-+			SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT);
-+
-+		SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0);
-+		SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0);
-+	}
-+
-+	SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS,
-+	     SSB_SROM8_FEM_TSSIPOS_SHIFT);
-+	SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN,
-+	     SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
-+	SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE,
-+	     SSB_SROM8_FEM_PDET_RANGE_SHIFT);
-+	SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO,
-+	     SSB_SROM8_FEM_TR_ISO_SHIFT);
-+	SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT,
-+	     SSB_SROM8_FEM_ANTSWLUT_SHIFT);
-+
-+	SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS,
-+	     SSB_SROM8_FEM_TSSIPOS_SHIFT);
-+	SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN,
-+	     SSB_SROM8_FEM_EXTPA_GAIN_SHIFT);
-+	SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE,
-+	     SSB_SROM8_FEM_PDET_RANGE_SHIFT);
-+	SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO,
-+	     SSB_SROM8_FEM_TR_ISO_SHIFT);
-+	SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT,
-+	     SSB_SROM8_FEM_ANTSWLUT_SHIFT);
-+}
-+
-+/*
-+ * Indicates the presence of external SPROM.
-+ */
-+static bool bcma_sprom_ext_available(struct bcma_bus *bus)
-+{
-+	u32 chip_status;
-+	u32 srom_control;
-+	u32 present_mask;
-+
-+	if (bus->drv_cc.core->id.rev >= 31) {
-+		if (!(bus->drv_cc.capabilities & BCMA_CC_CAP_SPROM))
-+			return false;
-+
-+		srom_control = bcma_read32(bus->drv_cc.core,
-+					   BCMA_CC_SROM_CONTROL);
-+		return srom_control & BCMA_CC_SROM_CONTROL_PRESENT;
-+	}
-+
-+	/* older chipcommon revisions use chip status register */
-+	chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
-+	switch (bus->chipinfo.id) {
-+	case 0x4313:
-+		present_mask = BCMA_CC_CHIPST_4313_SPROM_PRESENT;
-+		break;
-+
-+	case 0x4331:
-+		present_mask = BCMA_CC_CHIPST_4331_SPROM_PRESENT;
-+		break;
-+
-+	default:
-+		return true;
-+	}
-+
-+	return chip_status & present_mask;
-+}
-+
-+/*
-+ * Indicates that on-chip OTP memory is present and enabled.
-+ */
-+static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
-+{
-+	u32 chip_status;
-+	u32 otpsize = 0;
-+	bool present;
-+
-+	chip_status = bcma_read32(bus->drv_cc.core, BCMA_CC_CHIPSTAT);
-+	switch (bus->chipinfo.id) {
-+	case 0x4313:
-+		present = chip_status & BCMA_CC_CHIPST_4313_OTP_PRESENT;
-+		break;
-+
-+	case 0x4331:
-+		present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
-+		break;
-+
-+	case 43224:
-+	case 43225:
-+		/* for these chips OTP is always available */
-+		present = true;
-+		break;
-+
-+	default:
-+		present = false;
-+		break;
-+	}
-+
-+	if (present) {
-+		otpsize = bus->drv_cc.capabilities & BCMA_CC_CAP_OTPS;
-+		otpsize >>= BCMA_CC_CAP_OTPS_SHIFT;
-+	}
-+
-+	return otpsize != 0;
-+}
-+
-+/*
-+ * Verify OTP is filled and determine the byte
-+ * offset where SPROM data is located.
-+ *
-+ * On error, returns 0; byte offset otherwise.
-+ */
-+static int bcma_sprom_onchip_offset(struct bcma_bus *bus)
-+{
-+	struct bcma_device *cc = bus->drv_cc.core;
-+	u32 offset;
-+
-+	/* verify OTP status */
-+	if ((bcma_read32(cc, BCMA_CC_OTPS) & BCMA_CC_OTPS_GU_PROG_HW) == 0)
-+		return 0;
-+
-+	/* obtain bit offset from otplayout register */
-+	offset = (bcma_read32(cc, BCMA_CC_OTPL) & BCMA_CC_OTPL_GURGN_OFFSET);
-+	return BCMA_CC_SPROM + (offset >> 3);
-+}
-+
-+int bcma_sprom_get(struct bcma_bus *bus)
-+{
-+	u16 offset = BCMA_CC_SPROM;
-+	u16 *sprom;
-+	int err = 0;
-+
-+	if (!bus->drv_cc.core)
-+		return -EOPNOTSUPP;
-+
-+	if (!bcma_sprom_ext_available(bus)) {
-+		/*
-+		 * External SPROM takes precedence so check
-+		 * on-chip OTP only when no external SPROM
-+		 * is present.
-+		 */
-+		if (bcma_sprom_onchip_available(bus)) {
-+			/* determine offset */
-+			offset = bcma_sprom_onchip_offset(bus);
-+		}
-+		if (!offset) {
-+			/*
-+			 * Maybe there is no SPROM on the device?
-+			 * Now we ask the arch code if there is some sprom
-+			 * available for this device in some other storage.
-+			 */
-+			err = bcma_fill_sprom_with_fallback(bus, &bus->sprom);
-+			return err;
-+		}
-+	}
-+
-+	sprom = kcalloc(SSB_SPROMSIZE_WORDS_R4, sizeof(u16),
-+			GFP_KERNEL);
-+	if (!sprom)
-+		return -ENOMEM;
-+
-+	if (bus->chipinfo.id == 0x4331)
-+		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
-+
-+	pr_debug("SPROM offset 0x%x\n", offset);
-+	bcma_sprom_read(bus, offset, sprom);
-+
-+	if (bus->chipinfo.id == 0x4331)
-+		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
-+
-+	err = bcma_sprom_valid(sprom);
-+	if (err)
-+		goto out;
-+
-+	bcma_sprom_extract_r8(bus, sprom);
-+
-+out:
-+	kfree(sprom);
-+	return err;
-+}
---- /dev/null
-+++ b/drivers/bcma/driver_pci_host.c
-@@ -0,0 +1,589 @@
-+/*
-+ * Broadcom specific AMBA
-+ * PCI Core in hostmode
-+ *
-+ * Copyright 2005 - 2011, Broadcom Corporation
-+ * Copyright 2006, 2007, Michael Buesch <m@bues.ch>
-+ * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include <linux/pci.h>
-+#include <linux/export.h>
-+#include <linux/bcma/bcma.h>
-+#include <asm/paccess.h>
-+
-+/* Probe a 32bit value on the bus and catch bus exceptions.
-+ * Returns nonzero on a bus exception.
-+ * This is MIPS specific */
-+#define mips_busprobe32(val, addr)	get_dbe((val), ((u32 *)(addr)))
-+
-+/* Assume one-hot slot wiring */
-+#define BCMA_PCI_SLOT_MAX	16
-+#define	PCI_CONFIG_SPACE_SIZE	256
-+
-+bool __devinit bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
-+{
-+	struct bcma_bus *bus = pc->core->bus;
-+	u16 chipid_top;
-+	u32 tmp;
-+
-+	chipid_top = (bus->chipinfo.id & 0xFF00);
-+	if (chipid_top != 0x4700 &&
-+	    chipid_top != 0x5300)
-+		return false;
-+
-+	if (bus->sprom.boardflags_lo & BCMA_CORE_PCI_BFL_NOPCI) {
-+		pr_info("This PCI core is disabled and not working\n");
-+		return false;
-+	}
-+
-+	bcma_core_enable(pc->core, 0);
-+
-+	return !mips_busprobe32(tmp, pc->core->io_addr);
-+}
-+
-+static u32 bcma_pcie_read_config(struct bcma_drv_pci *pc, u32 address)
-+{
-+	pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
-+	pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
-+	return pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_DATA);
-+}
-+
-+static void bcma_pcie_write_config(struct bcma_drv_pci *pc, u32 address,
-+				   u32 data)
-+{
-+	pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_ADDR, address);
-+	pcicore_read32(pc, BCMA_CORE_PCI_CONFIG_ADDR);
-+	pcicore_write32(pc, BCMA_CORE_PCI_CONFIG_DATA, data);
-+}
-+
-+static u32 bcma_get_cfgspace_addr(struct bcma_drv_pci *pc, unsigned int dev,
-+			     unsigned int func, unsigned int off)
-+{
-+	u32 addr = 0;
-+
-+	/* Issue config commands only when the data link is up (atleast
-+	 * one external pcie device is present).
-+	 */
-+	if (dev >= 2 || !(bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_LSREG)
-+			  & BCMA_CORE_PCI_DLLP_LSREG_LINKUP))
-+		goto out;
-+
-+	/* Type 0 transaction */
-+	/* Slide the PCI window to the appropriate slot */
-+	pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
-+	/* Calculate the address */
-+	addr = pc->host_controller->host_cfg_addr;
-+	addr |= (dev << BCMA_CORE_PCI_CFG_SLOT_SHIFT);
-+	addr |= (func << BCMA_CORE_PCI_CFG_FUN_SHIFT);
-+	addr |= (off & ~3);
-+
-+out:
-+	return addr;
-+}
-+
-+static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
-+				  unsigned int func, unsigned int off,
-+				  void *buf, int len)
-+{
-+	int err = -EINVAL;
-+	u32 addr, val;
-+	void __iomem *mmio = 0;
-+
-+	WARN_ON(!pc->hostmode);
-+	if (unlikely(len != 1 && len != 2 && len != 4))
-+		goto out;
-+	if (dev == 0) {
-+		/* we support only two functions on device 0 */
-+		if (func > 1)
-+			return -EINVAL;
-+
-+		/* accesses to config registers with offsets >= 256
-+		 * requires indirect access.
-+		 */
-+		if (off >= PCI_CONFIG_SPACE_SIZE) {
-+			addr = (func << 12);
-+			addr |= (off & 0x0FFF);
-+			val = bcma_pcie_read_config(pc, addr);
-+		} else {
-+			addr = BCMA_CORE_PCI_PCICFG0;
-+			addr |= (func << 8);
-+			addr |= (off & 0xfc);
-+			val = pcicore_read32(pc, addr);
-+		}
-+	} else {
-+		addr = bcma_get_cfgspace_addr(pc, dev, func, off);
-+		if (unlikely(!addr))
-+			goto out;
-+		err = -ENOMEM;
-+		mmio = ioremap_nocache(addr, len);
-+		if (!mmio)
-+			goto out;
-+
-+		if (mips_busprobe32(val, mmio)) {
-+			val = 0xffffffff;
-+			goto unmap;
-+		}
-+
-+		val = readl(mmio);
-+	}
-+	val >>= (8 * (off & 3));
-+
-+	switch (len) {
-+	case 1:
-+		*((u8 *)buf) = (u8)val;
-+		break;
-+	case 2:
-+		*((u16 *)buf) = (u16)val;
-+		break;
-+	case 4:
-+		*((u32 *)buf) = (u32)val;
-+		break;
-+	}
-+	err = 0;
-+unmap:
-+	if (mmio)
-+		iounmap(mmio);
-+out:
-+	return err;
-+}
-+
-+static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
-+				   unsigned int func, unsigned int off,
-+				   const void *buf, int len)
-+{
-+	int err = -EINVAL;
-+	u32 addr = 0, val = 0;
-+	void __iomem *mmio = 0;
-+	u16 chipid = pc->core->bus->chipinfo.id;
-+
-+	WARN_ON(!pc->hostmode);
-+	if (unlikely(len != 1 && len != 2 && len != 4))
-+		goto out;
-+	if (dev == 0) {
-+		/* accesses to config registers with offsets >= 256
-+		 * requires indirect access.
-+		 */
-+		if (off < PCI_CONFIG_SPACE_SIZE) {
-+			addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
-+			addr |= (func << 8);
-+			addr |= (off & 0xfc);
-+			mmio = ioremap_nocache(addr, len);
-+			if (!mmio)
-+				goto out;
-+		}
-+	} else {
-+		addr = bcma_get_cfgspace_addr(pc, dev, func, off);
-+		if (unlikely(!addr))
-+			goto out;
-+		err = -ENOMEM;
-+		mmio = ioremap_nocache(addr, len);
-+		if (!mmio)
-+			goto out;
-+
-+		if (mips_busprobe32(val, mmio)) {
-+			val = 0xffffffff;
-+			goto unmap;
-+		}
-+	}
-+
-+	switch (len) {
-+	case 1:
-+		val = readl(mmio);
-+		val &= ~(0xFF << (8 * (off & 3)));
-+		val |= *((const u8 *)buf) << (8 * (off & 3));
-+		break;
-+	case 2:
-+		val = readl(mmio);
-+		val &= ~(0xFFFF << (8 * (off & 3)));
-+		val |= *((const u16 *)buf) << (8 * (off & 3));
-+		break;
-+	case 4:
-+		val = *((const u32 *)buf);
-+		break;
-+	}
-+	if (dev == 0 && !addr) {
-+		/* accesses to config registers with offsets >= 256
-+		 * requires indirect access.
-+		 */
-+		addr = (func << 12);
-+		addr |= (off & 0x0FFF);
-+		bcma_pcie_write_config(pc, addr, val);
-+	} else {
-+		writel(val, mmio);
-+
-+		if (chipid == 0x4716 || chipid == 0x4748)
-+			readl(mmio);
-+	}
-+
-+	err = 0;
-+unmap:
-+	if (mmio)
-+		iounmap(mmio);
-+out:
-+	return err;
-+}
-+
-+static int bcma_core_pci_hostmode_read_config(struct pci_bus *bus,
-+					      unsigned int devfn,
-+					      int reg, int size, u32 *val)
-+{
-+	unsigned long flags;
-+	int err;
-+	struct bcma_drv_pci *pc;
-+	struct bcma_drv_pci_host *pc_host;
-+
-+	pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
-+	pc = pc_host->pdev;
-+
-+	spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
-+	err = bcma_extpci_read_config(pc, PCI_SLOT(devfn),
-+				     PCI_FUNC(devfn), reg, val, size);
-+	spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
-+
-+	return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-+}
-+
-+static int bcma_core_pci_hostmode_write_config(struct pci_bus *bus,
-+					       unsigned int devfn,
-+					       int reg, int size, u32 val)
-+{
-+	unsigned long flags;
-+	int err;
-+	struct bcma_drv_pci *pc;
-+	struct bcma_drv_pci_host *pc_host;
-+
-+	pc_host = container_of(bus->ops, struct bcma_drv_pci_host, pci_ops);
-+	pc = pc_host->pdev;
-+
-+	spin_lock_irqsave(&pc_host->cfgspace_lock, flags);
-+	err = bcma_extpci_write_config(pc, PCI_SLOT(devfn),
-+				      PCI_FUNC(devfn), reg, &val, size);
-+	spin_unlock_irqrestore(&pc_host->cfgspace_lock, flags);
-+
-+	return err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-+}
-+
-+/* return cap_offset if requested capability exists in the PCI config space */
-+static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
-+					     unsigned int dev,
-+					     unsigned int func, u8 req_cap_id,
-+					     unsigned char *buf, u32 *buflen)
-+{
-+	u8 cap_id;
-+	u8 cap_ptr = 0;
-+	u32 bufsize;
-+	u8 byte_val;
-+
-+	/* check for Header type 0 */
-+	bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
-+				sizeof(u8));
-+	if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
-+		return cap_ptr;
-+
-+	/* check if the capability pointer field exists */
-+	bcma_extpci_read_config(pc, dev, func, PCI_STATUS, &byte_val,
-+				sizeof(u8));
-+	if (!(byte_val & PCI_STATUS_CAP_LIST))
-+		return cap_ptr;
-+
-+	/* check if the capability pointer is 0x00 */
-+	bcma_extpci_read_config(pc, dev, func, PCI_CAPABILITY_LIST, &cap_ptr,
-+				sizeof(u8));
-+	if (cap_ptr == 0x00)
-+		return cap_ptr;
-+
-+	/* loop thr'u the capability list and see if the requested capabilty
-+	 * exists */
-+	bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id, sizeof(u8));
-+	while (cap_id != req_cap_id) {
-+		bcma_extpci_read_config(pc, dev, func, cap_ptr + 1, &cap_ptr,
-+					sizeof(u8));
-+		if (cap_ptr == 0x00)
-+			return cap_ptr;
-+		bcma_extpci_read_config(pc, dev, func, cap_ptr, &cap_id,
-+					sizeof(u8));
-+	}
-+
-+	/* found the caller requested capability */
-+	if ((buf != NULL) && (buflen != NULL)) {
-+		u8 cap_data;
-+
-+		bufsize = *buflen;
-+		if (!bufsize)
-+			return cap_ptr;
-+
-+		*buflen = 0;
-+
-+		/* copy the cpability data excluding cap ID and next ptr */
-+		cap_data = cap_ptr + 2;
-+		if ((bufsize + cap_data)  > PCI_CONFIG_SPACE_SIZE)
-+			bufsize = PCI_CONFIG_SPACE_SIZE - cap_data;
-+		*buflen = bufsize;
-+		while (bufsize--) {
-+			bcma_extpci_read_config(pc, dev, func, cap_data, buf,
-+						sizeof(u8));
-+			cap_data++;
-+			buf++;
-+		}
-+	}
-+
-+	return cap_ptr;
-+}
-+
-+/* If the root port is capable of returning Config Request
-+ * Retry Status (CRS) Completion Status to software then
-+ * enable the feature.
-+ */
-+static void __devinit bcma_core_pci_enable_crs(struct bcma_drv_pci *pc)
-+{
-+	u8 cap_ptr, root_ctrl, root_cap, dev;
-+	u16 val16;
-+	int i;
-+
-+	cap_ptr = bcma_find_pci_capability(pc, 0, 0, PCI_CAP_ID_EXP, NULL,
-+					   NULL);
-+	root_cap = cap_ptr + PCI_EXP_RTCAP;
-+	bcma_extpci_read_config(pc, 0, 0, root_cap, &val16, sizeof(u16));
-+	if (val16 & BCMA_CORE_PCI_RC_CRS_VISIBILITY) {
-+		/* Enable CRS software visibility */
-+		root_ctrl = cap_ptr + PCI_EXP_RTCTL;
-+		val16 = PCI_EXP_RTCTL_CRSSVE;
-+		bcma_extpci_read_config(pc, 0, 0, root_ctrl, &val16,
-+					sizeof(u16));
-+
-+		/* Initiate a configuration request to read the vendor id
-+		 * field of the device function's config space header after
-+		 * 100 ms wait time from the end of Reset. If the device is
-+		 * not done with its internal initialization, it must at
-+		 * least return a completion TLP, with a completion status
-+		 * of "Configuration Request Retry Status (CRS)". The root
-+		 * complex must complete the request to the host by returning
-+		 * a read-data value of 0001h for the Vendor ID field and
-+		 * all 1s for any additional bytes included in the request.
-+		 * Poll using the config reads for max wait time of 1 sec or
-+		 * until we receive the successful completion status. Repeat
-+		 * the procedure for all the devices.
-+		 */
-+		for (dev = 1; dev < BCMA_PCI_SLOT_MAX; dev++) {
-+			for (i = 0; i < 100000; i++) {
-+				bcma_extpci_read_config(pc, dev, 0,
-+							PCI_VENDOR_ID, &val16,
-+							sizeof(val16));
-+				if (val16 != 0x1)
-+					break;
-+				udelay(10);
-+			}
-+			if (val16 == 0x1)
-+				pr_err("PCI: Broken device in slot %d\n", dev);
-+		}
-+	}
-+}
-+
-+void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
-+{
-+	struct bcma_bus *bus = pc->core->bus;
-+	struct bcma_drv_pci_host *pc_host;
-+	u32 tmp;
-+	u32 pci_membase_1G;
-+	unsigned long io_map_base;
-+
-+	pr_info("PCIEcore in host mode found\n");
-+
-+	pc_host = kzalloc(sizeof(*pc_host), GFP_KERNEL);
-+	if (!pc_host)  {
-+		pr_err("can not allocate memory");
-+		return;
-+	}
-+
-+	pc->host_controller = pc_host;
-+	pc_host->pci_controller.io_resource = &pc_host->io_resource;
-+	pc_host->pci_controller.mem_resource = &pc_host->mem_resource;
-+	pc_host->pci_controller.pci_ops = &pc_host->pci_ops;
-+	pc_host->pdev = pc;
-+
-+	pci_membase_1G = BCMA_SOC_PCI_DMA;
-+	pc_host->host_cfg_addr = BCMA_SOC_PCI_CFG;
-+
-+	pc_host->pci_ops.read = bcma_core_pci_hostmode_read_config;
-+	pc_host->pci_ops.write = bcma_core_pci_hostmode_write_config;
-+
-+	pc_host->mem_resource.name = "BCMA PCIcore external memory",
-+	pc_host->mem_resource.start = BCMA_SOC_PCI_DMA;
-+	pc_host->mem_resource.end = BCMA_SOC_PCI_DMA + BCMA_SOC_PCI_DMA_SZ - 1;
-+	pc_host->mem_resource.flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED;
-+
-+	pc_host->io_resource.name = "BCMA PCIcore external I/O",
-+	pc_host->io_resource.start = 0x100;
-+	pc_host->io_resource.end = 0x7FF;
-+	pc_host->io_resource.flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED;
-+
-+	/* Reset RC */
-+	udelay(3000);
-+	pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
-+	udelay(1000);
-+	pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
-+			BCMA_CORE_PCI_CTL_RST_OE);
-+
-+	/* 64 MB I/O access window. On 4716, use
-+	 * sbtopcie0 to access the device registers. We
-+	 * can't use address match 2 (1 GB window) region
-+	 * as mips can't generate 64-bit address on the
-+	 * backplane.
-+	 */
-+	if (bus->chipinfo.id == 0x4716 || bus->chipinfo.id == 0x4748) {
-+		pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
-+		pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
-+					    BCMA_SOC_PCI_MEM_SZ - 1;
-+		pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
-+				BCMA_CORE_PCI_SBTOPCI_MEM | BCMA_SOC_PCI_MEM);
-+	} else if (bus->chipinfo.id == 0x5300) {
-+		tmp = BCMA_CORE_PCI_SBTOPCI_MEM;
-+		tmp |= BCMA_CORE_PCI_SBTOPCI_PREF;
-+		tmp |= BCMA_CORE_PCI_SBTOPCI_BURST;
-+		if (pc->core->core_unit == 0) {
-+			pc_host->mem_resource.start = BCMA_SOC_PCI_MEM;
-+			pc_host->mem_resource.end = BCMA_SOC_PCI_MEM +
-+						    BCMA_SOC_PCI_MEM_SZ - 1;
-+			pci_membase_1G = BCMA_SOC_PCIE_DMA_H32;
-+			pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
-+					tmp | BCMA_SOC_PCI_MEM);
-+		} else if (pc->core->core_unit == 1) {
-+			pc_host->mem_resource.start = BCMA_SOC_PCI1_MEM;
-+			pc_host->mem_resource.end = BCMA_SOC_PCI1_MEM +
-+						    BCMA_SOC_PCI_MEM_SZ - 1;
-+			pci_membase_1G = BCMA_SOC_PCIE1_DMA_H32;
-+			pc_host->host_cfg_addr = BCMA_SOC_PCI1_CFG;
-+			pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
-+					tmp | BCMA_SOC_PCI1_MEM);
-+		}
-+	} else
-+		pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI0,
-+				BCMA_CORE_PCI_SBTOPCI_IO);
-+
-+	/* 64 MB configuration access window */
-+	pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI1, BCMA_CORE_PCI_SBTOPCI_CFG0);
-+
-+	/* 1 GB memory access window */
-+	pcicore_write32(pc, BCMA_CORE_PCI_SBTOPCI2,
-+			BCMA_CORE_PCI_SBTOPCI_MEM | pci_membase_1G);
-+
-+
-+	/* As per PCI Express Base Spec 1.1 we need to wait for
-+	 * at least 100 ms from the end of a reset (cold/warm/hot)
-+	 * before issuing configuration requests to PCI Express
-+	 * devices.
-+	 */
-+	udelay(100000);
-+
-+	bcma_core_pci_enable_crs(pc);
-+
-+	/* Enable PCI bridge BAR0 memory & master access */
-+	tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
-+	bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
-+
-+	/* Enable PCI interrupts */
-+	pcicore_write32(pc, BCMA_CORE_PCI_IMASK, BCMA_CORE_PCI_IMASK_INTA);
-+
-+	/* Ok, ready to run, register it to the system.
-+	 * The following needs change, if we want to port hostmode
-+	 * to non-MIPS platform. */
-+	io_map_base = (unsigned long)ioremap_nocache(BCMA_SOC_PCI_MEM,
-+						     0x04000000);
-+	pc_host->pci_controller.io_map_base = io_map_base;
-+	set_io_port_base(pc_host->pci_controller.io_map_base);
-+	/* Give some time to the PCI controller to configure itself with the new
-+	 * values. Not waiting at this point causes crashes of the machine. */
-+	mdelay(10);
-+	register_pci_controller(&pc_host->pci_controller);
-+	return;
-+}
-+
-+/* Early PCI fixup for a device on the PCI-core bridge. */
-+static void bcma_core_pci_fixup_pcibridge(struct pci_dev *dev)
-+{
-+	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
-+		/* This is not a device on the PCI-core bridge. */
-+		return;
-+	}
-+	if (PCI_SLOT(dev->devfn) != 0)
-+		return;
-+
-+	pr_info("PCI: Fixing up bridge %s\n", pci_name(dev));
-+
-+	/* Enable PCI bridge bus mastering and memory space */
-+	pci_set_master(dev);
-+	if (pcibios_enable_device(dev, ~0) < 0) {
-+		pr_err("PCI: BCMA bridge enable failed\n");
-+		return;
-+	}
-+
-+	/* Enable PCI bridge BAR1 prefetch and burst */
-+	pci_write_config_dword(dev, BCMA_PCI_BAR1_CONTROL, 3);
-+}
-+DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_pcibridge);
-+
-+/* Early PCI fixup for all PCI-cores to set the correct memory address. */
-+static void bcma_core_pci_fixup_addresses(struct pci_dev *dev)
-+{
-+	struct resource *res;
-+	int pos;
-+
-+	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
-+		/* This is not a device on the PCI-core bridge. */
-+		return;
-+	}
-+	if (PCI_SLOT(dev->devfn) == 0)
-+		return;
-+
-+	pr_info("PCI: Fixing up addresses %s\n", pci_name(dev));
-+
-+	for (pos = 0; pos < 6; pos++) {
-+		res = &dev->resource[pos];
-+		if (res->flags & (IORESOURCE_IO | IORESOURCE_MEM))
-+			pci_assign_resource(dev, pos);
-+	}
-+}
-+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, bcma_core_pci_fixup_addresses);
-+
-+/* This function is called when doing a pci_enable_device().
-+ * We must first check if the device is a device on the PCI-core bridge. */
-+int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
-+{
-+	struct bcma_drv_pci_host *pc_host;
-+
-+	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
-+		/* This is not a device on the PCI-core bridge. */
-+		return -ENODEV;
-+	}
-+	pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
-+			       pci_ops);
-+
-+	pr_info("PCI: Fixing up device %s\n", pci_name(dev));
-+
-+	/* Fix up interrupt lines */
-+	dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
-+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL(bcma_core_pci_plat_dev_init);
-+
-+/* PCI device IRQ mapping. */
-+int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
-+{
-+	struct bcma_drv_pci_host *pc_host;
-+
-+	if (dev->bus->ops->read != bcma_core_pci_hostmode_read_config) {
-+		/* This is not a device on the PCI-core bridge. */
-+		return -ENODEV;
-+	}
-+
-+	pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
-+			       pci_ops);
-+	return bcma_core_mips_irq(pc_host->pdev->core) + 2;
-+}
-+EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
---- /dev/null
-+++ b/drivers/bcma/driver_mips.c
-@@ -0,0 +1,256 @@
-+/*
-+ * Broadcom specific AMBA
-+ * Broadcom MIPS32 74K core driver
-+ *
-+ * Copyright 2009, Broadcom Corporation
-+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
-+ * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
-+ * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+
-+#include <linux/bcma/bcma.h>
-+
-+#include <linux/serial.h>
-+#include <linux/serial_core.h>
-+#include <linux/serial_reg.h>
-+#include <linux/time.h>
-+
-+/* The 47162a0 hangs when reading MIPS DMP registers registers */
-+static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
-+{
-+	return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
-+	       dev->id.id == BCMA_CORE_MIPS_74K;
-+}
-+
-+/* The 5357b0 hangs when reading USB20H DMP registers */
-+static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
-+{
-+	return (dev->bus->chipinfo.id == 0x5357 ||
-+		dev->bus->chipinfo.id == 0x4749) &&
-+	       dev->bus->chipinfo.pkg == 11 &&
-+	       dev->id.id == BCMA_CORE_USB20_HOST;
-+}
-+
-+static inline u32 mips_read32(struct bcma_drv_mips *mcore,
-+			      u16 offset)
-+{
-+	return bcma_read32(mcore->core, offset);
-+}
-+
-+static inline void mips_write32(struct bcma_drv_mips *mcore,
-+				u16 offset,
-+				u32 value)
-+{
-+	bcma_write32(mcore->core, offset, value);
-+}
-+
-+static const u32 ipsflag_irq_mask[] = {
-+	0,
-+	BCMA_MIPS_IPSFLAG_IRQ1,
-+	BCMA_MIPS_IPSFLAG_IRQ2,
-+	BCMA_MIPS_IPSFLAG_IRQ3,
-+	BCMA_MIPS_IPSFLAG_IRQ4,
-+};
-+
-+static const u32 ipsflag_irq_shift[] = {
-+	0,
-+	BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
-+	BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
-+	BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
-+	BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
-+};
-+
-+static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
-+{
-+	u32 flag;
-+
-+	if (bcma_core_mips_bcm47162a0_quirk(dev))
-+		return dev->core_index;
-+	if (bcma_core_mips_bcm5357b0_quirk(dev))
-+		return dev->core_index;
-+	flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
-+
-+	return flag & 0x1F;
-+}
-+
-+/* Get the MIPS IRQ assignment for a specified device.
-+ * If unassigned, 0 is returned.
-+ */
-+unsigned int bcma_core_mips_irq(struct bcma_device *dev)
-+{
-+	struct bcma_device *mdev = dev->bus->drv_mips.core;
-+	u32 irqflag;
-+	unsigned int irq;
-+
-+	irqflag = bcma_core_mips_irqflag(dev);
-+
-+	for (irq = 1; irq <= 4; irq++)
-+		if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
-+		    (1 << irqflag))
-+			return irq;
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL(bcma_core_mips_irq);
-+
-+static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
-+{
-+	unsigned int oldirq = bcma_core_mips_irq(dev);
-+	struct bcma_bus *bus = dev->bus;
-+	struct bcma_device *mdev = bus->drv_mips.core;
-+	u32 irqflag;
-+
-+	irqflag = bcma_core_mips_irqflag(dev);
-+	BUG_ON(oldirq == 6);
-+
-+	dev->irq = irq + 2;
-+
-+	/* clear the old irq */
-+	if (oldirq == 0)
-+		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
-+			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
-+			    ~(1 << irqflag));
-+	else
-+		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
-+
-+	/* assign the new one */
-+	if (irq == 0) {
-+		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
-+			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
-+			    (1 << irqflag));
-+	} else {
-+		u32 oldirqflag = bcma_read32(mdev,
-+					     BCMA_MIPS_MIPS74K_INTMASK(irq));
-+		if (oldirqflag) {
-+			struct bcma_device *core;
-+
-+			/* backplane irq line is in use, find out who uses
-+			 * it and set user to irq 0
-+			 */
-+			list_for_each_entry_reverse(core, &bus->cores, list) {
-+				if ((1 << bcma_core_mips_irqflag(core)) ==
-+				    oldirqflag) {
-+					bcma_core_mips_set_irq(core, 0);
-+					break;
-+				}
-+			}
-+		}
-+		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
-+			     1 << irqflag);
-+	}
-+
-+	pr_info("set_irq: core 0x%04x, irq %d => %d\n",
-+		dev->id.id, oldirq + 2, irq + 2);
-+}
-+
-+static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
-+{
-+	int i;
-+	static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
-+	printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
-+	for (i = 0; i <= 6; i++)
-+		printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
-+	printk("\n");
-+}
-+
-+static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
-+{
-+	struct bcma_device *core;
-+
-+	list_for_each_entry_reverse(core, &bus->cores, list) {
-+		bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
-+	}
-+}
-+
-+u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
-+{
-+	struct bcma_bus *bus = mcore->core->bus;
-+
-+	if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
-+		return bcma_pmu_get_clockcpu(&bus->drv_cc);
-+
-+	pr_err("No PMU available, need this to get the cpu clock\n");
-+	return 0;
-+}
-+EXPORT_SYMBOL(bcma_cpu_clock);
-+
-+static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
-+{
-+	struct bcma_bus *bus = mcore->core->bus;
-+
-+	switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
-+	case BCMA_CC_FLASHT_STSER:
-+	case BCMA_CC_FLASHT_ATSER:
-+		pr_err("Serial flash not supported.\n");
-+		break;
-+	case BCMA_CC_FLASHT_PARA:
-+		pr_info("found parallel flash.\n");
-+		bus->drv_cc.pflash.window = 0x1c000000;
-+		bus->drv_cc.pflash.window_size = 0x02000000;
-+
-+		if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
-+		     BCMA_CC_FLASH_CFG_DS) == 0)
-+			bus->drv_cc.pflash.buswidth = 1;
-+		else
-+			bus->drv_cc.pflash.buswidth = 2;
-+		break;
-+	default:
-+		pr_err("flash not supported.\n");
-+	}
-+}
-+
-+void bcma_core_mips_init(struct bcma_drv_mips *mcore)
-+{
-+	struct bcma_bus *bus;
-+	struct bcma_device *core;
-+	bus = mcore->core->bus;
-+
-+	pr_info("Initializing MIPS core...\n");
-+
-+	if (!mcore->setup_done)
-+		mcore->assigned_irqs = 1;
-+
-+	/* Assign IRQs to all cores on the bus */
-+	list_for_each_entry_reverse(core, &bus->cores, list) {
-+		int mips_irq;
-+		if (core->irq)
-+			continue;
-+
-+		mips_irq = bcma_core_mips_irq(core);
-+		if (mips_irq > 4)
-+			core->irq = 0;
-+		else
-+			core->irq = mips_irq + 2;
-+		if (core->irq > 5)
-+			continue;
-+		switch (core->id.id) {
-+		case BCMA_CORE_PCI:
-+		case BCMA_CORE_PCIE:
-+		case BCMA_CORE_ETHERNET:
-+		case BCMA_CORE_ETHERNET_GBIT:
-+		case BCMA_CORE_MAC_GBIT:
-+		case BCMA_CORE_80211:
-+		case BCMA_CORE_USB20_HOST:
-+			/* These devices get their own IRQ line if available,
-+			 * the rest goes on IRQ0
-+			 */
-+			if (mcore->assigned_irqs <= 4)
-+				bcma_core_mips_set_irq(core,
-+						       mcore->assigned_irqs++);
-+			break;
-+		}
-+	}
-+	pr_info("IRQ reconfiguration done\n");
-+	bcma_core_mips_dump_irq(bus);
-+
-+	if (mcore->setup_done)
-+		return;
-+
-+	bcma_chipco_serial_init(&bus->drv_cc);
-+	bcma_core_mips_flash_detect(mcore);
-+	mcore->setup_done = true;
-+}
---- /dev/null
-+++ b/drivers/bcma/host_soc.c
-@@ -0,0 +1,183 @@
-+/*
-+ * Broadcom specific AMBA
-+ * System on Chip (SoC) Host
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include "bcma_private.h"
-+#include "scan.h"
-+#include <linux/bcma/bcma.h>
-+#include <linux/bcma/bcma_soc.h>
-+
-+static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
-+{
-+	return readb(core->io_addr + offset);
-+}
-+
-+static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
-+{
-+	return readw(core->io_addr + offset);
-+}
-+
-+static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
-+{
-+	return readl(core->io_addr + offset);
-+}
-+
-+static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
-+				 u8 value)
-+{
-+	writeb(value, core->io_addr + offset);
-+}
-+
-+static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
-+				 u16 value)
-+{
-+	writew(value, core->io_addr + offset);
-+}
-+
-+static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
-+				 u32 value)
-+{
-+	writel(value, core->io_addr + offset);
-+}
-+
-+#ifdef CONFIG_BCMA_BLOCKIO
-+static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
-+				     size_t count, u16 offset, u8 reg_width)
-+{
-+	void __iomem *addr = core->io_addr + offset;
-+
-+	switch (reg_width) {
-+	case sizeof(u8): {
-+		u8 *buf = buffer;
-+
-+		while (count) {
-+			*buf = __raw_readb(addr);
-+			buf++;
-+			count--;
-+		}
-+		break;
-+	}
-+	case sizeof(u16): {
-+		__le16 *buf = buffer;
-+
-+		WARN_ON(count & 1);
-+		while (count) {
-+			*buf = (__force __le16)__raw_readw(addr);
-+			buf++;
-+			count -= 2;
-+		}
-+		break;
-+	}
-+	case sizeof(u32): {
-+		__le32 *buf = buffer;
-+
-+		WARN_ON(count & 3);
-+		while (count) {
-+			*buf = (__force __le32)__raw_readl(addr);
-+			buf++;
-+			count -= 4;
-+		}
-+		break;
-+	}
-+	default:
-+		WARN_ON(1);
-+	}
-+}
-+
-+static void bcma_host_soc_block_write(struct bcma_device *core,
-+				      const void *buffer,
-+				      size_t count, u16 offset, u8 reg_width)
-+{
-+	void __iomem *addr = core->io_addr + offset;
-+
-+	switch (reg_width) {
-+	case sizeof(u8): {
-+		const u8 *buf = buffer;
-+
-+		while (count) {
-+			__raw_writeb(*buf, addr);
-+			buf++;
-+			count--;
-+		}
-+		break;
-+	}
-+	case sizeof(u16): {
-+		const __le16 *buf = buffer;
-+
-+		WARN_ON(count & 1);
-+		while (count) {
-+			__raw_writew((__force u16)(*buf), addr);
-+			buf++;
-+			count -= 2;
-+		}
-+		break;
-+	}
-+	case sizeof(u32): {
-+		const __le32 *buf = buffer;
-+
-+		WARN_ON(count & 3);
-+		while (count) {
-+			__raw_writel((__force u32)(*buf), addr);
-+			buf++;
-+			count -= 4;
-+		}
-+		break;
-+	}
-+	default:
-+		WARN_ON(1);
-+	}
-+}
-+#endif /* CONFIG_BCMA_BLOCKIO */
-+
-+static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
-+{
-+	return readl(core->io_wrap + offset);
-+}
-+
-+static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
-+				  u32 value)
-+{
-+	writel(value, core->io_wrap + offset);
-+}
-+
-+const struct bcma_host_ops bcma_host_soc_ops = {
-+	.read8		= bcma_host_soc_read8,
-+	.read16		= bcma_host_soc_read16,
-+	.read32		= bcma_host_soc_read32,
-+	.write8		= bcma_host_soc_write8,
-+	.write16	= bcma_host_soc_write16,
-+	.write32	= bcma_host_soc_write32,
-+#ifdef CONFIG_BCMA_BLOCKIO
-+	.block_read	= bcma_host_soc_block_read,
-+	.block_write	= bcma_host_soc_block_write,
-+#endif
-+	.aread32	= bcma_host_soc_aread32,
-+	.awrite32	= bcma_host_soc_awrite32,
-+};
-+
-+int __init bcma_host_soc_register(struct bcma_soc *soc)
-+{
-+	struct bcma_bus *bus = &soc->bus;
-+	int err;
-+
-+	/* iomap only first core. We have to read some register on this core
-+	 * to scan the bus.
-+	 */
-+	bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
-+	if (!bus->mmio)
-+		return -ENOMEM;
-+
-+	/* Host specific */
-+	bus->hosttype = BCMA_HOSTTYPE_SOC;
-+	bus->ops = &bcma_host_soc_ops;
-+
-+	/* Register */
-+	err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
-+	if (err)
-+		iounmap(bus->mmio);
-+
-+	return err;
-+}
---- /dev/null
-+++ b/include/linux/bcma/bcma_driver_mips.h
-@@ -0,0 +1,51 @@
-+#ifndef LINUX_BCMA_DRIVER_MIPS_H_
-+#define LINUX_BCMA_DRIVER_MIPS_H_
-+
-+#define BCMA_MIPS_IPSFLAG		0x0F08
-+/* which sbflags get routed to mips interrupt 1 */
-+#define  BCMA_MIPS_IPSFLAG_IRQ1		0x0000003F
-+#define  BCMA_MIPS_IPSFLAG_IRQ1_SHIFT	0
-+/* which sbflags get routed to mips interrupt 2 */
-+#define  BCMA_MIPS_IPSFLAG_IRQ2		0x00003F00
-+#define  BCMA_MIPS_IPSFLAG_IRQ2_SHIFT	8
-+/* which sbflags get routed to mips interrupt 3 */
-+#define  BCMA_MIPS_IPSFLAG_IRQ3		0x003F0000
-+#define  BCMA_MIPS_IPSFLAG_IRQ3_SHIFT	16
-+/* which sbflags get routed to mips interrupt 4 */
-+#define  BCMA_MIPS_IPSFLAG_IRQ4		0x3F000000
-+#define  BCMA_MIPS_IPSFLAG_IRQ4_SHIFT	24
-+
-+/* MIPS 74K core registers */
-+#define BCMA_MIPS_MIPS74K_CORECTL	0x0000
-+#define BCMA_MIPS_MIPS74K_EXCEPTBASE	0x0004
-+#define BCMA_MIPS_MIPS74K_BIST		0x000C
-+#define BCMA_MIPS_MIPS74K_INTMASK_INT0	0x0014
-+#define BCMA_MIPS_MIPS74K_INTMASK(int) \
-+	((int) * 4 + BCMA_MIPS_MIPS74K_INTMASK_INT0)
-+#define BCMA_MIPS_MIPS74K_NMIMASK	0x002C
-+#define BCMA_MIPS_MIPS74K_GPIOSEL	0x0040
-+#define BCMA_MIPS_MIPS74K_GPIOOUT	0x0044
-+#define BCMA_MIPS_MIPS74K_GPIOEN	0x0048
-+#define BCMA_MIPS_MIPS74K_CLKCTLST	0x01E0
-+
-+#define BCMA_MIPS_OOBSELOUTA30		0x100
-+
-+struct bcma_device;
-+
-+struct bcma_drv_mips {
-+	struct bcma_device *core;
-+	u8 setup_done:1;
-+	unsigned int assigned_irqs;
-+};
-+
-+#ifdef CONFIG_BCMA_DRIVER_MIPS
-+extern void bcma_core_mips_init(struct bcma_drv_mips *mcore);
-+#else
-+static inline void bcma_core_mips_init(struct bcma_drv_mips *mcore) { }
-+#endif
-+
-+extern u32 bcma_cpu_clock(struct bcma_drv_mips *mcore);
-+
-+extern unsigned int bcma_core_mips_irq(struct bcma_device *dev);
-+
-+#endif /* LINUX_BCMA_DRIVER_MIPS_H_ */
---- /dev/null
-+++ b/include/linux/bcma/bcma_soc.h
-@@ -0,0 +1,16 @@
-+#ifndef LINUX_BCMA_SOC_H_
-+#define LINUX_BCMA_SOC_H_
-+
-+#include <linux/bcma/bcma.h>
-+
-+struct bcma_soc {
-+	struct bcma_bus bus;
-+	struct bcma_device core_cc;
-+	struct bcma_device core_mips;
-+};
-+
-+int __init bcma_host_soc_register(struct bcma_soc *soc);
-+
-+int bcma_bus_register(struct bcma_bus *bus);
-+
-+#endif /* LINUX_BCMA_SOC_H_ */
diff --git a/target/linux/generic/patches-2.6.38/100-overlayfs.patch b/target/linux/generic/patches-2.6.38/100-overlayfs.patch
deleted file mode 100644
index d526865a08..0000000000
--- a/target/linux/generic/patches-2.6.38/100-overlayfs.patch
+++ /dev/null
@@ -1,2787 +0,0 @@
---- /dev/null
-+++ b/Documentation/filesystems/overlayfs.txt
-@@ -0,0 +1,163 @@
-+Written by: Neil Brown <neilb@suse.de>
-+
-+Overlay Filesystem
-+==================
-+
-+This document describes a prototype for a new approach to providing
-+overlay-filesystem functionality in Linux (sometimes referred to as
-+union-filesystems).  An overlay-filesystem tries to present a
-+filesystem which is the result over overlaying one filesystem on top
-+of the other.
-+
-+The result will inevitably fail to look exactly like a normal
-+filesystem for various technical reasons.  The expectation is that
-+many use cases will be able to ignore these differences.
-+
-+This approach is 'hybrid' because the objects that appear in the
-+filesystem do not all appear to belong to that filesystem.  In many
-+case an object accessed in the union will be indistinguishable
-+from accessing the corresponding object from the original filesystem.
-+This is most obvious from the 'st_dev' field returned by stat(2).
-+
-+While directories will report an st_dev for the overlay-filesystem,
-+all non-directory objects will report an st_dev whichever of the
-+'lower' or 'upper' filesystem that is providing the object.  Similarly
-+st_ino will only be unique when combined with st_dev, and both of
-+these can change over the lifetime of a non-directory object.  Many
-+applications and tools ignore these values and will not be affected.
-+
-+Upper and Lower
-+---------------
-+
-+An overlay filesystem combines two filesystems - an 'upper' filesystem
-+and a 'lower' filesystem.  When a name exists in both filesystems, the
-+object in the 'upper' filesystem is visible while the object in the
-+'lower' filesystem is either hidden or, in the case of directories,
-+merged with the 'upper' object.
-+
-+It would be more correct to refer to an upper and lower 'directory
-+tree' rather than 'filesystem' as it is quite possible for both
-+directory trees to be in the same filesystem and there is no
-+requirement that the root of a filesystem be given for either upper or
-+lower.
-+
-+The lower filesystem can be any filesystem supported by Linux and does
-+not need to be writable.  The lower filesystem can even be another
-+overlayfs.  The upper filesystem will normally be writable and if it
-+is it must support the creation of trusted.* extended attributes, and
-+must provide valid d_type in readdir responses, at least for symbolic
-+links - so NFS is not suitable.
-+
-+A read-only overlay of two read-only filesystems may use any
-+filesystem type.
-+
-+Directories
-+-----------
-+
-+Overlaying mainly involved directories.  If a given name appears in both
-+upper and lower filesystems and refers to a non-directory in either,
-+then the lower object is hidden - the name refers only to the upper
-+object.
-+
-+Where both upper and lower objects are directories, a merged directory
-+is formed.
-+
-+At mount time, the two directories given as mount options are combined
-+into a merged directory.  Then whenever a lookup is requested in such
-+a merged directory, the lookup is performed in each actual directory
-+and the combined result is cached in the dentry belonging to the overlay
-+filesystem.  If both actual lookups find directories, both are stored
-+and a merged directory is created, otherwise only one is stored: the
-+upper if it exists, else the lower.
-+
-+Only the lists of names from directories are merged.  Other content
-+such as metadata and extended attributes are reported for the upper
-+directory only.  These attributes of the lower directory are hidden.
-+
-+whiteouts and opaque directories
-+--------------------------------
-+
-+In order to support rm and rmdir without changing the lower
-+filesystem, an overlay filesystem needs to record in the upper filesystem
-+that files have been removed.  This is done using whiteouts and opaque
-+directories (non-directories are always opaque).
-+
-+The overlay filesystem uses extended attributes with a
-+"trusted.overlay."  prefix to record these details.
-+
-+A whiteout is created as a symbolic link with target
-+"(overlay-whiteout)" and with xattr "trusted.overlay.whiteout" set to "y".
-+When a whiteout is found in the upper level of a merged directory, any
-+matching name in the lower level is ignored, and the whiteout itself
-+is also hidden.
-+
-+A directory is made opaque by setting the xattr "trusted.overlay.opaque"
-+to "y".  Where the upper filesystem contains an opaque directory, any
-+directory in the lower filesystem with the same name is ignored.
-+
-+readdir
-+-------
-+
-+When a 'readdir' request is made on a merged directory, the upper and
-+lower directories are each read and the name lists merged in the
-+obvious way (upper is read first, then lower - entries that already
-+exist are not re-added).  This merged name list is cached in the
-+'struct file' and so remains as long as the file is kept open.  If the
-+directory is opened and read by two processes at the same time, they
-+will each have separate caches.  A seekdir to the start of the
-+directory (offset 0) followed by a readdir will cause the cache to be
-+discarded and rebuilt.
-+
-+This means that changes to the merged directory do not appear while a
-+directory is being read.  This is unlikely to be noticed by many
-+programs.
-+
-+seek offsets are assigned sequentially when the directories are read.
-+Thus if
-+  - read part of a directory
-+  - remember an offset, and close the directory
-+  - re-open the directory some time later
-+  - seek to the remembered offset
-+
-+there may be little correlation between the old and new locations in
-+the list of filenames, particularly if anything has changed in the
-+directory.
-+
-+Readdir on directories that are not merged is simply handled by the
-+underlying directory (upper or lower).
-+
-+
-+Non-directories
-+---------------
-+
-+Objects that are not directories (files, symlinks, device-special
-+files etc) are presented either from the upper or lower filesystem as
-+appropriate.  When a file in the lower filesystem is accessed in a way
-+the requires write-access; such as opening for write access, changing
-+some metadata etc, the file is first copied from the lower filesystem
-+to the upper filesystem (copy_up).  Note that creating a hard-link
-+also requires copy-up, though of course creation of a symlink does
-+not.
-+
-+The copy_up process first makes sure that the containing directory
-+exists in the upper filesystem - creating it and any parents as
-+necessary.  It then creates the object with the same metadata (owner,
-+mode, mtime, symlink-target etc) and then if the object is a file, the
-+data is copied from the lower to the upper filesystem.  Finally any
-+extended attributes are copied up.
-+
-+Once the copy_up is complete, the overlay filesystem simply
-+provides direct access to the newly created file in the upper
-+filesystem - future operations on the file are barely noticed by the
-+overlay filesystem (though an operation on the name of the file such as
-+rename or unlink will of course be noticed and handled).
-+
-+Changes to underlying filesystems
-+---------------------------------
-+
-+Offline changes, when the overlay is not mounted, are allowed to either
-+the upper or the lower trees.
-+
-+Changes to the underlying filesystems while part of a mounted overlay
-+filesystem are not allowed.  This is not yet enforced, but will be in
-+the future.
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -63,6 +63,7 @@ source "fs/quota/Kconfig"
- 
- source "fs/autofs4/Kconfig"
- source "fs/fuse/Kconfig"
-+source "fs/overlayfs/Kconfig"
- 
- config CUSE
- 	tristate "Character device in Userspace support"
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -103,6 +103,7 @@ obj-$(CONFIG_QNX4FS_FS)		+= qnx4/
- obj-$(CONFIG_AUTOFS4_FS)	+= autofs4/
- obj-$(CONFIG_ADFS_FS)		+= adfs/
- obj-$(CONFIG_FUSE_FS)		+= fuse/
-+obj-$(CONFIG_OVERLAYFS_FS)	+= overlayfs/
- obj-$(CONFIG_UDF_FS)		+= udf/
- obj-$(CONFIG_SUN_OPENPROMFS)	+= openpromfs/
- obj-$(CONFIG_OMFS_FS)		+= omfs/
---- a/fs/namespace.c
-+++ b/fs/namespace.c
-@@ -1451,6 +1451,23 @@ void drop_collected_mounts(struct vfsmou
- 	release_mounts(&umount_list);
- }
- 
-+struct vfsmount *clone_private_mount(struct path *path)
-+{
-+	struct vfsmount *mnt;
-+
-+	if (IS_MNT_UNBINDABLE(path->mnt))
-+		return ERR_PTR(-EINVAL);
-+
-+	down_read(&namespace_sem);
-+	mnt = clone_mnt(path->mnt, path->dentry, CL_PRIVATE);
-+	up_read(&namespace_sem);
-+	if (!mnt)
-+		return ERR_PTR(-ENOMEM);
-+
-+	return mnt;
-+}
-+EXPORT_SYMBOL_GPL(clone_private_mount);
-+
- int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg,
- 		   struct vfsmount *root)
- {
---- a/fs/open.c
-+++ b/fs/open.c
-@@ -664,19 +664,19 @@ static inline int __get_file_write_acces
- 	return error;
- }
- 
--static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
--					struct file *f,
-+static struct file *__dentry_open(struct path *path, struct file *f,
- 					int (*open)(struct inode *, struct file *),
- 					const struct cred *cred)
- {
- 	struct inode *inode;
- 	int error;
- 
-+	path_get(path);
- 	f->f_mode = OPEN_FMODE(f->f_flags) | FMODE_LSEEK |
- 				FMODE_PREAD | FMODE_PWRITE;
--	inode = dentry->d_inode;
-+	inode = path->dentry->d_inode;
- 	if (f->f_mode & FMODE_WRITE) {
--		error = __get_file_write_access(inode, mnt);
-+		error = __get_file_write_access(inode, path->mnt);
- 		if (error)
- 			goto cleanup_file;
- 		if (!special_file(inode->i_mode))
-@@ -684,8 +684,7 @@ static struct file *__dentry_open(struct
- 	}
- 
- 	f->f_mapping = inode->i_mapping;
--	f->f_path.dentry = dentry;
--	f->f_path.mnt = mnt;
-+	f->f_path = *path;
- 	f->f_pos = 0;
- 	f->f_op = fops_get(inode->i_fop);
- 	file_sb_list_add(f, inode->i_sb);
-@@ -731,7 +730,7 @@ cleanup_all:
- 			 * here, so just reset the state.
- 			 */
- 			file_reset_write(f);
--			mnt_drop_write(mnt);
-+			mnt_drop_write(path->mnt);
- 		}
- 	}
- 	file_sb_list_del(f);
-@@ -739,8 +738,7 @@ cleanup_all:
- 	f->f_path.mnt = NULL;
- cleanup_file:
- 	put_filp(f);
--	dput(dentry);
--	mntput(mnt);
-+	path_put(path);
- 	return ERR_PTR(error);
- }
- 
-@@ -766,14 +764,14 @@ cleanup_file:
- struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
- 		int (*open)(struct inode *, struct file *))
- {
-+	struct path path = { .dentry = dentry, .mnt = nd->path.mnt };
- 	const struct cred *cred = current_cred();
- 
- 	if (IS_ERR(nd->intent.open.file))
- 		goto out;
- 	if (IS_ERR(dentry))
- 		goto out_err;
--	nd->intent.open.file = __dentry_open(dget(dentry), mntget(nd->path.mnt),
--					     nd->intent.open.file,
-+	nd->intent.open.file = __dentry_open(&path, nd->intent.open.file,
- 					     open, cred);
- out:
- 	return nd->intent.open.file;
-@@ -802,10 +800,17 @@ struct file *nameidata_to_filp(struct na
- 
- 	/* Has the filesystem initialised the file for us? */
- 	if (filp->f_path.dentry == NULL) {
--		path_get(&nd->path);
--		filp = __dentry_open(nd->path.dentry, nd->path.mnt, filp,
--				     NULL, cred);
-+		struct inode *inode = nd->path.dentry->d_inode;
-+
-+		if (inode->i_op->open) {
-+			int flags = filp->f_flags;
-+			put_filp(filp);
-+			filp = inode->i_op->open(nd->path.dentry, flags, cred);
-+		} else {
-+			filp = __dentry_open(&nd->path, filp, NULL, cred);
-+		}
- 	}
-+
- 	return filp;
- }
- 
-@@ -816,35 +821,45 @@ struct file *nameidata_to_filp(struct na
- struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags,
- 			 const struct cred *cred)
- {
--	int error;
-+	struct path path = { .dentry = dentry, .mnt = mnt };
-+	struct file *ret;
-+
-+	BUG_ON(!mnt);
-+
-+	ret = vfs_open(&path, flags, cred);
-+	path_put(&path);
-+
-+	return ret;
-+}
-+EXPORT_SYMBOL(dentry_open);
-+
-+/**
-+ * vfs_open - open the file at the given path
-+ * @path: path to open
-+ * @flags: open flags
-+ * @cred: credentials to use
-+ *
-+ * Open the file.  If successful, the returned file will have acquired
-+ * an additional reference for path.
-+ */
-+struct file *vfs_open(struct path *path, int flags, const struct cred *cred)
-+{
- 	struct file *f;
-+	struct inode *inode = path->dentry->d_inode;
- 
- 	validate_creds(cred);
- 
--	/*
--	 * We must always pass in a valid mount pointer.   Historically
--	 * callers got away with not passing it, but we must enforce this at
--	 * the earliest possible point now to avoid strange problems deep in the
--	 * filesystem stack.
--	 */
--	if (!mnt) {
--		printk(KERN_WARNING "%s called with NULL vfsmount\n", __func__);
--		dump_stack();
--		return ERR_PTR(-EINVAL);
--	}
-+	if (inode->i_op->open)
-+		return inode->i_op->open(path->dentry, flags, cred);
- 
--	error = -ENFILE;
- 	f = get_empty_filp();
--	if (f == NULL) {
--		dput(dentry);
--		mntput(mnt);
--		return ERR_PTR(error);
--	}
-+	if (f == NULL)
-+		return ERR_PTR(-ENFILE);
- 
- 	f->f_flags = flags;
--	return __dentry_open(dentry, mnt, f, NULL, cred);
-+	return __dentry_open(path, f, NULL, cred);
- }
--EXPORT_SYMBOL(dentry_open);
-+EXPORT_SYMBOL(vfs_open);
- 
- static void __put_unused_fd(struct files_struct *files, unsigned int fd)
- {
---- /dev/null
-+++ b/fs/overlayfs/Kconfig
-@@ -0,0 +1,4 @@
-+config OVERLAYFS_FS
-+	tristate "Overlay filesystem support"
-+	help
-+	  Add support for overlay filesystem.
---- /dev/null
-+++ b/fs/overlayfs/Makefile
-@@ -0,0 +1,5 @@
-+#
-+# Makefile for the overlay filesystem.
-+#
-+
-+obj-$(CONFIG_OVERLAYFS_FS) += overlayfs.o
---- /dev/null
-+++ b/fs/overlayfs/overlayfs.c
-@@ -0,0 +1,2358 @@
-+#include <linux/fs.h>
-+#include <linux/namei.h>
-+#include <linux/sched.h>
-+#include <linux/fs_struct.h>
-+#include <linux/file.h>
-+#include <linux/xattr.h>
-+#include <linux/security.h>
-+#include <linux/device_cgroup.h>
-+#include <linux/mount.h>
-+#include <linux/splice.h>
-+#include <linux/slab.h>
-+#include <linux/parser.h>
-+#include <linux/module.h>
-+#include <linux/uaccess.h>
-+#include <linux/rbtree.h>
-+
-+MODULE_AUTHOR("Miklos Szeredi <miklos@szeredi.hu>");
-+MODULE_DESCRIPTION("Overlay filesystem");
-+MODULE_LICENSE("GPL");
-+
-+#define OVL_COPY_UP_CHUNK_SIZE (1 << 20)
-+
-+struct ovl_fs {
-+	struct vfsmount *upper_mnt;
-+	struct vfsmount *lower_mnt;
-+};
-+
-+struct ovl_entry {
-+	struct dentry *__upperdentry;
-+	struct dentry *lowerdentry;
-+	union {
-+		struct {
-+			u64 version;
-+			bool opaque;
-+		};
-+		struct rcu_head rcu;
-+	};
-+};
-+
-+static const char *ovl_whiteout_xattr = "trusted.overlay.whiteout";
-+static const char *ovl_opaque_xattr = "trusted.overlay.opaque";
-+static const char *ovl_whiteout_symlink = "(overlay-whiteout)";
-+
-+enum ovl_path_type {
-+	OVL_PATH_UPPER,
-+	OVL_PATH_MERGE,
-+	OVL_PATH_LOWER,
-+};
-+
-+static enum ovl_path_type ovl_path_type(struct dentry *dentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	if (oe->__upperdentry) {
-+		if (oe->lowerdentry && S_ISDIR(dentry->d_inode->i_mode))
-+			return OVL_PATH_MERGE;
-+		else
-+			return OVL_PATH_UPPER;
-+	} else {
-+		return OVL_PATH_LOWER;
-+	}
-+}
-+
-+static struct dentry *ovl_upperdentry_dereference(struct ovl_entry *oe)
-+{
-+	struct dentry *upperdentry = ACCESS_ONCE(oe->__upperdentry);
-+	smp_read_barrier_depends();
-+	return upperdentry;
-+}
-+
-+static void ovl_path_upper(struct dentry *dentry, struct path *path)
-+{
-+	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	path->mnt = ofs->upper_mnt;
-+	path->dentry = ovl_upperdentry_dereference(oe);
-+}
-+
-+static void ovl_path_lower(struct dentry *dentry, struct path *path)
-+{
-+	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	path->mnt = ofs->lower_mnt;
-+	path->dentry = oe->lowerdentry;
-+}
-+
-+static enum ovl_path_type ovl_path_real(struct dentry *dentry,
-+					struct path *path)
-+{
-+
-+	enum ovl_path_type type = ovl_path_type(dentry);
-+
-+	if (type == OVL_PATH_LOWER)
-+		ovl_path_lower(dentry, path);
-+	else
-+		ovl_path_upper(dentry, path);
-+
-+	return type;
-+}
-+
-+static struct dentry *ovl_dentry_upper(struct dentry *dentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	return ovl_upperdentry_dereference(oe);
-+}
-+
-+static struct dentry *ovl_dentry_lower(struct dentry *dentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	return oe->lowerdentry;
-+}
-+
-+static struct dentry *ovl_dentry_real(struct dentry *dentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+	struct dentry *realdentry;
-+
-+	realdentry = ovl_upperdentry_dereference(oe);
-+	if (!realdentry)
-+		realdentry = oe->lowerdentry;
-+
-+	return realdentry;
-+}
-+
-+static bool ovl_dentry_is_opaque(struct dentry *dentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+	return oe->opaque;
-+}
-+
-+static void ovl_dentry_set_opaque(struct dentry *dentry, bool opaque)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+	oe->opaque = opaque;
-+}
-+
-+static void ovl_dentry_update(struct dentry *dentry, struct dentry *upperdentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	WARN_ON(!mutex_is_locked(&upperdentry->d_parent->d_inode->i_mutex));
-+	WARN_ON(oe->__upperdentry);
-+	smp_wmb();
-+	oe->__upperdentry = upperdentry;
-+}
-+
-+static void ovl_dentry_version_inc(struct dentry *dentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	WARN_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
-+	oe->version++;
-+}
-+
-+static u64 ovl_dentry_version_get(struct dentry *dentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	WARN_ON(!mutex_is_locked(&dentry->d_inode->i_mutex));
-+	return oe->version;
-+}
-+
-+static bool ovl_is_whiteout(struct dentry *dentry)
-+{
-+	int res;
-+	char val;
-+
-+	if (!dentry)
-+		return false;
-+	if (!dentry->d_inode)
-+		return false;
-+	if (!S_ISLNK(dentry->d_inode->i_mode))
-+		return false;
-+
-+	res = vfs_getxattr(dentry, ovl_whiteout_xattr, &val, 1);
-+	if (res == 1 && val == 'y')
-+		return true;
-+
-+	return false;
-+}
-+
-+static bool ovl_is_opaquedir(struct dentry *dentry)
-+{
-+	int res;
-+	char val;
-+
-+	if (!S_ISDIR(dentry->d_inode->i_mode))
-+		return false;
-+
-+	res = vfs_getxattr(dentry, ovl_opaque_xattr, &val, 1);
-+	if (res == 1 && val == 'y')
-+		return true;
-+
-+	return false;
-+}
-+
-+struct ovl_cache_entry {
-+	const char *name;
-+	unsigned int len;
-+	unsigned int type;
-+	u64 ino;
-+	bool is_whiteout;
-+	struct list_head l_node;
-+	struct rb_node node;
-+};
-+
-+struct ovl_readdir_data {
-+	struct rb_root *root;
-+	struct list_head *list;
-+	struct list_head *middle;
-+	struct dentry *dir;
-+	int count;
-+	int err;
-+};
-+
-+struct ovl_dir_file {
-+	bool is_real;
-+	bool is_cached;
-+	struct list_head cursor;
-+	u64 cache_version;
-+	struct list_head cache;
-+	struct file *realfile;
-+};
-+
-+static struct ovl_cache_entry *ovl_cache_entry_from_node(struct rb_node *n)
-+{
-+	return container_of(n, struct ovl_cache_entry, node);
-+}
-+
-+static struct ovl_cache_entry *ovl_cache_entry_find(struct rb_root *root,
-+						    const char *name, int len)
-+{
-+	struct rb_node *node = root->rb_node;
-+	int cmp;
-+
-+	while (node) {
-+		struct ovl_cache_entry *p = ovl_cache_entry_from_node(node);
-+
-+		cmp = strncmp(name, p->name, len);
-+		if (cmp > 0)
-+			node = p->node.rb_right;
-+		else if (cmp < 0 || len < p->len)
-+			node = p->node.rb_left;
-+		else
-+			return p;
-+	}
-+
-+	return NULL;
-+}
-+
-+static struct ovl_cache_entry *ovl_cache_entry_new(const char *name, int len,
-+						   u64 ino, unsigned int d_type,
-+						   bool is_whiteout)
-+{
-+	struct ovl_cache_entry *p;
-+
-+	p = kmalloc(sizeof(*p) + len + 1, GFP_KERNEL);
-+	if (p) {
-+		char *name_copy = (char *) (p + 1);
-+		memcpy(name_copy, name, len);
-+		name_copy[len] = '\0';
-+		p->name = name_copy;
-+		p->len = len;
-+		p->type = d_type;
-+		p->ino = ino;
-+		p->is_whiteout = is_whiteout;
-+	}
-+
-+	return p;
-+}
-+
-+static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
-+				  const char *name, int len, u64 ino,
-+				  unsigned int d_type, bool is_whiteout)
-+{
-+	struct rb_node **newp = &rdd->root->rb_node;
-+	struct rb_node *parent = NULL;
-+	struct ovl_cache_entry *p;
-+
-+	while (*newp) {
-+		int cmp;
-+		struct ovl_cache_entry *tmp;
-+
-+		parent = *newp;
-+		tmp = ovl_cache_entry_from_node(*newp);
-+		cmp = strncmp(name, tmp->name, len);
-+		if (cmp > 0)
-+			newp = &tmp->node.rb_right;
-+		else if (cmp < 0 || len < tmp->len)
-+			newp = &tmp->node.rb_left;
-+		else
-+			return 0;
-+	}
-+
-+	p = ovl_cache_entry_new(name, len, ino, d_type, is_whiteout);
-+	if (p == NULL)
-+		return -ENOMEM;
-+
-+	list_add_tail(&p->l_node, rdd->list);
-+	rb_link_node(&p->node, parent, newp);
-+	rb_insert_color(&p->node, rdd->root);
-+
-+	return 0;
-+}
-+
-+static int ovl_fill_lower(void *buf, const char *name, int namelen,
-+			    loff_t offset, u64 ino, unsigned int d_type)
-+{
-+	struct ovl_readdir_data *rdd = buf;
-+	struct ovl_cache_entry *p;
-+
-+	rdd->count++;
-+	p = ovl_cache_entry_find(rdd->root, name, namelen);
-+	if (p) {
-+		list_move_tail(&p->l_node, rdd->middle);
-+	} else {
-+		p = ovl_cache_entry_new(name, namelen, ino, d_type, false);
-+		if (p == NULL)
-+			rdd->err = -ENOMEM;
-+		else
-+			list_add_tail(&p->l_node, rdd->middle);
-+	}
-+
-+	return rdd->err;
-+}
-+
-+static void ovl_cache_free(struct list_head *list)
-+{
-+	struct ovl_cache_entry *p;
-+	struct ovl_cache_entry *n;
-+
-+	list_for_each_entry_safe(p, n, list, l_node)
-+		kfree(p);
-+
-+	INIT_LIST_HEAD(list);
-+}
-+
-+static int ovl_fill_upper(void *buf, const char *name, int namelen,
-+			  loff_t offset, u64 ino, unsigned int d_type)
-+{
-+	struct ovl_readdir_data *rdd = buf;
-+	bool is_whiteout = false;
-+
-+	rdd->count++;
-+	if (d_type == DT_LNK) {
-+		struct dentry *dentry;
-+
-+		dentry = lookup_one_len(name, rdd->dir, namelen);
-+		if (IS_ERR(dentry)) {
-+			rdd->err = PTR_ERR(dentry);
-+			goto out;
-+		}
-+		is_whiteout = ovl_is_whiteout(dentry);
-+		dput(dentry);
-+	}
-+
-+	rdd->err = ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type,
-+					  is_whiteout);
-+
-+out:
-+	return rdd->err;
-+}
-+
-+static int ovl_dir_read(struct path *realpath, struct ovl_readdir_data *rdd,
-+			  filldir_t filler)
-+{
-+	const struct cred *old_cred;
-+	struct cred *override_cred;
-+	struct file *realfile;
-+	int err;
-+
-+	realfile = vfs_open(realpath, O_RDONLY | O_DIRECTORY, current_cred());
-+	if (IS_ERR(realfile))
-+		return PTR_ERR(realfile);
-+
-+	err = -ENOMEM;
-+	override_cred = prepare_creds();
-+	if (override_cred) {
-+		/*
-+		 * CAP_SYS_ADMIN for getxattr
-+		 * CAP_DAC_OVERRIDE for lookup and unlink
-+		 */
-+		cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-+		cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
-+		old_cred = override_creds(override_cred);
-+
-+		do {
-+			rdd->count = 0;
-+			rdd->err = 0;
-+			err = vfs_readdir(realfile, filler, rdd);
-+			if (err >= 0)
-+				err = rdd->err;
-+		} while (!err && rdd->count);
-+
-+		revert_creds(old_cred);
-+		put_cred(override_cred);
-+	}
-+	fput(realfile);
-+
-+	if (err) {
-+		if (rdd->list)
-+			ovl_cache_free(rdd->list);
-+		return err;
-+	}
-+
-+	return 0;
-+}
-+
-+static void ovl_dir_reset(struct file *file)
-+{
-+	struct ovl_dir_file *od = file->private_data;
-+	enum ovl_path_type type = ovl_path_type(file->f_path.dentry);
-+
-+	if (ovl_dentry_version_get(file->f_path.dentry) != od->cache_version) {
-+		list_del_init(&od->cursor);
-+		ovl_cache_free(&od->cache);
-+		od->is_cached = false;
-+	}
-+	WARN_ON(!od->is_real && type != OVL_PATH_MERGE);
-+	if (od->is_real && type == OVL_PATH_MERGE) {
-+		fput(od->realfile);
-+		od->realfile = NULL;
-+		od->is_real = false;
-+	}
-+}
-+
-+static int ovl_dir_read_merged(struct path *upperpath, struct path *lowerpath,
-+			       struct ovl_readdir_data *rdd)
-+{
-+	int err;
-+	struct rb_root root = RB_ROOT;
-+	struct list_head middle;
-+
-+	rdd->root = &root;
-+	if (upperpath->dentry) {
-+		rdd->dir = upperpath->dentry;
-+		err = ovl_dir_read(upperpath, rdd, ovl_fill_upper);
-+		if (err)
-+			goto out;
-+	}
-+	/*
-+	 * Insert lowerpath entries before upperpath ones, this allows
-+	 * offsets to be reasonably constant
-+	 */
-+	list_add(&middle, rdd->list);
-+	rdd->middle = &middle;
-+	err = ovl_dir_read(lowerpath, rdd, ovl_fill_lower);
-+	list_del(&middle);
-+out:
-+	rdd->root = NULL;
-+
-+	return err;
-+}
-+
-+static void ovl_seek_cursor(struct ovl_dir_file *od, loff_t pos)
-+{
-+	struct list_head *l;
-+	loff_t off;
-+
-+	l = od->cache.next;
-+	for (off = 0; off < pos; off++) {
-+		if (l == &od->cache)
-+			break;
-+		l = l->next;
-+	}
-+	list_move_tail(&od->cursor, l);
-+}
-+
-+static int ovl_readdir(struct file *file, void *buf, filldir_t filler)
-+{
-+	struct ovl_dir_file *od = file->private_data;
-+	int res;
-+
-+	if (!file->f_pos)
-+		ovl_dir_reset(file);
-+
-+	if (od->is_real) {
-+		res = vfs_readdir(od->realfile, filler, buf);
-+		file->f_pos = od->realfile->f_pos;
-+
-+		return res;
-+	}
-+
-+	if (!od->is_cached) {
-+		struct path lowerpath;
-+		struct path upperpath;
-+		struct ovl_readdir_data rdd = { .list = &od->cache };
-+
-+		ovl_path_lower(file->f_path.dentry, &lowerpath);
-+		ovl_path_upper(file->f_path.dentry, &upperpath);
-+
-+		res = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd);
-+		if (res)
-+			return res;
-+
-+		od->cache_version = ovl_dentry_version_get(file->f_path.dentry);
-+		od->is_cached = true;
-+
-+		ovl_seek_cursor(od, file->f_pos);
-+	}
-+
-+	while (od->cursor.next != &od->cache) {
-+		int over;
-+		loff_t off;
-+		struct ovl_cache_entry *p;
-+
-+		p = list_entry(od->cursor.next, struct ovl_cache_entry, l_node);
-+		off = file->f_pos;
-+		file->f_pos++;
-+		list_move(&od->cursor, &p->l_node);
-+
-+		if (p->is_whiteout)
-+			continue;
-+
-+		over = filler(buf, p->name, p->len, off, p->ino, p->type);
-+		if (over)
-+			break;
-+	}
-+
-+	return 0;
-+}
-+
-+static loff_t ovl_dir_llseek(struct file *file, loff_t offset, int origin)
-+{
-+	loff_t res;
-+	struct ovl_dir_file *od = file->private_data;
-+
-+	mutex_lock(&file->f_dentry->d_inode->i_mutex);
-+	if (!file->f_pos)
-+		ovl_dir_reset(file);
-+
-+	if (od->is_real) {
-+		res = vfs_llseek(od->realfile, offset, origin);
-+		file->f_pos = od->realfile->f_pos;
-+	} else {
-+		res = -EINVAL;
-+
-+		switch (origin) {
-+		case SEEK_CUR:
-+			offset += file->f_pos;
-+			break;
-+		case SEEK_SET:
-+			break;
-+		default:
-+			goto out_unlock;
-+		}
-+		if (offset < 0)
-+			goto out_unlock;
-+
-+		if (offset != file->f_pos) {
-+			file->f_pos = offset;
-+			if (od->is_cached)
-+				ovl_seek_cursor(od, offset);
-+		}
-+		res = offset;
-+	}
-+out_unlock:
-+	mutex_unlock(&file->f_dentry->d_inode->i_mutex);
-+
-+	return res;
-+}
-+
-+static int ovl_dir_fsync(struct file *file, int datasync)
-+{
-+	struct ovl_dir_file *od = file->private_data;
-+
-+	/* May need to reopen directory if it got copied up */
-+	if (!od->realfile) {
-+		struct path upperpath;
-+
-+		ovl_path_upper(file->f_path.dentry, &upperpath);
-+		od->realfile = vfs_open(&upperpath, O_RDONLY, current_cred());
-+		if (IS_ERR(od->realfile))
-+			return PTR_ERR(od->realfile);
-+	}
-+
-+	return vfs_fsync(od->realfile, datasync);
-+}
-+
-+static int ovl_dir_release(struct inode *inode, struct file *file)
-+{
-+	struct ovl_dir_file *od = file->private_data;
-+
-+	list_del(&od->cursor);
-+	ovl_cache_free(&od->cache);
-+	if (od->realfile)
-+		fput(od->realfile);
-+	kfree(od);
-+
-+	return 0;
-+}
-+
-+static int ovl_dir_open(struct inode *inode, struct file *file)
-+{
-+	struct path realpath;
-+	struct file *realfile;
-+	struct ovl_dir_file *od;
-+	enum ovl_path_type type;
-+
-+	od = kzalloc(sizeof(struct ovl_dir_file), GFP_KERNEL);
-+	if (!od)
-+		return -ENOMEM;
-+
-+	type = ovl_path_real(file->f_path.dentry, &realpath);
-+	realfile = vfs_open(&realpath, file->f_flags, current_cred());
-+	if (IS_ERR(realfile)) {
-+		kfree(od);
-+		return PTR_ERR(realfile);
-+	}
-+	INIT_LIST_HEAD(&od->cache);
-+	INIT_LIST_HEAD(&od->cursor);
-+	od->is_cached = false;
-+	od->realfile = realfile;
-+	od->is_real = (type != OVL_PATH_MERGE);
-+	file->private_data = od;
-+
-+	return 0;
-+}
-+
-+static const struct file_operations ovl_dir_operations = {
-+	.read		= generic_read_dir,
-+	.open		= ovl_dir_open,
-+	.readdir	= ovl_readdir,
-+	.llseek		= ovl_dir_llseek,
-+	.fsync		= ovl_dir_fsync,
-+	.release	= ovl_dir_release,
-+};
-+
-+static const struct inode_operations ovl_dir_inode_operations;
-+
-+static void ovl_entry_free(struct rcu_head *head)
-+{
-+	struct ovl_entry *oe = container_of(head, struct ovl_entry, rcu);
-+	kfree(oe);
-+}
-+
-+static void ovl_dentry_release(struct dentry *dentry)
-+{
-+	struct ovl_entry *oe = dentry->d_fsdata;
-+
-+	if (oe) {
-+		dput(oe->__upperdentry);
-+		dput(oe->lowerdentry);
-+		call_rcu(&oe->rcu, ovl_entry_free);
-+	}
-+}
-+
-+static const struct dentry_operations ovl_dentry_operations = {
-+	.d_release = ovl_dentry_release,
-+};
-+
-+static struct dentry *ovl_lookup_real(struct dentry *dir, struct qstr *name)
-+{
-+	struct dentry *dentry;
-+
-+	mutex_lock(&dir->d_inode->i_mutex);
-+	dentry = lookup_one_len(name->name, dir, name->len);
-+	mutex_unlock(&dir->d_inode->i_mutex);
-+
-+	if (IS_ERR(dentry)) {
-+		if (PTR_ERR(dentry) == -ENOENT)
-+			dentry = NULL;
-+	} else if (!dentry->d_inode) {
-+		dput(dentry);
-+		dentry = NULL;
-+	}
-+	return dentry;
-+}
-+
-+static struct ovl_entry *ovl_alloc_entry(void)
-+{
-+	return kzalloc(sizeof(struct ovl_entry), GFP_KERNEL);
-+}
-+
-+static struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
-+				   struct ovl_entry *oe);
-+
-+static struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
-+				   struct nameidata *nd)
-+{
-+	struct ovl_entry *oe;
-+	struct dentry *upperdir;
-+	struct dentry *lowerdir;
-+	struct dentry *upperdentry = NULL;
-+	struct dentry *lowerdentry = NULL;
-+	struct inode *inode = NULL;
-+	int err;
-+
-+	err = -ENOMEM;
-+	oe = ovl_alloc_entry();
-+	if (!oe)
-+		goto out;
-+
-+	upperdir = ovl_dentry_upper(dentry->d_parent);
-+	lowerdir = ovl_dentry_lower(dentry->d_parent);
-+
-+	if (upperdir) {
-+		upperdentry = ovl_lookup_real(upperdir, &dentry->d_name);
-+		err = PTR_ERR(upperdentry);
-+		if (IS_ERR(upperdentry))
-+			goto out_put_dir;
-+
-+		if (lowerdir && upperdentry &&
-+		    (S_ISLNK(upperdentry->d_inode->i_mode) ||
-+		     S_ISDIR(upperdentry->d_inode->i_mode))) {
-+			const struct cred *old_cred;
-+			struct cred *override_cred;
-+
-+			err = -ENOMEM;
-+			override_cred = prepare_creds();
-+			if (!override_cred)
-+				goto out_dput_upper;
-+
-+			/* CAP_SYS_ADMIN needed for getxattr */
-+			cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-+			old_cred = override_creds(override_cred);
-+
-+			if (ovl_is_opaquedir(upperdentry)) {
-+				oe->opaque = true;
-+			} else if (ovl_is_whiteout(upperdentry)) {
-+				dput(upperdentry);
-+				upperdentry = NULL;
-+				oe->opaque = true;
-+			}
-+			revert_creds(old_cred);
-+			put_cred(override_cred);
-+		}
-+	}
-+	if (lowerdir && !oe->opaque) {
-+		lowerdentry = ovl_lookup_real(lowerdir, &dentry->d_name);
-+		err = PTR_ERR(lowerdentry);
-+		if (IS_ERR(lowerdentry))
-+			goto out_dput_upper;
-+	}
-+
-+	if (lowerdentry && upperdentry &&
-+	    (!S_ISDIR(upperdentry->d_inode->i_mode) ||
-+	     !S_ISDIR(lowerdentry->d_inode->i_mode))) {
-+		dput(lowerdentry);
-+		lowerdentry = NULL;
-+		oe->opaque = true;
-+	}
-+
-+	if (lowerdentry || upperdentry) {
-+		struct dentry *realdentry;
-+
-+		realdentry = upperdentry ? upperdentry : lowerdentry;
-+		err = -ENOMEM;
-+		inode = ovl_new_inode(dir->i_sb, realdentry->d_inode->i_mode, oe);
-+		if (!inode)
-+			goto out_dput;
-+	}
-+
-+	if (upperdentry)
-+		oe->__upperdentry = upperdentry;
-+
-+	if (lowerdentry)
-+		oe->lowerdentry = lowerdentry;
-+
-+	dentry->d_fsdata = oe;
-+	dentry->d_op = &ovl_dentry_operations;
-+	d_add(dentry, inode);
-+
-+	return NULL;
-+
-+out_dput:
-+	dput(lowerdentry);
-+out_dput_upper:
-+	dput(upperdentry);
-+out_put_dir:
-+	kfree(oe);
-+out:
-+	return ERR_PTR(err);
-+}
-+
-+static int ovl_copy_up_xattr(struct dentry *old, struct dentry *new)
-+{
-+	ssize_t list_size, size;
-+	char *buf, *name, *value;
-+	int error;
-+
-+	if (!old->d_inode->i_op->getxattr ||
-+	    !new->d_inode->i_op->getxattr)
-+		return 0;
-+
-+	list_size = vfs_listxattr(old, NULL, 0);
-+	if (list_size <= 0) {
-+		if (list_size == -EOPNOTSUPP)
-+			return 0;
-+		return list_size;
-+	}
-+
-+	buf = kzalloc(list_size, GFP_KERNEL);
-+	if (!buf)
-+		return -ENOMEM;
-+
-+	error = -ENOMEM;
-+	value = kmalloc(XATTR_SIZE_MAX, GFP_KERNEL);
-+	if (!value)
-+		goto out;
-+
-+	list_size = vfs_listxattr(old, buf, list_size);
-+	if (list_size <= 0) {
-+		error = list_size;
-+		goto out_free_value;
-+	}
-+
-+	for (name = buf; name < (buf + list_size); name += strlen(name) + 1) {
-+		size = vfs_getxattr(old, name, value, XATTR_SIZE_MAX);
-+		if (size <= 0) {
-+			error = size;
-+			goto out_free_value;
-+		}
-+		error = vfs_setxattr(new, name, value, size, 0);
-+		if (error)
-+			goto out_free_value;
-+	}
-+
-+out_free_value:
-+	kfree(value);
-+out:
-+	kfree(buf);
-+	return error;
-+}
-+
-+static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
-+{
-+	struct file *old_file;
-+	struct file *new_file;
-+	int error = 0;
-+
-+	if (len == 0)
-+		return 0;
-+
-+	old_file = vfs_open(old, O_RDONLY, current_cred());
-+	if (IS_ERR(old_file))
-+		return PTR_ERR(old_file);
-+
-+	new_file = vfs_open(new, O_WRONLY, current_cred());
-+	if (IS_ERR(new_file)) {
-+		error = PTR_ERR(new_file);
-+		goto out_fput;
-+	}
-+
-+	/* FIXME: copy up sparse files efficiently */
-+	while (len) {
-+		loff_t offset = new_file->f_pos;
-+		size_t this_len = OVL_COPY_UP_CHUNK_SIZE;
-+		long bytes;
-+
-+		if (len < this_len)
-+			this_len = len;
-+
-+		if (signal_pending_state(TASK_KILLABLE, current))
-+			return -EINTR;
-+
-+		bytes = do_splice_direct(old_file, &offset, new_file, this_len,
-+				 SPLICE_F_MOVE);
-+		if (bytes <= 0) {
-+			error = bytes;
-+			break;
-+		}
-+
-+		len -= bytes;
-+	}
-+
-+	fput(new_file);
-+out_fput:
-+	fput(old_file);
-+	return error;
-+}
-+
-+static struct dentry *ovl_lookup_create(struct dentry *upperdir,
-+					struct dentry *template)
-+{
-+	int err;
-+	struct dentry *newdentry;
-+	struct qstr *name = &template->d_name;
-+
-+	newdentry = lookup_one_len(name->name, upperdir, name->len);
-+	if (IS_ERR(newdentry))
-+		return newdentry;
-+
-+	if (newdentry->d_inode) {
-+		const struct cred *old_cred;
-+		struct cred *override_cred;
-+
-+		/* No need to check whiteout if lower parent is non-existent */
-+		err = -EEXIST;
-+		if (!ovl_dentry_lower(template->d_parent))
-+			goto out_dput;
-+
-+		if (!S_ISLNK(newdentry->d_inode->i_mode))
-+			goto out_dput;
-+
-+		err = -ENOMEM;
-+		override_cred = prepare_creds();
-+		if (!override_cred)
-+			goto out_dput;
-+
-+		/*
-+		 * CAP_SYS_ADMIN for getxattr
-+		 * CAP_FOWNER for unlink in sticky directory
-+		 */
-+		cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-+		cap_raise(override_cred->cap_effective, CAP_FOWNER);
-+		old_cred = override_creds(override_cred);
-+
-+		err = -EEXIST;
-+		if (ovl_is_whiteout(newdentry))
-+			err = vfs_unlink(upperdir->d_inode, newdentry);
-+
-+		revert_creds(old_cred);
-+		put_cred(override_cred);
-+		if (err)
-+			goto out_dput;
-+
-+		dput(newdentry);
-+		newdentry = lookup_one_len(name->name, upperdir, name->len);
-+		if (IS_ERR(newdentry))
-+			return newdentry;
-+
-+		/*
-+		 * Whiteout just been successfully removed, parent
-+		 * i_mutex is still held, there's no way the lookup
-+		 * could return positive.
-+		 */
-+		WARN_ON(newdentry->d_inode);
-+	}
-+
-+	return newdentry;
-+
-+out_dput:
-+	dput(newdentry);
-+	return ERR_PTR(err);
-+}
-+
-+static struct dentry *ovl_upper_create(struct dentry *upperdir,
-+				       struct dentry *dentry,
-+				       struct kstat *stat, const char *link)
-+{
-+	int err;
-+	struct dentry *newdentry;
-+	struct inode *dir = upperdir->d_inode;
-+
-+	newdentry = ovl_lookup_create(upperdir, dentry);
-+	if (IS_ERR(newdentry))
-+		goto out;
-+
-+	switch (stat->mode & S_IFMT) {
-+	case S_IFREG:
-+		err = vfs_create(dir, newdentry, stat->mode, NULL);
-+		break;
-+
-+	case S_IFDIR:
-+		err = vfs_mkdir(dir, newdentry, stat->mode);
-+		break;
-+
-+	case S_IFCHR:
-+	case S_IFBLK:
-+	case S_IFIFO:
-+	case S_IFSOCK:
-+		err = vfs_mknod(dir, newdentry, stat->mode, stat->rdev);
-+		break;
-+
-+	case S_IFLNK:
-+		err = vfs_symlink(dir, newdentry, link);
-+		break;
-+
-+	default:
-+		err = -EPERM;
-+	}
-+	if (err) {
-+		dput(newdentry);
-+		newdentry = ERR_PTR(err);
-+	}
-+
-+out:
-+	return newdentry;
-+
-+}
-+
-+static char *ovl_read_symlink(struct dentry *realdentry)
-+{
-+	int res;
-+	char *buf;
-+	struct inode *inode = realdentry->d_inode;
-+	mm_segment_t old_fs;
-+
-+	res = -EINVAL;
-+	if (!inode->i_op->readlink)
-+		goto err;
-+
-+	res = -ENOMEM;
-+	buf = (char *) __get_free_page(GFP_KERNEL);
-+	if (!buf)
-+		goto err;
-+
-+	old_fs = get_fs();
-+	set_fs(get_ds());
-+	/* The cast to a user pointer is valid due to the set_fs() */
-+	res = inode->i_op->readlink(realdentry,
-+				    (char __user *)buf, PAGE_SIZE - 1);
-+	set_fs(old_fs);
-+	if (res < 0) {
-+		free_page((unsigned long) buf);
-+		goto err;
-+	}
-+	buf[res] = '\0';
-+
-+	return buf;
-+
-+err:
-+	return ERR_PTR(res);
-+}
-+
-+static int ovl_set_timestamps(struct dentry *upperdentry, struct kstat *stat)
-+{
-+	struct iattr attr = {
-+		.ia_valid = ATTR_ATIME | ATTR_MTIME | ATTR_ATIME_SET | ATTR_MTIME_SET,
-+		.ia_atime = stat->atime,
-+		.ia_mtime = stat->mtime,
-+	};
-+
-+	return notify_change(upperdentry, &attr);
-+}
-+
-+static int ovl_set_mode(struct dentry *upperdentry, umode_t mode)
-+{
-+	struct iattr attr = {
-+		.ia_valid = ATTR_MODE,
-+		.ia_mode = mode,
-+	};
-+
-+	return notify_change(upperdentry, &attr);
-+}
-+
-+static int ovl_set_opaque(struct dentry *upperdentry)
-+{
-+	int err;
-+	const struct cred *old_cred;
-+	struct cred *override_cred;
-+
-+	override_cred = prepare_creds();
-+	if (!override_cred)
-+		return -ENOMEM;
-+
-+	/* CAP_SYS_ADMIN for setxattr of "trusted" namespace */
-+	cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-+	old_cred = override_creds(override_cred);
-+	err = vfs_setxattr(upperdentry, ovl_opaque_xattr, "y", 1, 0);
-+	revert_creds(old_cred);
-+	put_cred(override_cred);
-+
-+	return err;
-+}
-+
-+static int ovl_remove_opaque(struct dentry *upperdentry)
-+{
-+	int err;
-+	const struct cred *old_cred;
-+	struct cred *override_cred;
-+
-+	override_cred = prepare_creds();
-+	if (!override_cred)
-+		return -ENOMEM;
-+
-+	/* CAP_SYS_ADMIN for removexattr of "trusted" namespace */
-+	cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-+	old_cred = override_creds(override_cred);
-+	err = vfs_removexattr(upperdentry, ovl_opaque_xattr);
-+	revert_creds(old_cred);
-+	put_cred(override_cred);
-+
-+	return err;
-+}
-+
-+static int ovl_copy_up_locked(struct dentry *upperdir, struct dentry *dentry,
-+			      struct path *lowerpath, struct kstat *stat,
-+			      const char *link)
-+{
-+	int err;
-+	struct path newpath;
-+	umode_t mode = stat->mode;
-+	struct ovl_fs *ofs = dentry->d_sb->s_fs_info;
-+
-+	/* Can't properly set mode on creation because of the umask */
-+	stat->mode &= S_IFMT;
-+
-+	newpath.mnt = ofs->upper_mnt;
-+	newpath.dentry = ovl_upper_create(upperdir, dentry, stat, link);
-+	if (IS_ERR(newpath.dentry)) {
-+		err = PTR_ERR(newpath.dentry);
-+
-+		/* Already copied up? */
-+		if (err == -EEXIST && ovl_path_type(dentry) != OVL_PATH_LOWER)
-+			return 0;
-+
-+		return err;
-+	}
-+
-+	/* FIXME: recovery from failure to copy up */
-+
-+	if (S_ISREG(stat->mode)) {
-+		err = ovl_copy_up_data(lowerpath, &newpath, stat->size);
-+		if (err)
-+			return err;
-+	}
-+
-+	err = ovl_copy_up_xattr(lowerpath->dentry, newpath.dentry);
-+	if (err)
-+		return err;
-+
-+	mutex_lock(&newpath.dentry->d_inode->i_mutex);
-+	if (!S_ISLNK(stat->mode))
-+		err = ovl_set_mode(newpath.dentry, mode);
-+	if (!err)
-+		err = ovl_set_timestamps(newpath.dentry, stat);
-+	mutex_unlock(&newpath.dentry->d_inode->i_mutex);
-+	if (err)
-+		return err;
-+
-+	ovl_dentry_update(dentry, newpath.dentry);
-+
-+	/*
-+	 * Easiest way to get rid of the lower dentry reference is to
-+	 * drop this dentry.  This is neither needed nor possible for
-+	 * directories.
-+	 */
-+	if (!S_ISDIR(stat->mode))
-+		d_drop(dentry);
-+
-+	return 0;
-+}
-+
-+static int ovl_copy_up_one(struct dentry *parent, struct dentry *dentry,
-+			   struct path *lowerpath, struct kstat *stat)
-+{
-+	int err;
-+	struct kstat pstat;
-+	struct path parentpath;
-+	struct dentry *upperdir;
-+	const struct cred *old_cred;
-+	struct cred *override_cred;
-+	char *link = NULL;
-+
-+	ovl_path_upper(parent, &parentpath);
-+	upperdir = parentpath.dentry;
-+
-+	err = vfs_getattr(parentpath.mnt, parentpath.dentry, &pstat);
-+	if (err)
-+		return err;
-+
-+	if (S_ISLNK(stat->mode)) {
-+		link = ovl_read_symlink(lowerpath->dentry);
-+		if (IS_ERR(link))
-+			return PTR_ERR(link);
-+	}
-+
-+	err = -ENOMEM;
-+	override_cred = prepare_creds();
-+	if (!override_cred)
-+		goto out_free_link;
-+
-+	override_cred->fsuid = stat->uid;
-+	override_cred->fsgid = stat->gid;
-+	/*
-+	 * CAP_SYS_ADMIN for copying up extended attributes
-+	 * CAP_DAC_OVERRIDE for create
-+	 * CAP_FOWNER for chmod, timestamp update
-+	 * CAP_FSETID for chmod
-+	 * CAP_MKNOD for mknod
-+	 */
-+	cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-+	cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
-+	cap_raise(override_cred->cap_effective, CAP_FOWNER);
-+	cap_raise(override_cred->cap_effective, CAP_FSETID);
-+	cap_raise(override_cred->cap_effective, CAP_MKNOD);
-+	old_cred = override_creds(override_cred);
-+
-+	mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT);
-+	/*
-+	 * Using upper filesystem locking to protect against copy up
-+	 * racing with rename (rename means the copy up was already
-+	 * successful).
-+	 */
-+	if (dentry->d_parent != parent) {
-+		WARN_ON((ovl_path_type(dentry) == OVL_PATH_LOWER));
-+		err = 0;
-+	} else {
-+		err = ovl_copy_up_locked(upperdir, dentry, lowerpath,
-+					 stat, link);
-+		if (!err) {
-+			/* Restore timestamps on parent (best effort) */
-+			ovl_set_timestamps(upperdir, &pstat);
-+		}
-+	}
-+
-+	mutex_unlock(&upperdir->d_inode->i_mutex);
-+
-+	revert_creds(old_cred);
-+	put_cred(override_cred);
-+
-+out_free_link:
-+	if (link)
-+		free_page((unsigned long) link);
-+
-+	return err;
-+}
-+
-+static int ovl_copy_up(struct dentry *dentry)
-+{
-+	int err;
-+
-+	err = 0;
-+	while (!err) {
-+		struct dentry *next;
-+		struct dentry *parent;
-+		struct path lowerpath;
-+		struct kstat stat;
-+		enum ovl_path_type type = ovl_path_type(dentry);
-+
-+		if (type != OVL_PATH_LOWER)
-+			break;
-+
-+		next = dget(dentry);
-+		/* find the topmost dentry not yet copied up */
-+		for (;;) {
-+			parent = dget_parent(next);
-+
-+			type = ovl_path_type(parent);
-+			if (type != OVL_PATH_LOWER)
-+				break;
-+
-+			dput(next);
-+			next = parent;
-+		}
-+
-+		ovl_path_lower(next, &lowerpath);
-+		err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat);
-+		if (!err)
-+			err = ovl_copy_up_one(parent, next, &lowerpath, &stat);
-+
-+		dput(parent);
-+		dput(next);
-+	}
-+
-+	return err;
-+}
-+
-+/* Optimize by not copying up the file first and truncating later */
-+static int ovl_copy_up_truncate(struct dentry *dentry, loff_t size)
-+{
-+	int err;
-+	struct kstat stat;
-+	struct path lowerpath;
-+	struct dentry *parent = dget_parent(dentry);
-+
-+	err = ovl_copy_up(parent);
-+	if (err)
-+		goto out_dput_parent;
-+
-+	ovl_path_lower(dentry, &lowerpath);
-+	err = vfs_getattr(lowerpath.mnt, lowerpath.dentry, &stat);
-+	if (err)
-+		goto out_dput_parent;
-+
-+	if (size < stat.size)
-+		stat.size = size;
-+
-+	err = ovl_copy_up_one(parent, dentry, &lowerpath, &stat);
-+
-+out_dput_parent:
-+	dput(parent);
-+	return err;
-+}
-+
-+static int ovl_setattr(struct dentry *dentry, struct iattr *attr)
-+{
-+	struct dentry *upperdentry;
-+	int err;
-+
-+	if ((attr->ia_valid & ATTR_SIZE) && !ovl_dentry_upper(dentry))
-+		err = ovl_copy_up_truncate(dentry, attr->ia_size);
-+	else
-+		err = ovl_copy_up(dentry);
-+	if (err)
-+		return err;
-+
-+	upperdentry = ovl_dentry_upper(dentry);
-+
-+	if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
-+		attr->ia_valid &= ~ATTR_MODE;
-+
-+	mutex_lock(&upperdentry->d_inode->i_mutex);
-+	err = notify_change(upperdentry, attr);
-+	mutex_unlock(&upperdentry->d_inode->i_mutex);
-+
-+	return err;
-+}
-+
-+static int ovl_getattr(struct vfsmount *mnt, struct dentry *dentry,
-+			 struct kstat *stat)
-+{
-+	struct path realpath;
-+
-+	ovl_path_real(dentry, &realpath);
-+	return vfs_getattr(realpath.mnt, realpath.dentry, stat);
-+}
-+
-+static int ovl_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
-+			 struct kstat *stat)
-+{
-+	int err;
-+	enum ovl_path_type type;
-+	struct path realpath;
-+
-+	type = ovl_path_real(dentry, &realpath);
-+	err = vfs_getattr(realpath.mnt, realpath.dentry, stat);
-+	if (err)
-+		return err;
-+
-+	stat->dev = dentry->d_sb->s_dev;
-+	stat->ino = dentry->d_inode->i_ino;
-+
-+	/*
-+	 * It's probably not worth it to count subdirs to get the
-+	 * correct link count.  nlink=1 seems to pacify 'find' and
-+	 * other utilities.
-+	 */
-+	if (type == OVL_PATH_MERGE)
-+		stat->nlink = 1;
-+
-+	return 0;
-+}
-+
-+static int ovl_permission(struct inode *inode, int mask, unsigned int flags)
-+{
-+	struct ovl_entry *oe;
-+	struct dentry *alias = NULL;
-+	struct inode *realinode;
-+	struct dentry *realdentry;
-+	bool is_upper;
-+	int err;
-+
-+	if (S_ISDIR(inode->i_mode)) {
-+		oe = inode->i_private;
-+	} else if (flags & IPERM_FLAG_RCU) {
-+		return -ECHILD;
-+	} else {
-+		/*
-+		 * For non-directories find an alias and get the info
-+		 * from there.
-+		 */
-+		spin_lock(&inode->i_lock);
-+		if (WARN_ON(list_empty(&inode->i_dentry))) {
-+			spin_unlock(&inode->i_lock);
-+			return -ENOENT;
-+		}
-+		alias = list_entry(inode->i_dentry.next, struct dentry, d_alias);
-+		dget(alias);
-+		spin_unlock(&inode->i_lock);
-+		oe = alias->d_fsdata;
-+	}
-+
-+	realdentry = ovl_upperdentry_dereference(oe);
-+	is_upper = true;
-+	if (!realdentry) {
-+		realdentry = oe->lowerdentry;
-+		is_upper = false;
-+	}
-+
-+	/* Careful in RCU walk mode */
-+	realinode = ACCESS_ONCE(realdentry->d_inode);
-+	if (!realinode) {
-+		WARN_ON(!(flags & IPERM_FLAG_RCU));
-+		return -ENOENT;
-+	}
-+
-+	if (mask & MAY_WRITE) {
-+		umode_t mode = realinode->i_mode;
-+
-+		/*
-+		 * Writes will always be redirected to upper layer, so
-+		 * ignore lower layer being read-only.
-+		 */
-+		err = -EROFS;
-+		if (is_upper && IS_RDONLY(realinode) &&
-+		    (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
-+			goto out_dput;
-+
-+		/*
-+		 * Nobody gets write access to an immutable file.
-+		 */
-+		err = -EACCES;
-+		if (IS_IMMUTABLE(realinode))
-+			goto out_dput;
-+	}
-+
-+	if (realinode->i_op->permission)
-+		err = realinode->i_op->permission(realinode, mask, flags);
-+	else
-+		err = generic_permission(realinode, mask, flags,
-+					 realinode->i_op->check_acl);
-+out_dput:
-+	dput(alias);
-+	return err;
-+}
-+
-+static int ovl_create_object(struct dentry *dentry, int mode, dev_t rdev,
-+			     const char *link)
-+{
-+	int err;
-+	struct dentry *newdentry;
-+	struct dentry *upperdir;
-+	struct inode *inode;
-+	struct kstat stat = {
-+		.mode = mode,
-+		.rdev = rdev,
-+	};
-+
-+	err = -ENOMEM;
-+	inode = ovl_new_inode(dentry->d_sb, mode, dentry->d_fsdata);
-+	if (!inode)
-+		goto out;
-+
-+	err = ovl_copy_up(dentry->d_parent);
-+	if (err)
-+		goto out_iput;
-+
-+	upperdir = ovl_dentry_upper(dentry->d_parent);
-+	mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT);
-+
-+	newdentry = ovl_upper_create(upperdir, dentry, &stat, link);
-+	err = PTR_ERR(newdentry);
-+	if (IS_ERR(newdentry))
-+		goto out_unlock;
-+
-+	ovl_dentry_version_inc(dentry->d_parent);
-+	if (ovl_dentry_is_opaque(dentry) && S_ISDIR(mode)) {
-+		err = ovl_set_opaque(newdentry);
-+		if (err)
-+			goto out_dput;
-+	}
-+	ovl_dentry_update(dentry, newdentry);
-+	d_instantiate(dentry, inode);
-+	inode = NULL;
-+	newdentry = NULL;
-+	err = 0;
-+
-+out_dput:
-+	dput(newdentry);
-+out_unlock:
-+	mutex_unlock(&upperdir->d_inode->i_mutex);
-+out_iput:
-+	iput(inode);
-+out:
-+	return err;
-+}
-+
-+static int ovl_create(struct inode *dir, struct dentry *dentry, int mode,
-+			struct nameidata *nd)
-+{
-+	return ovl_create_object(dentry, (mode & 07777) | S_IFREG, 0, NULL);
-+}
-+
-+static int ovl_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-+{
-+	return ovl_create_object(dentry, (mode & 07777) | S_IFDIR, 0, NULL);
-+}
-+
-+static int ovl_mknod(struct inode *dir, struct dentry *dentry, int mode,
-+		       dev_t rdev)
-+{
-+	return ovl_create_object(dentry, mode, rdev, NULL);
-+}
-+
-+static int ovl_symlink(struct inode *dir, struct dentry *dentry,
-+			 const char *link)
-+{
-+	return ovl_create_object(dentry, S_IFLNK, 0, link);
-+}
-+
-+struct ovl_link_data {
-+	struct dentry *realdentry;
-+	void *cookie;
-+};
-+
-+static void *ovl_follow_link(struct dentry *dentry, struct nameidata *nd)
-+{
-+	void *ret;
-+	struct dentry *realdentry;
-+	struct inode *realinode;
-+
-+	realdentry = ovl_dentry_real(dentry);
-+	realinode = realdentry->d_inode;
-+
-+	if (WARN_ON(!realinode->i_op->follow_link))
-+		return ERR_PTR(-EPERM);
-+
-+	ret = realinode->i_op->follow_link(realdentry, nd);
-+	if (IS_ERR(ret))
-+		return ret;
-+
-+	if (realinode->i_op->put_link) {
-+		struct ovl_link_data *data;
-+
-+		data = kmalloc(sizeof(struct ovl_link_data), GFP_KERNEL);
-+		if (!data) {
-+			realinode->i_op->put_link(realdentry, nd, ret);
-+			return ERR_PTR(-ENOMEM);
-+		}
-+		data->realdentry = realdentry;
-+		data->cookie = ret;
-+
-+		return data;
-+	} else {
-+		return NULL;
-+	}
-+}
-+
-+static void ovl_put_link(struct dentry *dentry, struct nameidata *nd, void *c)
-+{
-+	struct inode *realinode;
-+	struct ovl_link_data *data = c;
-+
-+	if (!data)
-+		return;
-+
-+	realinode = data->realdentry->d_inode;
-+	realinode->i_op->put_link(data->realdentry, nd, data->cookie);
-+	kfree(data);
-+}
-+
-+static int ovl_readlink(struct dentry *dentry, char __user *buf, int bufsiz)
-+{
-+	struct path realpath;
-+	struct inode *realinode;
-+
-+	ovl_path_real(dentry, &realpath);
-+	realinode = realpath.dentry->d_inode;
-+
-+	if (!realinode->i_op->readlink)
-+		return -EINVAL;
-+
-+	touch_atime(realpath.mnt, realpath.dentry);
-+
-+	return realinode->i_op->readlink(realpath.dentry, buf, bufsiz);
-+}
-+
-+static int ovl_whiteout(struct dentry *upperdir, struct dentry *dentry)
-+{
-+	int err;
-+	struct dentry *newdentry;
-+	const struct cred *old_cred;
-+	struct cred *override_cred;
-+
-+	/* FIXME: recheck lower dentry to see if whiteout is really needed */
-+
-+	err = -ENOMEM;
-+	override_cred = prepare_creds();
-+	if (!override_cred)
-+		goto out;
-+
-+	/*
-+	 * CAP_SYS_ADMIN for setxattr
-+	 * CAP_DAC_OVERRIDE for symlink creation
-+	 */
-+	cap_raise(override_cred->cap_effective, CAP_SYS_ADMIN);
-+	cap_raise(override_cred->cap_effective, CAP_DAC_OVERRIDE);
-+	override_cred->fsuid = 0;
-+	override_cred->fsgid = 0;
-+	old_cred = override_creds(override_cred);
-+
-+	newdentry = lookup_one_len(dentry->d_name.name, upperdir,
-+				   dentry->d_name.len);
-+	err = PTR_ERR(newdentry);
-+	if (IS_ERR(newdentry))
-+		goto out_put_cred;
-+
-+	/* Just been removed within the same locked region */
-+	WARN_ON(newdentry->d_inode);
-+
-+	err = vfs_symlink(upperdir->d_inode, newdentry, ovl_whiteout_symlink);
-+	if (err)
-+		goto out_dput;
-+
-+	ovl_dentry_version_inc(dentry->d_parent);
-+
-+	err = vfs_setxattr(newdentry, ovl_whiteout_xattr, "y", 1, 0);
-+
-+out_dput:
-+	dput(newdentry);
-+out_put_cred:
-+	revert_creds(old_cred);
-+	put_cred(override_cred);
-+out:
-+	return err;
-+}
-+
-+static int ovl_do_remove(struct dentry *dentry, bool is_dir)
-+{
-+	int err;
-+	enum ovl_path_type type;
-+	struct path realpath;
-+	struct dentry *upperdir;
-+
-+	err = ovl_copy_up(dentry->d_parent);
-+	if (err)
-+		return err;
-+
-+	upperdir = ovl_dentry_upper(dentry->d_parent);
-+	mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT);
-+	type = ovl_path_real(dentry, &realpath);
-+	if (type != OVL_PATH_LOWER) {
-+		err = -ESTALE;
-+		if (realpath.dentry->d_parent != upperdir)
-+			goto out_d_drop;
-+
-+		if (is_dir)
-+			err = vfs_rmdir(upperdir->d_inode, realpath.dentry);
-+		else
-+			err = vfs_unlink(upperdir->d_inode, realpath.dentry);
-+		if (err)
-+			goto out_d_drop;
-+
-+		ovl_dentry_version_inc(dentry->d_parent);
-+	}
-+
-+	if (type != OVL_PATH_UPPER || ovl_dentry_is_opaque(dentry))
-+		err = ovl_whiteout(upperdir, dentry);
-+
-+	/*
-+	 * Keeping this dentry hashed would mean having to release
-+	 * upperpath/lowerpath, which could only be done if we are the
-+	 * sole user of this dentry.  Too tricky...  Just unhash for
-+	 * now.
-+	 */
-+out_d_drop:
-+	d_drop(dentry);
-+	mutex_unlock(&upperdir->d_inode->i_mutex);
-+
-+	return err;
-+}
-+
-+static int ovl_unlink(struct inode *dir, struct dentry *dentry)
-+{
-+	return ovl_do_remove(dentry, false);
-+}
-+
-+static int ovl_check_empty_dir(struct dentry *dentry)
-+{
-+	int err;
-+	struct path lowerpath;
-+	struct path upperpath;
-+	struct ovl_cache_entry *p;
-+	LIST_HEAD(list);
-+	struct ovl_readdir_data rdd = { .list = &list };
-+
-+	ovl_path_upper(dentry, &upperpath);
-+	ovl_path_lower(dentry, &lowerpath);
-+
-+	err = ovl_dir_read_merged(&upperpath, &lowerpath, &rdd);
-+	if (err)
-+		return err;
-+
-+	err = 0;
-+
-+	list_for_each_entry(p, &list, l_node) {
-+		if (p->is_whiteout)
-+			continue;
-+
-+		if (p->name[0] == '.') {
-+			if (p->len == 1)
-+				continue;
-+			if (p->len == 2 && p->name[1] == '.')
-+				continue;
-+		}
-+		err = -ENOTEMPTY;
-+		break;
-+	}
-+
-+	ovl_cache_free(&list);
-+
-+	return err;
-+}
-+
-+static int ovl_unlink_whiteout(void *buf, const char *name, int namelen,
-+				 loff_t offset, u64 ino, unsigned int d_type)
-+{
-+	struct ovl_readdir_data *rdd = buf;
-+
-+	rdd->count++;
-+	/* check d_type to filter out "." and ".." */
-+	if (d_type == DT_LNK) {
-+		struct dentry *dentry;
-+
-+		dentry = lookup_one_len(name, rdd->dir, namelen);
-+		if (IS_ERR(dentry)) {
-+			rdd->err = PTR_ERR(dentry);
-+		} else {
-+			rdd->err = vfs_unlink(rdd->dir->d_inode, dentry);
-+			dput(dentry);
-+		}
-+	}
-+
-+	return rdd->err;
-+}
-+
-+static int ovl_remove_whiteouts(struct dentry *dentry)
-+{
-+	struct path upperpath;
-+	struct ovl_readdir_data rdd = {	.list = NULL };
-+
-+	ovl_path_upper(dentry, &upperpath);
-+	rdd.dir = upperpath.dentry;
-+
-+	return ovl_dir_read(&upperpath, &rdd, ovl_unlink_whiteout);
-+}
-+
-+static int ovl_rmdir(struct inode *dir, struct dentry *dentry)
-+{
-+	int err;
-+	enum ovl_path_type type;
-+
-+	type = ovl_path_type(dentry);
-+	if (type != OVL_PATH_UPPER) {
-+		err = ovl_check_empty_dir(dentry);
-+		if (err)
-+			return err;
-+
-+		if (type == OVL_PATH_MERGE) {
-+			err = ovl_remove_whiteouts(dentry);
-+			if (err)
-+				return err;
-+		}
-+	}
-+
-+	return ovl_do_remove(dentry, true);
-+}
-+
-+static int ovl_link(struct dentry *old, struct inode *newdir,
-+		    struct dentry *new)
-+{
-+	int err;
-+	struct dentry *olddentry;
-+	struct dentry *newdentry;
-+	struct dentry *upperdir;
-+
-+	err = ovl_copy_up(old);
-+	if (err)
-+		goto out;
-+
-+	err = ovl_copy_up(new->d_parent);
-+	if (err)
-+		goto out;
-+
-+	upperdir = ovl_dentry_upper(new->d_parent);
-+	mutex_lock_nested(&upperdir->d_inode->i_mutex, I_MUTEX_PARENT);
-+	newdentry = ovl_lookup_create(upperdir, new);
-+	err = PTR_ERR(newdentry);
-+	if (IS_ERR(newdentry))
-+		goto out_unlock;
-+
-+	olddentry = ovl_dentry_upper(old);
-+	err = vfs_link(olddentry, upperdir->d_inode, newdentry);
-+	if (!err) {
-+		ovl_dentry_version_inc(new->d_parent);
-+		ovl_dentry_update(new, newdentry);
-+
-+		ihold(old->d_inode);
-+		d_instantiate(new, old->d_inode);
-+	} else {
-+		dput(newdentry);
-+	}
-+out_unlock:
-+	mutex_unlock(&upperdir->d_inode->i_mutex);
-+out:
-+	return err;
-+
-+}
-+
-+static int ovl_rename(struct inode *olddir, struct dentry *old,
-+			struct inode *newdir, struct dentry *new)
-+{
-+	int err;
-+	enum ovl_path_type old_type;
-+	struct dentry *old_upperdir;
-+	struct dentry *new_upperdir;
-+	struct dentry *olddentry;
-+	struct dentry *newdentry;
-+	struct dentry *trap;
-+	bool is_dir = S_ISDIR(old->d_inode->i_mode);
-+
-+	/* Don't copy up directory trees */
-+	old_type = ovl_path_type(old);
-+	if (old_type != OVL_PATH_UPPER && is_dir)
-+		return -EXDEV;
-+
-+	if (new->d_inode) {
-+		enum ovl_path_type new_type;
-+
-+		new_type = ovl_path_type(new);
-+
-+		if (new_type == OVL_PATH_LOWER && old_type == OVL_PATH_LOWER) {
-+			if (ovl_dentry_lower(old)->d_inode ==
-+			    ovl_dentry_lower(new)->d_inode)
-+				return 0;
-+		}
-+		if (new_type != OVL_PATH_LOWER && old_type != OVL_PATH_LOWER) {
-+			if (ovl_dentry_upper(old)->d_inode ==
-+			    ovl_dentry_upper(new)->d_inode)
-+				return 0;
-+		}
-+
-+		if (new_type != OVL_PATH_UPPER &&
-+		    S_ISDIR(new->d_inode->i_mode)) {
-+			err = ovl_check_empty_dir(new);
-+			if (err)
-+				return err;
-+
-+			if (new_type == OVL_PATH_MERGE) {
-+				err = ovl_remove_whiteouts(new);
-+				if (err)
-+					return err;
-+			}
-+		}
-+	}
-+
-+	err = ovl_copy_up(old);
-+	if (err)
-+		return err;
-+
-+	err = ovl_copy_up(new->d_parent);
-+	if (err)
-+		return err;
-+
-+	old_upperdir = ovl_dentry_upper(old->d_parent);
-+	new_upperdir = ovl_dentry_upper(new->d_parent);
-+
-+	trap = lock_rename(new_upperdir, old_upperdir);
-+
-+	olddentry = ovl_dentry_upper(old);
-+	newdentry = ovl_dentry_upper(new);
-+	if (newdentry) {
-+		dget(newdentry);
-+	} else {
-+		newdentry = ovl_lookup_create(new_upperdir, new);
-+		err = PTR_ERR(newdentry);
-+		if (IS_ERR(newdentry))
-+			goto out_unlock;
-+	}
-+
-+	err = -ESTALE;
-+	if (olddentry->d_parent != old_upperdir)
-+		goto out_dput;
-+	if (newdentry->d_parent != new_upperdir)
-+		goto out_dput;
-+	if (olddentry == trap)
-+		goto out_dput;
-+	if (newdentry == trap)
-+		goto out_dput;
-+
-+	err = vfs_rename(old_upperdir->d_inode, olddentry,
-+			 new_upperdir->d_inode, newdentry);
-+
-+	if (!err) {
-+		bool old_opaque = ovl_dentry_is_opaque(old);
-+		bool new_opaque = ovl_dentry_is_opaque(new);
-+
-+		if (ovl_path_type(new) != OVL_PATH_UPPER)
-+			new_opaque = true;
-+
-+		if (old_type != OVL_PATH_UPPER || old_opaque)
-+			err = ovl_whiteout(old_upperdir, old);
-+		if (!err && is_dir) {
-+			if (old_opaque && !new_opaque) {
-+				ovl_remove_opaque(olddentry);
-+				ovl_dentry_set_opaque(old, false);
-+			}
-+			if (!old_opaque && new_opaque) {
-+				err = ovl_set_opaque(olddentry);
-+				ovl_dentry_set_opaque(old, true);
-+			}
-+		}
-+		ovl_dentry_version_inc(old->d_parent);
-+		ovl_dentry_version_inc(new->d_parent);
-+	}
-+
-+out_dput:
-+	dput(newdentry);
-+out_unlock:
-+	unlock_rename(new_upperdir, old_upperdir);
-+	return err;
-+}
-+
-+static bool ovl_is_private_xattr(const char *name)
-+{
-+	return strncmp(name, "trusted.overlay.", 14) == 0;
-+}
-+
-+static int ovl_setxattr(struct dentry *dentry, const char *name,
-+			  const void *value, size_t size, int flags)
-+{
-+	int err;
-+	struct dentry *upperdentry;
-+
-+	if (ovl_is_private_xattr(name))
-+		return -EPERM;
-+
-+	err = ovl_copy_up(dentry);
-+	if (err)
-+		return err;
-+
-+	upperdentry = ovl_dentry_upper(dentry);
-+	return  vfs_setxattr(upperdentry, name, value, size, flags);
-+}
-+
-+static ssize_t ovl_getxattr(struct dentry *dentry, const char *name,
-+			      void *value, size_t size)
-+{
-+	if (ovl_path_type(dentry->d_parent) == OVL_PATH_MERGE &&
-+	    ovl_is_private_xattr(name))
-+		return -ENODATA;
-+
-+	return vfs_getxattr(ovl_dentry_real(dentry), name, value, size);
-+}
-+
-+static ssize_t ovl_listxattr(struct dentry *dentry, char *list, size_t size)
-+{
-+	ssize_t res;
-+	int off;
-+
-+	res = vfs_listxattr(ovl_dentry_real(dentry), list, size);
-+	if (res <= 0 || size == 0)
-+		return res;
-+
-+	if (ovl_path_type(dentry->d_parent) != OVL_PATH_MERGE)
-+		return res;
-+
-+	/* filter out private xattrs */
-+	for (off = 0; off < res;) {
-+		char *s = list + off;
-+		size_t slen = strlen(s) + 1;
-+
-+		BUG_ON(off + slen > res);
-+
-+		if (ovl_is_private_xattr(s)) {
-+			res -= slen;
-+			memmove(s, s + slen, res - off);
-+		} else {
-+			off += slen;
-+		}
-+	}
-+
-+	return res;
-+}
-+
-+static int ovl_removexattr(struct dentry *dentry, const char *name)
-+{
-+	int err;
-+	struct path realpath;
-+	enum ovl_path_type type;
-+
-+	if (ovl_path_type(dentry->d_parent) == OVL_PATH_MERGE &&
-+	    ovl_is_private_xattr(name))
-+		return -ENODATA;
-+
-+	type = ovl_path_real(dentry, &realpath);
-+	if (type == OVL_PATH_LOWER) {
-+		err = vfs_getxattr(realpath.dentry, name, NULL, 0);
-+		if (err < 0)
-+			return err;
-+
-+		err = ovl_copy_up(dentry);
-+		if (err)
-+			return err;
-+
-+		ovl_path_upper(dentry, &realpath);
-+	}
-+
-+	return vfs_removexattr(realpath.dentry, name);
-+}
-+
-+static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type,
-+				  struct dentry *realdentry)
-+{
-+	if (type != OVL_PATH_LOWER)
-+		return false;
-+
-+	if (special_file(realdentry->d_inode->i_mode))
-+		return false;
-+
-+	if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC))
-+		return false;
-+
-+	return true;
-+}
-+
-+static struct file *ovl_open(struct dentry *dentry, int flags,
-+			     const struct cred *cred)
-+{
-+	int err;
-+	struct path realpath;
-+	enum ovl_path_type type;
-+
-+	type = ovl_path_real(dentry, &realpath);
-+	if (ovl_open_need_copy_up(flags, type, realpath.dentry)) {
-+		if (flags & O_TRUNC)
-+			err = ovl_copy_up_truncate(dentry, 0);
-+		else
-+			err = ovl_copy_up(dentry);
-+		if (err)
-+			return ERR_PTR(err);
-+
-+		ovl_path_upper(dentry, &realpath);
-+	}
-+
-+	return vfs_open(&realpath, flags, cred);
-+}
-+
-+static const struct inode_operations ovl_dir_inode_operations = {
-+	.lookup		= ovl_lookup,
-+	.mkdir		= ovl_mkdir,
-+	.symlink	= ovl_symlink,
-+	.unlink		= ovl_unlink,
-+	.rmdir		= ovl_rmdir,
-+	.rename		= ovl_rename,
-+	.link		= ovl_link,
-+	.setattr	= ovl_setattr,
-+	.create		= ovl_create,
-+	.mknod		= ovl_mknod,
-+	.permission	= ovl_permission,
-+	.getattr	= ovl_dir_getattr,
-+	.setxattr	= ovl_setxattr,
-+	.getxattr	= ovl_getxattr,
-+	.listxattr	= ovl_listxattr,
-+	.removexattr	= ovl_removexattr,
-+};
-+
-+static const struct inode_operations ovl_file_inode_operations = {
-+	.setattr	= ovl_setattr,
-+	.permission	= ovl_permission,
-+	.getattr	= ovl_getattr,
-+	.setxattr	= ovl_setxattr,
-+	.getxattr	= ovl_getxattr,
-+	.listxattr	= ovl_listxattr,
-+	.removexattr	= ovl_removexattr,
-+	.open		= ovl_open,
-+};
-+
-+static const struct inode_operations ovl_symlink_inode_operations = {
-+	.setattr	= ovl_setattr,
-+	.follow_link	= ovl_follow_link,
-+	.put_link	= ovl_put_link,
-+	.readlink	= ovl_readlink,
-+	.getattr	= ovl_getattr,
-+	.setxattr	= ovl_setxattr,
-+	.getxattr	= ovl_getxattr,
-+	.listxattr	= ovl_listxattr,
-+	.removexattr	= ovl_removexattr,
-+};
-+
-+static struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
-+				   struct ovl_entry *oe)
-+{
-+	struct inode *inode;
-+
-+	inode = new_inode(sb);
-+	if (!inode)
-+		return NULL;
-+
-+	mode &= S_IFMT;
-+
-+	inode->i_ino = get_next_ino();
-+	inode->i_mode = mode;
-+	inode->i_flags |= S_NOATIME | S_NOCMTIME;
-+
-+	switch (mode) {
-+	case S_IFDIR:
-+		inode->i_private = oe;
-+		inode->i_op = &ovl_dir_inode_operations;
-+		inode->i_fop = &ovl_dir_operations;
-+		break;
-+
-+	case S_IFLNK:
-+		inode->i_op = &ovl_symlink_inode_operations;
-+		break;
-+
-+	case S_IFREG:
-+	case S_IFSOCK:
-+	case S_IFBLK:
-+	case S_IFCHR:
-+	case S_IFIFO:
-+		inode->i_op = &ovl_file_inode_operations;
-+		break;
-+
-+	default:
-+		WARN(1, "illegal file type: %i\n", mode);
-+		inode = NULL;
-+	}
-+
-+	return inode;
-+
-+}
-+
-+static void ovl_put_super(struct super_block *sb)
-+{
-+	struct ovl_fs *ufs = sb->s_fs_info;
-+
-+	if (!(sb->s_flags & MS_RDONLY))
-+		mnt_drop_write(ufs->upper_mnt);
-+
-+	mntput(ufs->upper_mnt);
-+	mntput(ufs->lower_mnt);
-+
-+	kfree(ufs);
-+}
-+
-+static int ovl_remount_fs(struct super_block *sb, int *flagsp, char *data)
-+{
-+	int flags = *flagsp;
-+	struct ovl_fs *ufs = sb->s_fs_info;
-+
-+	/* When remounting rw or ro, we need to adjust the write access to the
-+	 * upper fs.
-+	 */
-+	if (((flags ^ sb->s_flags) & MS_RDONLY) == 0)
-+		/* No change to readonly status */
-+		return 0;
-+
-+	if (flags & MS_RDONLY) {
-+		mnt_drop_write(ufs->upper_mnt);
-+		return 0;
-+	} else
-+		return mnt_want_write(ufs->upper_mnt);
-+}
-+
-+/**
-+ * ovl_statfs
-+ * @sb: The overlayfs super block
-+ * @buf: The struct kstatfs to fill in with stats
-+ *
-+ * Get the filesystem statistics.  As writes always target the upper layer
-+ * filesystem pass the statfs to the same filesystem.
-+ */
-+static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf)
-+{
-+	struct dentry *root_dentry = dentry->d_sb->s_root;
-+	struct path path;
-+	ovl_path_upper(root_dentry, &path);
-+
-+	if (!path.dentry->d_sb->s_op->statfs)
-+		return -ENOSYS;
-+	return path.dentry->d_sb->s_op->statfs(path.dentry, buf);
-+}
-+
-+static const struct super_operations ovl_super_operations = {
-+	.put_super	= ovl_put_super,
-+	.remount_fs	= ovl_remount_fs,
-+	.statfs		= ovl_statfs,
-+};
-+
-+struct ovl_config {
-+	char *lowerdir;
-+	char *upperdir;
-+};
-+
-+enum {
-+	Opt_lowerdir,
-+	Opt_upperdir,
-+	Opt_err,
-+};
-+
-+static const match_table_t ovl_tokens = {
-+	{Opt_lowerdir,			"lowerdir=%s"},
-+	{Opt_upperdir,			"upperdir=%s"},
-+	{Opt_err,			NULL}
-+};
-+
-+static int ovl_parse_opt(char *opt, struct ovl_config *config)
-+{
-+	char *p;
-+
-+	config->upperdir = NULL;
-+	config->lowerdir = NULL;
-+
-+	while ((p = strsep(&opt, ",")) != NULL) {
-+		int token;
-+		substring_t args[MAX_OPT_ARGS];
-+
-+		if (!*p)
-+			continue;
-+
-+		token = match_token(p, ovl_tokens, args);
-+		switch (token) {
-+		case Opt_upperdir:
-+			kfree(config->upperdir);
-+			config->upperdir = match_strdup(&args[0]);
-+			if (!config->upperdir)
-+				return -ENOMEM;
-+			break;
-+
-+		case Opt_lowerdir:
-+			kfree(config->lowerdir);
-+			config->lowerdir = match_strdup(&args[0]);
-+			if (!config->lowerdir)
-+				return -ENOMEM;
-+			break;
-+
-+		default:
-+			return -EINVAL;
-+		}
-+	}
-+	return 0;
-+}
-+
-+static int ovl_fill_super(struct super_block *sb, void *data, int silent)
-+{
-+	struct path lowerpath;
-+	struct path upperpath;
-+	struct inode *root_inode;
-+	struct dentry *root_dentry;
-+	struct ovl_entry *oe;
-+	struct ovl_fs *ufs;
-+	struct ovl_config config;
-+	int err;
-+
-+	err = ovl_parse_opt((char *) data, &config);
-+	if (err)
-+		goto out;
-+
-+	err = -EINVAL;
-+	if (!config.upperdir || !config.lowerdir) {
-+		printk(KERN_ERR "overlayfs: missing upperdir or lowerdir\n");
-+		goto out_free_config;
-+	}
-+
-+	err = -ENOMEM;
-+	ufs = kmalloc(sizeof(struct ovl_fs), GFP_KERNEL);
-+	if (!ufs)
-+		goto out_free_config;
-+
-+	oe = ovl_alloc_entry();
-+	if (oe == NULL)
-+		goto out_free_ufs;
-+
-+	root_inode = ovl_new_inode(sb, S_IFDIR, oe);
-+	if (!root_inode)
-+		goto out_free_oe;
-+
-+	err = kern_path(config.upperdir, LOOKUP_FOLLOW, &upperpath);
-+	if (err)
-+		goto out_put_root;
-+
-+	err = kern_path(config.lowerdir, LOOKUP_FOLLOW, &lowerpath);
-+	if (err)
-+		goto out_put_upperpath;
-+
-+	err = -ENOTDIR;
-+	if (!S_ISDIR(upperpath.dentry->d_inode->i_mode) ||
-+	    !S_ISDIR(lowerpath.dentry->d_inode->i_mode))
-+		goto out_put_lowerpath;
-+
-+	ufs->upper_mnt = clone_private_mount(&upperpath);
-+	err = PTR_ERR(ufs->upper_mnt);
-+	if (IS_ERR(ufs->upper_mnt)) {
-+		printk(KERN_ERR "overlayfs: failed to clone upperpath\n");
-+		goto out_put_lowerpath;
-+	}
-+
-+	ufs->lower_mnt = clone_private_mount(&lowerpath);
-+	err = PTR_ERR(ufs->lower_mnt);
-+	if (IS_ERR(ufs->lower_mnt)) {
-+		printk(KERN_ERR "overlayfs: failed to clone lowerpath\n");
-+		goto out_put_upper_mnt;
-+	}
-+
-+	if (!(sb->s_flags & MS_RDONLY)) {
-+		err = mnt_want_write(ufs->upper_mnt);
-+		if (err)
-+			goto out_put_lower_mnt;
-+	}
-+
-+	err = -ENOMEM;
-+	root_dentry = d_alloc_root(root_inode);
-+	if (!root_dentry)
-+		goto out_drop_write;
-+
-+	mntput(upperpath.mnt);
-+	mntput(lowerpath.mnt);
-+
-+	oe->__upperdentry = upperpath.dentry;
-+	oe->lowerdentry = lowerpath.dentry;
-+
-+	root_dentry->d_fsdata = oe;
-+	root_dentry->d_op = &ovl_dentry_operations;
-+
-+	sb->s_op = &ovl_super_operations;
-+	sb->s_root = root_dentry;
-+	sb->s_fs_info = ufs;
-+
-+	return 0;
-+
-+out_drop_write:
-+	if (!(sb->s_flags & MS_RDONLY))
-+		mnt_drop_write(ufs->upper_mnt);
-+out_put_lower_mnt:
-+	mntput(ufs->lower_mnt);
-+out_put_upper_mnt:
-+	mntput(ufs->upper_mnt);
-+out_put_lowerpath:
-+	path_put(&lowerpath);
-+out_put_upperpath:
-+	path_put(&upperpath);
-+out_put_root:
-+	iput(root_inode);
-+out_free_oe:
-+	kfree(oe);
-+out_free_ufs:
-+	kfree(ufs);
-+out_free_config:
-+	kfree(config.lowerdir);
-+	kfree(config.upperdir);
-+out:
-+	return err;
-+}
-+
-+static int ovl_get_sb(struct file_system_type *fs_type,
-+			int flags, const char *dev_name,
-+			void *raw_data, struct vfsmount *mnt)
-+{
-+	return get_sb_nodev(fs_type, flags, raw_data, ovl_fill_super, mnt);
-+}
-+
-+static struct file_system_type ovl_fs_type = {
-+	.owner		= THIS_MODULE,
-+	.name		= "overlayfs",
-+	.get_sb		= ovl_get_sb,
-+	.kill_sb	= kill_anon_super,
-+};
-+
-+static int __init ovl_init(void)
-+{
-+	return register_filesystem(&ovl_fs_type);
-+}
-+
-+static void __exit ovl_exit(void)
-+{
-+	unregister_filesystem(&ovl_fs_type);
-+}
-+
-+module_init(ovl_init);
-+module_exit(ovl_exit);
---- a/fs/splice.c
-+++ b/fs/splice.c
-@@ -1296,6 +1296,7 @@ long do_splice_direct(struct file *in, l
- 
- 	return ret;
- }
-+EXPORT_SYMBOL(do_splice_direct);
- 
- static int splice_pipe_to_pipe(struct pipe_inode_info *ipipe,
- 			       struct pipe_inode_info *opipe,
---- a/include/linux/fs.h
-+++ b/include/linux/fs.h
-@@ -1587,6 +1587,7 @@ struct inode_operations {
- 	void (*truncate_range)(struct inode *, loff_t, loff_t);
- 	int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
- 		      u64 len);
-+	struct file *(*open)(struct dentry *, int flags, const struct cred *);
- } ____cacheline_aligned;
- 
- struct seq_file;
-@@ -1990,6 +1991,7 @@ extern int do_fallocate(struct file *fil
- extern long do_sys_open(int dfd, const char __user *filename, int flags,
- 			int mode);
- extern struct file *filp_open(const char *, int, int);
-+extern struct file *vfs_open(struct path *, int flags, const struct cred *);
- extern struct file * dentry_open(struct dentry *, struct vfsmount *, int,
- 				 const struct cred *);
- extern int filp_close(struct file *, fl_owner_t id);
---- a/include/linux/mount.h
-+++ b/include/linux/mount.h
-@@ -100,6 +100,9 @@ extern void mnt_pin(struct vfsmount *mnt
- extern void mnt_unpin(struct vfsmount *mnt);
- extern int __mnt_is_readonly(struct vfsmount *mnt);
- 
-+struct path;
-+extern struct vfsmount *clone_private_mount(struct path *path);
-+
- extern struct vfsmount *do_kern_mount(const char *fstype, int flags,
- 				      const char *name, void *data);
- 
diff --git a/target/linux/generic/patches-2.6.38/101-overlayfs_fix_readdir_deadlock.patch b/target/linux/generic/patches-2.6.38/101-overlayfs_fix_readdir_deadlock.patch
deleted file mode 100644
index 81ef4c084f..0000000000
--- a/target/linux/generic/patches-2.6.38/101-overlayfs_fix_readdir_deadlock.patch
+++ /dev/null
@@ -1,124 +0,0 @@
---- a/fs/overlayfs/overlayfs.c
-+++ b/fs/overlayfs/overlayfs.c
-@@ -253,8 +253,7 @@ static struct ovl_cache_entry *ovl_cache
- }
- 
- static struct ovl_cache_entry *ovl_cache_entry_new(const char *name, int len,
--						   u64 ino, unsigned int d_type,
--						   bool is_whiteout)
-+						   u64 ino, unsigned int d_type)
- {
- 	struct ovl_cache_entry *p;
- 
-@@ -267,7 +266,7 @@ static struct ovl_cache_entry *ovl_cache
- 		p->len = len;
- 		p->type = d_type;
- 		p->ino = ino;
--		p->is_whiteout = is_whiteout;
-+		p->is_whiteout = false;
- 	}
- 
- 	return p;
-@@ -275,7 +274,7 @@ static struct ovl_cache_entry *ovl_cache
- 
- static int ovl_cache_entry_add_rb(struct ovl_readdir_data *rdd,
- 				  const char *name, int len, u64 ino,
--				  unsigned int d_type, bool is_whiteout)
-+				  unsigned int d_type)
- {
- 	struct rb_node **newp = &rdd->root->rb_node;
- 	struct rb_node *parent = NULL;
-@@ -296,11 +295,18 @@ static int ovl_cache_entry_add_rb(struct
- 			return 0;
- 	}
- 
--	p = ovl_cache_entry_new(name, len, ino, d_type, is_whiteout);
-+	p = ovl_cache_entry_new(name, len, ino, d_type);
- 	if (p == NULL)
- 		return -ENOMEM;
- 
--	list_add_tail(&p->l_node, rdd->list);
-+	/*
-+	 * Add links before other types to be able to quicky mark
-+	 * any whiteout entries
-+	 */
-+	if (d_type == DT_LNK)
-+		list_add(&p->l_node, rdd->list);
-+	else
-+		list_add_tail(&p->l_node, rdd->list);
- 	rb_link_node(&p->node, parent, newp);
- 	rb_insert_color(&p->node, rdd->root);
- 
-@@ -318,7 +324,7 @@ static int ovl_fill_lower(void *buf, con
- 	if (p) {
- 		list_move_tail(&p->l_node, rdd->middle);
- 	} else {
--		p = ovl_cache_entry_new(name, namelen, ino, d_type, false);
-+		p = ovl_cache_entry_new(name, namelen, ino, d_type);
- 		if (p == NULL)
- 			rdd->err = -ENOMEM;
- 		else
-@@ -343,26 +349,9 @@ static int ovl_fill_upper(void *buf, con
- 			  loff_t offset, u64 ino, unsigned int d_type)
- {
- 	struct ovl_readdir_data *rdd = buf;
--	bool is_whiteout = false;
- 
- 	rdd->count++;
--	if (d_type == DT_LNK) {
--		struct dentry *dentry;
--
--		dentry = lookup_one_len(name, rdd->dir, namelen);
--		if (IS_ERR(dentry)) {
--			rdd->err = PTR_ERR(dentry);
--			goto out;
--		}
--		is_whiteout = ovl_is_whiteout(dentry);
--		dput(dentry);
--	}
--
--	rdd->err = ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type,
--					  is_whiteout);
--
--out:
--	return rdd->err;
-+	return ovl_cache_entry_add_rb(rdd, name, namelen, ino, d_type);
- }
- 
- static int ovl_dir_read(struct path *realpath, struct ovl_readdir_data *rdd,
-@@ -428,6 +417,26 @@ static void ovl_dir_reset(struct file *f
- 	}
- }
- 
-+static void ovl_dir_mark_whiteouts(struct ovl_readdir_data *rdd)
-+{
-+	struct ovl_cache_entry *p;
-+	struct dentry *dentry;
-+
-+	mutex_lock(&rdd->dir->d_inode->i_mutex);
-+	list_for_each_entry(p, rdd->list, l_node) {
-+		if (p->type != DT_LNK)
-+			break;
-+
-+		dentry = lookup_one_len(p->name, rdd->dir, p->len);
-+		if (IS_ERR(dentry))
-+			continue;
-+
-+		p->is_whiteout = ovl_is_whiteout(dentry);
-+		dput(dentry);
-+	}
-+	mutex_unlock(&rdd->dir->d_inode->i_mutex);
-+}
-+
- static int ovl_dir_read_merged(struct path *upperpath, struct path *lowerpath,
- 			       struct ovl_readdir_data *rdd)
- {
-@@ -441,6 +450,8 @@ static int ovl_dir_read_merged(struct pa
- 		err = ovl_dir_read(upperpath, rdd, ovl_fill_upper);
- 		if (err)
- 			goto out;
-+
-+		ovl_dir_mark_whiteouts(rdd);
- 	}
- 	/*
- 	 * Insert lowerpath entries before upperpath ones, this allows
diff --git a/target/linux/generic/patches-2.6.38/102-overlayfs_fix_readdir_unlink_deadlock.patch b/target/linux/generic/patches-2.6.38/102-overlayfs_fix_readdir_unlink_deadlock.patch
deleted file mode 100644
index 6f4ceb4b77..0000000000
--- a/target/linux/generic/patches-2.6.38/102-overlayfs_fix_readdir_unlink_deadlock.patch
+++ /dev/null
@@ -1,76 +0,0 @@
---- a/fs/overlayfs/overlayfs.c
-+++ b/fs/overlayfs/overlayfs.c
-@@ -1700,37 +1700,56 @@ static int ovl_check_empty_dir(struct de
- 	return err;
- }
- 
--static int ovl_unlink_whiteout(void *buf, const char *name, int namelen,
--				 loff_t offset, u64 ino, unsigned int d_type)
-+static int ovl_fill_links(void *buf, const char *name, int namelen,
-+                          loff_t offset, u64 ino, unsigned int d_type)
- {
- 	struct ovl_readdir_data *rdd = buf;
-+	struct ovl_cache_entry *p;
- 
--	rdd->count++;
--	/* check d_type to filter out "." and ".." */
--	if (d_type == DT_LNK) {
--		struct dentry *dentry;
-+	if (d_type != DT_LNK)
-+		return 0;
- 
--		dentry = lookup_one_len(name, rdd->dir, namelen);
--		if (IS_ERR(dentry)) {
--			rdd->err = PTR_ERR(dentry);
--		} else {
--			rdd->err = vfs_unlink(rdd->dir->d_inode, dentry);
--			dput(dentry);
--		}
--	}
-+	p = ovl_cache_entry_new(name, namelen, ino, d_type);
-+	if (!p)
-+		return -ENOMEM;
- 
--	return rdd->err;
-+	list_add(&p->l_node, rdd->list);
-+	return 0;
- }
- 
- static int ovl_remove_whiteouts(struct dentry *dentry)
- {
- 	struct path upperpath;
--	struct ovl_readdir_data rdd = {	.list = NULL };
-+	LIST_HEAD(list);
-+	struct ovl_readdir_data rdd = {	.list = &list };
-+	struct ovl_cache_entry *p, *t;
-+	int ret;
- 
- 	ovl_path_upper(dentry, &upperpath);
- 	rdd.dir = upperpath.dentry;
- 
--	return ovl_dir_read(&upperpath, &rdd, ovl_unlink_whiteout);
-+	ret = ovl_dir_read(&upperpath, &rdd, ovl_fill_links);
-+
-+	mutex_lock(&rdd.dir->d_inode->i_mutex);
-+	list_for_each_entry_safe(p, t, &list, l_node) {
-+		struct dentry *dentry;
-+
-+		if (!ret) {
-+			dentry = lookup_one_len(p->name, rdd.dir, p->len);
-+			if (IS_ERR(dentry)) {
-+				ret = PTR_ERR(dentry);
-+			} else {
-+				ret = vfs_unlink(rdd.dir->d_inode, dentry);
-+				dput(dentry);
-+			}
-+		}
-+
-+		list_del(&p->l_node);
-+		kfree(p);
-+	}
-+	mutex_unlock(&rdd.dir->d_inode->i_mutex);
-+
-+	return ret;
- }
- 
- static int ovl_rmdir(struct inode *dir, struct dentry *dentry)
diff --git a/target/linux/generic/patches-2.6.38/110_fix_ecn_marking_ipv6.patch b/target/linux/generic/patches-2.6.38/110_fix_ecn_marking_ipv6.patch
deleted file mode 100644
index a981884b1b..0000000000
--- a/target/linux/generic/patches-2.6.38/110_fix_ecn_marking_ipv6.patch
+++ /dev/null
@@ -1,25 +0,0 @@
---- a/include/net/inet_ecn.h
-+++ b/include/net/inet_ecn.h
-@@ -38,9 +38,19 @@ static inline __u8 INET_ECN_encapsulate(
- 	return outer;
- }
- 
--#define	INET_ECN_xmit(sk) do { inet_sk(sk)->tos |= INET_ECN_ECT_0; } while (0)
--#define	INET_ECN_dontxmit(sk) \
--	do { inet_sk(sk)->tos &= ~INET_ECN_MASK; } while (0)
-+static inline void INET_ECN_xmit(struct sock *sk)
-+{
-+	inet_sk(sk)->tos |= INET_ECN_ECT_0;
-+	if (inet6_sk(sk) != NULL)
-+		inet6_sk(sk)->tclass |= INET_ECN_ECT_0;
-+}
-+
-+static inline void INET_ECN_dontxmit(struct sock *sk)
-+{
-+	inet_sk(sk)->tos &= ~INET_ECN_MASK;
-+	if (inet6_sk(sk) != NULL)
-+		inet6_sk(sk)->tclass &= ~INET_ECN_MASK;
-+}
- 
- #define IP6_ECN_flow_init(label) do {		\
-       (label) &= ~htonl(INET_ECN_MASK << 20);	\
diff --git a/target/linux/generic/patches-2.6.38/200-fix_localversion.patch b/target/linux/generic/patches-2.6.38/200-fix_localversion.patch
deleted file mode 100644
index 70ed0ff3cb..0000000000
--- a/target/linux/generic/patches-2.6.38/200-fix_localversion.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/scripts/setlocalversion
-+++ b/scripts/setlocalversion
-@@ -164,7 +164,7 @@ else
- 	# annotated or signed tagged state (as git describe only
- 	# looks at signed or annotated tags - git tag -a/-s) and
- 	# LOCALVERSION= is not specified
--	if test "${LOCALVERSION+set}" != "set"; then
-+	if test "${CONFIG_LOCALVERSION+set}" != "set"; then
- 		scm=$(scm_version --short)
- 		res="$res${scm:++}"
- 	fi
diff --git a/target/linux/generic/patches-2.6.38/201-extra_optimization.patch b/target/linux/generic/patches-2.6.38/201-extra_optimization.patch
deleted file mode 100644
index d173e4c753..0000000000
--- a/target/linux/generic/patches-2.6.38/201-extra_optimization.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- a/Makefile
-+++ b/Makefile
-@@ -539,9 +539,9 @@ endif # $(dot-config)
- all: vmlinux
- 
- ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
--KBUILD_CFLAGS	+= -Os
-+KBUILD_CFLAGS	+= -Os -fno-caller-saves
- else
--KBUILD_CFLAGS	+= -O2
-+KBUILD_CFLAGS	+= -O2 -fno-reorder-blocks -fno-tree-ch -fno-caller-saves
- endif
- 
- include $(srctree)/arch/$(SRCARCH)/Makefile
-@@ -596,6 +596,9 @@ endif
- NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
- CHECKFLAGS     += $(NOSTDINC_FLAGS)
- 
-+# improve gcc optimization
-+CFLAGS += $(call cc-option,-funit-at-a-time,)
-+
- # warn about C99 declaration after statement
- KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
- 
diff --git a/target/linux/generic/patches-2.6.38/210-darwin_scripts_include.patch b/target/linux/generic/patches-2.6.38/210-darwin_scripts_include.patch
deleted file mode 100644
index 0686a38973..0000000000
--- a/target/linux/generic/patches-2.6.38/210-darwin_scripts_include.patch
+++ /dev/null
@@ -1,78 +0,0 @@
---- a/scripts/kallsyms.c
-+++ b/scripts/kallsyms.c
-@@ -22,6 +22,35 @@
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-+#ifdef __APPLE__
-+/* Darwin has no memmem implementation, this one is ripped of the uClibc-0.9.28 source */
-+void *memmem (const void *haystack, size_t haystack_len,
-+                          const void *needle,  size_t needle_len)
-+{
-+  const char *begin;
-+  const char *const last_possible
-+    = (const char *) haystack + haystack_len - needle_len;
-+
-+  if (needle_len == 0)
-+    /* The first occurrence of the empty string is deemed to occur at
-+       the beginning of the string.  */
-+    return (void *) haystack;
-+
-+  /* Sanity check, otherwise the loop might search through the whole
-+     memory.  */
-+  if (__builtin_expect (haystack_len < needle_len, 0))
-+    return NULL;
-+
-+  for (begin = (const char *) haystack; begin <= last_possible; ++begin)
-+    if (begin[0] == ((const char *) needle)[0] &&
-+        !memcmp ((const void *) &begin[1],
-+                 (const void *) ((const char *) needle + 1),
-+                 needle_len - 1))
-+      return (void *) begin;
-+
-+  return NULL;
-+}
-+#endif
- 
- #ifndef ARRAY_SIZE
- #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
---- a/scripts/kconfig/Makefile
-+++ b/scripts/kconfig/Makefile
-@@ -147,6 +147,9 @@ check-lxdialog  := $(srctree)/$(src)/lxd
- # we really need to do so. (Do not call gcc as part of make mrproper)
- HOST_EXTRACFLAGS += $(shell $(CONFIG_SHELL) $(check-lxdialog) -ccflags) \
-                     -DLOCALE
-+ifeq ($(shell uname -s),Darwin)
-+HOST_LOADLIBES  += -lncurses
-+endif
- 
- # ===========================================================================
- # Shared Makefile for the various kconfig executables:
---- a/scripts/mod/mk_elfconfig.c
-+++ b/scripts/mod/mk_elfconfig.c
-@@ -1,7 +1,11 @@
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-+#ifndef __APPLE__
- #include <elf.h>
-+#else
-+#include "../../../../../tools/sstrip/include/elf.h"
-+#endif
- 
- int
- main(int argc, char **argv)
---- a/scripts/mod/modpost.h
-+++ b/scripts/mod/modpost.h
-@@ -7,7 +7,11 @@
- #include <sys/mman.h>
- #include <fcntl.h>
- #include <unistd.h>
-+#if !(defined(__APPLE__) || defined(__CYGWIN__))
- #include <elf.h>
-+#else
-+#include "../../../../../tools/sstrip/include/elf.h"
-+#endif
- 
- #include "elfconfig.h"
- 
diff --git a/target/linux/generic/patches-2.6.38/211-stddef_include.patch b/target/linux/generic/patches-2.6.38/211-stddef_include.patch
deleted file mode 100644
index 7fe248d8d3..0000000000
--- a/target/linux/generic/patches-2.6.38/211-stddef_include.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- a/include/linux/stddef.h
-+++ b/include/linux/stddef.h
-@@ -16,6 +16,7 @@ enum {
- 	false	= 0,
- 	true	= 1
- };
-+#endif /* __KERNEL__ */
- 
- #undef offsetof
- #ifdef __compiler_offsetof
-@@ -23,6 +24,5 @@ enum {
- #else
- #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
- #endif
--#endif /* __KERNEL__ */
- 
- #endif
diff --git a/target/linux/generic/patches-2.6.38/220-module_exports.patch b/target/linux/generic/patches-2.6.38/220-module_exports.patch
deleted file mode 100644
index 5268115f01..0000000000
--- a/target/linux/generic/patches-2.6.38/220-module_exports.patch
+++ /dev/null
@@ -1,119 +0,0 @@
---- a/include/asm-generic/vmlinux.lds.h
-+++ b/include/asm-generic/vmlinux.lds.h
-@@ -52,6 +52,27 @@
- #define LOAD_OFFSET 0
- #endif
- 
-+#ifndef SYMTAB_KEEP_STR
-+#define SYMTAB_KEEP_STR *(__ksymtab_strings.*)
-+#define SYMTAB_DISCARD_STR
-+#else
-+#define SYMTAB_DISCARD_STR *(__ksymtab_strings.*)
-+#endif
-+
-+#ifndef SYMTAB_KEEP
-+#define SYMTAB_KEEP *(__ksymtab.*)
-+#define SYMTAB_DISCARD
-+#else
-+#define SYMTAB_DISCARD *(__ksymtab.*)
-+#endif
-+
-+#ifndef SYMTAB_KEEP_GPL
-+#define SYMTAB_KEEP_GPL *(__ksymtab_gpl.*)
-+#define SYMTAB_DISCARD_GPL
-+#else
-+#define SYMTAB_DISCARD_GPL *(__ksymtab_gpl.*)
-+#endif
-+
- #ifndef SYMBOL_PREFIX
- #define VMLINUX_SYMBOL(sym) sym
- #else
-@@ -274,35 +295,35 @@
- 	/* Kernel symbol table: Normal symbols */			\
- 	__ksymtab         : AT(ADDR(__ksymtab) - LOAD_OFFSET) {		\
- 		VMLINUX_SYMBOL(__start___ksymtab) = .;			\
--		*(__ksymtab)						\
-+		SYMTAB_KEEP						\
- 		VMLINUX_SYMBOL(__stop___ksymtab) = .;			\
- 	}								\
- 									\
- 	/* Kernel symbol table: GPL-only symbols */			\
- 	__ksymtab_gpl     : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) {	\
- 		VMLINUX_SYMBOL(__start___ksymtab_gpl) = .;		\
--		*(__ksymtab_gpl)					\
-+		SYMTAB_KEEP_GPL						\
- 		VMLINUX_SYMBOL(__stop___ksymtab_gpl) = .;		\
- 	}								\
- 									\
- 	/* Kernel symbol table: Normal unused symbols */		\
- 	__ksymtab_unused  : AT(ADDR(__ksymtab_unused) - LOAD_OFFSET) {	\
- 		VMLINUX_SYMBOL(__start___ksymtab_unused) = .;		\
--		*(__ksymtab_unused)					\
-+		*(__ksymtab_unused.*)					\
- 		VMLINUX_SYMBOL(__stop___ksymtab_unused) = .;		\
- 	}								\
- 									\
- 	/* Kernel symbol table: GPL-only unused symbols */		\
- 	__ksymtab_unused_gpl : AT(ADDR(__ksymtab_unused_gpl) - LOAD_OFFSET) { \
- 		VMLINUX_SYMBOL(__start___ksymtab_unused_gpl) = .;	\
--		*(__ksymtab_unused_gpl)					\
-+		*(__ksymtab_unused_gpl.*)				\
- 		VMLINUX_SYMBOL(__stop___ksymtab_unused_gpl) = .;	\
- 	}								\
- 									\
- 	/* Kernel symbol table: GPL-future-only symbols */		\
- 	__ksymtab_gpl_future : AT(ADDR(__ksymtab_gpl_future) - LOAD_OFFSET) { \
- 		VMLINUX_SYMBOL(__start___ksymtab_gpl_future) = .;	\
--		*(__ksymtab_gpl_future)					\
-+		*(__ksymtab_gpl_future.*)				\
- 		VMLINUX_SYMBOL(__stop___ksymtab_gpl_future) = .;	\
- 	}								\
- 									\
-@@ -343,7 +364,7 @@
- 									\
- 	/* Kernel symbol table: strings */				\
-         __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) {	\
--		*(__ksymtab_strings)					\
-+		SYMTAB_KEEP_STR						\
- 	}								\
- 									\
- 	/* __*init sections */						\
-@@ -677,6 +698,9 @@
- 	EXIT_TEXT							\
- 	EXIT_DATA							\
- 	EXIT_CALL							\
-+	SYMTAB_DISCARD							\
-+	SYMTAB_DISCARD_GPL						\
-+	SYMTAB_DISCARD_STR						\
- 	*(.discard)							\
- 	*(.discard.*)							\
- 	}
---- a/include/linux/module.h
-+++ b/include/linux/module.h
-@@ -229,16 +229,24 @@ struct module_use {
- #define __CRC_SYMBOL(sym, sec)
- #endif
- 
-+#ifdef MODULE
-+#define __EXPORT_SUFFIX(sym)
-+#else
-+#define __EXPORT_SUFFIX(sym) "." #sym
-+#endif
-+
- /* For every exported symbol, place a struct in the __ksymtab section */
- #define __EXPORT_SYMBOL(sym, sec)				\
- 	extern typeof(sym) sym;					\
- 	__CRC_SYMBOL(sym, sec)					\
- 	static const char __kstrtab_##sym[]			\
--	__attribute__((section("__ksymtab_strings"), aligned(1))) \
-+	__attribute__((section("__ksymtab_strings"		\
-+	  __EXPORT_SUFFIX(sym)), aligned(1)))			\
- 	= MODULE_SYMBOL_PREFIX #sym;                    	\
- 	static const struct kernel_symbol __ksymtab_##sym	\
- 	__used							\
--	__attribute__((section("__ksymtab" sec), unused))	\
-+	__attribute__((section("__ksymtab" sec			\
-+	  __EXPORT_SUFFIX(sym)), unused))			\
- 	= { (unsigned long)&sym, __kstrtab_##sym }
- 
- #define EXPORT_SYMBOL(sym)					\
diff --git a/target/linux/generic/patches-2.6.38/230-openwrt_lzma_options.patch b/target/linux/generic/patches-2.6.38/230-openwrt_lzma_options.patch
deleted file mode 100644
index 8819a633ac..0000000000
--- a/target/linux/generic/patches-2.6.38/230-openwrt_lzma_options.patch
+++ /dev/null
@@ -1,54 +0,0 @@
---- a/scripts/Makefile.lib
-+++ b/scripts/Makefile.lib
-@@ -254,7 +254,7 @@ cmd_bzip2 = (cat $(filter-out FORCE,$^)
- 
- quiet_cmd_lzma = LZMA    $@
- cmd_lzma = (cat $(filter-out FORCE,$^) | \
--	lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
-+	lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
- 	(rm -f $@ ; false)
- 
- quiet_cmd_lzo = LZO     $@
---- a/scripts/gen_initramfs_list.sh
-+++ b/scripts/gen_initramfs_list.sh
-@@ -226,7 +226,7 @@ cpio_list=
- output="/dev/stdout"
- output_file=""
- is_cpio_compressed=
--compr="gzip -9 -f"
-+compr="gzip -9 -f -"
- 
- arg="$1"
- case "$arg" in
-@@ -240,9 +240,9 @@ case "$arg" in
- 		output_file="$1"
- 		cpio_list="$(mktemp ${TMPDIR:-/tmp}/cpiolist.XXXXXX)"
- 		output=${cpio_list}
--		echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f"
--		echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f"
--		echo "$output_file" | grep -q "\.lzma$" && compr="lzma -9 -f"
-+		echo "$output_file" | grep -q "\.gz$" && compr="gzip -9 -f -"
-+		echo "$output_file" | grep -q "\.bz2$" && compr="bzip2 -9 -f -"
-+		echo "$output_file" | grep -q "\.lzma$" && compr="lzma e -d20 -lc1 -lp2 -pb2 -eos -si -so"
- 		echo "$output_file" | grep -q "\.xz$" && \
- 				compr="xz --check=crc32 --lzma2=dict=1MiB"
- 		echo "$output_file" | grep -q "\.lzo$" && compr="lzop -9 -f"
-@@ -296,7 +296,7 @@ if [ ! -z ${output_file} ]; then
- 	if [ "${is_cpio_compressed}" = "compressed" ]; then
- 		cat ${cpio_tfile} > ${output_file}
- 	else
--		(cat ${cpio_tfile} | ${compr}  - > ${output_file}) \
-+		(cat ${cpio_tfile} | ${compr} > ${output_file}) \
- 		|| (rm -f ${output_file} ; false)
- 	fi
- 	[ -z ${cpio_file} ] && rm ${cpio_tfile}
---- a/lib/decompress.c
-+++ b/lib/decompress.c
-@@ -40,6 +40,7 @@ static const struct compress_format {
- 	{ {037, 0236}, "gzip", gunzip },
- 	{ {0x42, 0x5a}, "bzip2", bunzip2 },
- 	{ {0x5d, 0x00}, "lzma", unlzma },
-+	{ {0x6d, 0x00}, "lzma-openwrt", unlzma },
- 	{ {0xfd, 0x37}, "xz", unxz },
- 	{ {0x89, 0x4c}, "lzo", unlzo },
- 	{ {0, 0}, NULL, NULL }
diff --git a/target/linux/generic/patches-2.6.38/250-netfilter_depends.patch b/target/linux/generic/patches-2.6.38/250-netfilter_depends.patch
deleted file mode 100644
index d270e9020b..0000000000
--- a/target/linux/generic/patches-2.6.38/250-netfilter_depends.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -152,7 +152,6 @@ config NF_CONNTRACK_FTP
- 
- config NF_CONNTRACK_H323
- 	tristate "H.323 protocol support"
--	depends on (IPV6 || IPV6=n)
- 	depends on NETFILTER_ADVANCED
- 	help
- 	  H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -558,7 +557,6 @@ config NETFILTER_XT_TARGET_SECMARK
- 
- config NETFILTER_XT_TARGET_TCPMSS
- 	tristate '"TCPMSS" target support'
--	depends on (IPV6 || IPV6=n)
- 	default m if NETFILTER_ADVANCED=n
- 	---help---
- 	  This option adds a `TCPMSS' target, which allows you to alter the
diff --git a/target/linux/generic/patches-2.6.38/251-sound_kconfig.patch b/target/linux/generic/patches-2.6.38/251-sound_kconfig.patch
deleted file mode 100644
index fb3df254dc..0000000000
--- a/target/linux/generic/patches-2.6.38/251-sound_kconfig.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/sound/core/Kconfig
-+++ b/sound/core/Kconfig
-@@ -8,7 +8,7 @@ config SND_PCM
- 	select GCD
- 
- config SND_HWDEP
--	tristate
-+	tristate "Sound hardware support"
- 
- config SND_RAWMIDI
- 	tristate
diff --git a/target/linux/generic/patches-2.6.38/252-mv_cesa_depends.patch b/target/linux/generic/patches-2.6.38/252-mv_cesa_depends.patch
deleted file mode 100644
index 1fd2f6365a..0000000000
--- a/target/linux/generic/patches-2.6.38/252-mv_cesa_depends.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/crypto/Kconfig
-+++ b/drivers/crypto/Kconfig
-@@ -162,6 +162,7 @@ config CRYPTO_DEV_MV_CESA
- 	depends on PLAT_ORION
- 	select CRYPTO_ALGAPI
- 	select CRYPTO_AES
-+	select CRYPTO_HASH2
- 	select CRYPTO_BLKCIPHER2
- 	help
- 	  This driver allows you to utilize the Cryptographic Engines and
diff --git a/target/linux/generic/patches-2.6.38/253-ssb_b43_default_on.patch b/target/linux/generic/patches-2.6.38/253-ssb_b43_default_on.patch
deleted file mode 100644
index 29d2a41a3b..0000000000
--- a/target/linux/generic/patches-2.6.38/253-ssb_b43_default_on.patch
+++ /dev/null
@@ -1,29 +0,0 @@
---- a/drivers/ssb/Kconfig
-+++ b/drivers/ssb/Kconfig
-@@ -29,6 +29,7 @@ config SSB_SPROM
- config SSB_BLOCKIO
- 	bool
- 	depends on SSB
-+	default y
- 
- config SSB_PCIHOST_POSSIBLE
- 	bool
-@@ -49,7 +50,7 @@ config SSB_PCIHOST
- config SSB_B43_PCI_BRIDGE
- 	bool
- 	depends on SSB_PCIHOST
--	default n
-+	default y
- 
- config SSB_PCMCIAHOST_POSSIBLE
- 	bool
---- a/drivers/bcma/Kconfig
-+++ b/drivers/bcma/Kconfig
-@@ -17,6 +17,7 @@ config BCMA
- config BCMA_BLOCKIO
- 	bool
- 	depends on BCMA
-+	default y
- 
- config BCMA_HOST_PCI_POSSIBLE
- 	bool
diff --git a/target/linux/generic/patches-2.6.38/254-textsearch_kconfig_hacks.patch b/target/linux/generic/patches-2.6.38/254-textsearch_kconfig_hacks.patch
deleted file mode 100644
index e9577ba5a0..0000000000
--- a/target/linux/generic/patches-2.6.38/254-textsearch_kconfig_hacks.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -158,16 +158,16 @@ config REED_SOLOMON_DEC16
- # Textsearch support is select'ed if needed
- #
- config TEXTSEARCH
--	boolean
-+	boolean	"Textsearch support"
- 
- config TEXTSEARCH_KMP
--	tristate
-+	tristate "Textsearch KMP"
- 
- config TEXTSEARCH_BM
--	tristate
-+	tristate "Textsearch BM"
- 
- config TEXTSEARCH_FSM
--	tristate
-+	tristate "Textsearch FSM"
- 
- config BTREE
- 	boolean
diff --git a/target/linux/generic/patches-2.6.38/255-lib80211_kconfig_hacks.patch b/target/linux/generic/patches-2.6.38/255-lib80211_kconfig_hacks.patch
deleted file mode 100644
index c044deac00..0000000000
--- a/target/linux/generic/patches-2.6.38/255-lib80211_kconfig_hacks.patch
+++ /dev/null
@@ -1,19 +0,0 @@
---- a/net/wireless/Kconfig
-+++ b/net/wireless/Kconfig
-@@ -142,13 +142,13 @@ config LIB80211
- 	  you want this built into your kernel.
- 
- config LIB80211_CRYPT_WEP
--	tristate
-+	tristate "LIB80211_CRYPT_WEP"
- 
- config LIB80211_CRYPT_CCMP
--	tristate
-+	tristate "LIB80211_CRYPT_CCMP"
- 
- config LIB80211_CRYPT_TKIP
--	tristate
-+	tristate "LIB80211_CRYPT_TKIP"
- 
- config LIB80211_DEBUG
- 	bool "lib80211 debugging messages"
diff --git a/target/linux/generic/patches-2.6.38/256-crypto_add_kconfig_prompts.patch b/target/linux/generic/patches-2.6.38/256-crypto_add_kconfig_prompts.patch
deleted file mode 100644
index 8462c711f0..0000000000
--- a/target/linux/generic/patches-2.6.38/256-crypto_add_kconfig_prompts.patch
+++ /dev/null
@@ -1,47 +0,0 @@
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -31,7 +31,7 @@ config CRYPTO_FIPS
- 	  this is.
- 
- config CRYPTO_ALGAPI
--	tristate
-+	tristate "ALGAPI"
- 	select CRYPTO_ALGAPI2
- 	help
- 	  This option provides the API for cryptographic algorithms.
-@@ -40,7 +40,7 @@ config CRYPTO_ALGAPI2
- 	tristate
- 
- config CRYPTO_AEAD
--	tristate
-+	tristate "AEAD"
- 	select CRYPTO_AEAD2
- 	select CRYPTO_ALGAPI
- 
-@@ -49,7 +49,7 @@ config CRYPTO_AEAD2
- 	select CRYPTO_ALGAPI2
- 
- config CRYPTO_BLKCIPHER
--	tristate
-+	tristate "BLKCIPHER"
- 	select CRYPTO_BLKCIPHER2
- 	select CRYPTO_ALGAPI
- 
-@@ -60,7 +60,7 @@ config CRYPTO_BLKCIPHER2
- 	select CRYPTO_WORKQUEUE
- 
- config CRYPTO_HASH
--	tristate
-+	tristate "HASH"
- 	select CRYPTO_HASH2
- 	select CRYPTO_ALGAPI
- 
-@@ -69,7 +69,7 @@ config CRYPTO_HASH2
- 	select CRYPTO_ALGAPI2
- 
- config CRYPTO_RNG
--	tristate
-+	tristate "RNG"
- 	select CRYPTO_RNG2
- 	select CRYPTO_ALGAPI
- 
diff --git a/target/linux/generic/patches-2.6.38/257-wireless_ext_kconfig_hack.patch b/target/linux/generic/patches-2.6.38/257-wireless_ext_kconfig_hack.patch
deleted file mode 100644
index daac5898ae..0000000000
--- a/target/linux/generic/patches-2.6.38/257-wireless_ext_kconfig_hack.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/net/wireless/Kconfig
-+++ b/net/wireless/Kconfig
-@@ -1,5 +1,5 @@
- config WIRELESS_EXT
--	bool
-+	bool "Wireless extensions"
- 
- config WEXT_CORE
- 	def_bool y
-@@ -11,10 +11,10 @@ config WEXT_PROC
- 	depends on WEXT_CORE
- 
- config WEXT_SPY
--	bool
-+	bool "WEXT_SPY"
- 
- config WEXT_PRIV
--	bool
-+	bool "WEXT_PRIV"
- 
- config CFG80211
- 	tristate "cfg80211 - wireless configuration API"
diff --git a/target/linux/generic/patches-2.6.38/258-make_config_average_selectable.patch b/target/linux/generic/patches-2.6.38/258-make_config_average_selectable.patch
deleted file mode 100644
index e66391cb0a..0000000000
--- a/target/linux/generic/patches-2.6.38/258-make_config_average_selectable.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -217,6 +217,13 @@ config LRU_CACHE
- 	tristate
- 
- config AVERAGE
--	bool
-+	bool "Averaging functions"
-+	help
-+	  This option is provided for the case where no in-kernel-tree
-+	  modules require averaging functions, but a module built outside
-+	  the kernel tree does. Such modules that use library averaging
-+	  functions require Y here.
-+
-+	  If unsure, say N.
- 
- endmenu
diff --git a/target/linux/generic/patches-2.6.38/260-geode-mfd.patch b/target/linux/generic/patches-2.6.38/260-geode-mfd.patch
deleted file mode 100644
index a90b64ab55..0000000000
--- a/target/linux/generic/patches-2.6.38/260-geode-mfd.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/drivers/gpio/Kconfig
-+++ b/drivers/gpio/Kconfig
-@@ -295,7 +295,7 @@ comment "PCI GPIO expanders:"
- 
- config GPIO_CS5535
- 	tristate "AMD CS5535/CS5536 GPIO support"
--	depends on PCI && X86 && !CS5535_GPIO
-+	depends on PCI && X86 && !CS5535_GPIO && MFD_CS5535
- 	help
- 	  The AMD CS5535 and CS5536 southbridges support 28 GPIO pins that
- 	  can be used for quite a number of things.  The CS5535/6 is found on
diff --git a/target/linux/generic/patches-2.6.38/261-geode-mfd2.patch b/target/linux/generic/patches-2.6.38/261-geode-mfd2.patch
deleted file mode 100644
index ffdf26902f..0000000000
--- a/target/linux/generic/patches-2.6.38/261-geode-mfd2.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/drivers/misc/Kconfig
-+++ b/drivers/misc/Kconfig
-@@ -224,8 +224,7 @@ config SGI_XP
- 
- config CS5535_MFGPT
- 	tristate "CS5535/CS5536 Geode Multi-Function General Purpose Timer (MFGPT) support"
--	depends on PCI
--	depends on X86
-+	depends on PCI && X86 && MFD_CS5536
- 	default n
- 	help
- 	  This driver provides access to MFGPT functionality for other
diff --git a/target/linux/generic/patches-2.6.38/300-mips_expose_boot_raw.patch b/target/linux/generic/patches-2.6.38/300-mips_expose_boot_raw.patch
deleted file mode 100644
index bd83f665a3..0000000000
--- a/target/linux/generic/patches-2.6.38/300-mips_expose_boot_raw.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-From: Mark Miller <mark@mirell.org>
-
-This exposes the CONFIG_BOOT_RAW symbol in Kconfig. This is needed on
-certain Broadcom chipsets running CFE in order to load the kernel.
-
-Signed-off-by: Mark Miller <mark@mirell.org>
-Acked-by: Rob Landley <rob@landley.net>
----
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -806,9 +806,6 @@ config ARC
- config ARCH_MAY_HAVE_PC_FDC
- 	bool
- 
--config BOOT_RAW
--	bool
--
- config CEVT_BCM1480
- 	bool
- 
-@@ -2244,6 +2241,18 @@ config USE_OF
- 	help
- 	  Include support for flattened device tree machine descriptions.
- 
-+config BOOT_RAW
-+	bool "Enable the kernel to be executed from the load address"
-+	default n
-+	help
-+	 Allow the kernel to be executed from the load address for
-+	 bootloaders which cannot read the ELF format. This places
-+	 a jump to start_kernel at the load address.
-+
-+	 If unsure, say N.
-+
-+
-+
- endmenu
- 
- config LOCKDEP_SUPPORT
diff --git a/target/linux/generic/patches-2.6.38/301-mips_image_cmdline_hack.patch b/target/linux/generic/patches-2.6.38/301-mips_image_cmdline_hack.patch
deleted file mode 100644
index b499334556..0000000000
--- a/target/linux/generic/patches-2.6.38/301-mips_image_cmdline_hack.patch
+++ /dev/null
@@ -1,28 +0,0 @@
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -902,6 +902,10 @@ config SYNC_R4K
- config MIPS_MACHINE
- 	def_bool n
- 
-+config IMAGE_CMDLINE_HACK
-+	bool "OpenWrt specific image command line hack"
-+	default n
-+
- config NO_IOPORT
- 	def_bool n
- 
---- a/arch/mips/kernel/head.S
-+++ b/arch/mips/kernel/head.S
-@@ -141,6 +141,12 @@ FEXPORT(__kernel_entry)
- 	j	kernel_entry
- #endif
- 
-+#ifdef CONFIG_IMAGE_CMDLINE_HACK
-+	.ascii	"CMDLINE:"
-+EXPORT(__image_cmdline)
-+	.fill	0x400
-+#endif /* CONFIG_IMAGE_CMDLINE_HACK */
-+
- 	__REF
- 
- NESTED(kernel_entry, 16, sp)			# kernel entry point
diff --git a/target/linux/generic/patches-2.6.38/302-mips_use_generic_thread_info_allocator.patch b/target/linux/generic/patches-2.6.38/302-mips_use_generic_thread_info_allocator.patch
deleted file mode 100644
index 915bb5f92c..0000000000
--- a/target/linux/generic/patches-2.6.38/302-mips_use_generic_thread_info_allocator.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/arch/mips/include/asm/thread_info.h
-+++ b/arch/mips/include/asm/thread_info.h
-@@ -85,6 +85,7 @@ register struct thread_info *__current_t
- 
- #define STACK_WARN	(THREAD_SIZE / 8)
- 
-+#if 0
- #define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
- 
- #ifdef CONFIG_DEBUG_STACK_USAGE
-@@ -94,6 +95,7 @@ register struct thread_info *__current_t
- #endif
- 
- #define free_thread_info(info) kfree(info)
-+#endif
- 
- #endif /* !__ASSEMBLY__ */
- 
diff --git a/target/linux/generic/patches-2.6.38/303-mips_fix_kexec.patch b/target/linux/generic/patches-2.6.38/303-mips_fix_kexec.patch
deleted file mode 100644
index e6928dde91..0000000000
--- a/target/linux/generic/patches-2.6.38/303-mips_fix_kexec.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/arch/mips/kernel/machine_kexec.c
-+++ b/arch/mips/kernel/machine_kexec.c
-@@ -52,7 +52,7 @@ machine_kexec(struct kimage *image)
- 	reboot_code_buffer =
- 	  (unsigned long)page_address(image->control_code_page);
- 
--	kexec_start_address = image->start;
-+	kexec_start_address = (unsigned long) phys_to_virt(image->start);
- 	kexec_indirection_page =
- 		(unsigned long) phys_to_virt(image->head & PAGE_MASK);
- 
diff --git a/target/linux/generic/patches-2.6.38/304-mips_disable_fpu.patch b/target/linux/generic/patches-2.6.38/304-mips_disable_fpu.patch
deleted file mode 100644
index d1f60df64d..0000000000
--- a/target/linux/generic/patches-2.6.38/304-mips_disable_fpu.patch
+++ /dev/null
@@ -1,160 +0,0 @@
-MIPS: allow disabling the kernel FPU emulator
-
-This patch allows turning off the in-kernel Algorithmics
-FPU emulator support, which allows one to save a couple of
-precious blocks on an embedded system.
-
-Signed-off-by: Florian Fainelli <florian@openwrt.org>
---
---- a/arch/mips/Kconfig
-+++ b/arch/mips/Kconfig
-@@ -887,6 +887,17 @@ config I8259
- config MIPS_BONITO64
- 	bool
- 
-+config MIPS_FPU_EMU
-+	bool "Enable FPU emulation"
-+	default y
-+	help
-+	   This option allows building a kernel with or without the Algorithmics
-+	   FPU emulator enabled. Turning off this option results in a kernel which
-+	   does not catch floating operations exceptions. Make sure that your toolchain
-+	   is configured to enable software floating point emulation in that case.
-+		
-+	   If unsure say Y here.
-+
- config MIPS_MSC
- 	bool
- 
---- a/arch/mips/math-emu/Makefile
-+++ b/arch/mips/math-emu/Makefile
-@@ -2,11 +2,13 @@
- # Makefile for the Linux/MIPS kernel FPU emulation.
- #
- 
--obj-y	:= cp1emu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
-+obj-y	:=	kernel_linkage.o dsemul.o cp1emu.o
-+
-+obj-$(CONFIG_MIPS_FPU_EMU)	+= ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \
- 	   ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \
- 	   dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \
- 	   dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \
- 	   sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \
- 	   sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \
--	   dp_sqrt.o sp_sqrt.o kernel_linkage.o dsemul.o
-+	   dp_sqrt.o sp_sqrt.o
- 
---- a/arch/mips/math-emu/cp1emu.c
-+++ b/arch/mips/math-emu/cp1emu.c
-@@ -58,7 +58,11 @@
- #define __mips 4
- 
- /* Function which emulates a floating point instruction. */
-+#ifdef CONFIG_DEBUG_FS
-+DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
-+#endif
- 
-+#ifdef CONFIG_MIPS_FPU_EMU
- static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *,
- 	mips_instruction);
- 
-@@ -69,10 +73,6 @@ static int fpux_emu(struct pt_regs *,
- 
- /* Further private data for which no space exists in mips_fpu_struct */
- 
--#ifdef CONFIG_DEBUG_FS
--DEFINE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
--#endif
--
- /* Control registers */
- 
- #define FPCREG_RID	0	/* $0  = revision id */
-@@ -1361,7 +1361,6 @@ int fpu_emulator_cop1Handler(struct pt_r
- 
- 	return sig;
- }
--
- #ifdef CONFIG_DEBUG_FS
- 
- static int fpuemu_stat_get(void *data, u64 *val)
-@@ -1410,4 +1409,11 @@ static int __init debugfs_fpuemu(void)
- 	return 0;
- }
- __initcall(debugfs_fpuemu);
--#endif
-+#endif /* CONFIG_DEBUGFS */
-+#else
-+int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
-+        int has_fpu)
-+{
-+	return 0;
-+}
-+#endif /* CONFIG_MIPS_FPU_EMU */
---- a/arch/mips/math-emu/dsemul.c
-+++ b/arch/mips/math-emu/dsemul.c
-@@ -109,6 +109,7 @@ int mips_dsemul(struct pt_regs *regs, mi
- 	return SIGILL;		/* force out of emulation loop */
- }
- 
-+#ifdef CONFIG_MIPS_FPU_EMU
- int do_dsemulret(struct pt_regs *xcp)
- {
- 	struct emuframe __user *fr;
-@@ -165,3 +166,9 @@ int do_dsemulret(struct pt_regs *xcp)
- 
- 	return 1;
- }
-+#else
-+int do_dsemulret(struct pt_regs *xcp)
-+{
-+	return 0;
-+}
-+#endif /* CONFIG_MIPS_FPU_EMU */
---- a/arch/mips/math-emu/kernel_linkage.c
-+++ b/arch/mips/math-emu/kernel_linkage.c
-@@ -29,6 +29,7 @@
- 
- #define SIGNALLING_NAN 0x7ff800007ff80000LL
- 
-+#ifdef CONFIG_MIPS_FPU_EMU
- void fpu_emulator_init_fpu(void)
- {
- 	static int first = 1;
-@@ -112,4 +113,36 @@ int fpu_emulator_restore_context32(struc
- 
- 	return err;
- }
--#endif
-+#endif	/* CONFIG_64BIT */
-+#else
-+
-+void fpu_emulator_init_fpu(void)
-+{
-+	printk(KERN_INFO "FPU emulator disabled, make sure your toolchain"
-+		"was compiled with software floating point support (soft-float)\n");
-+	return;
-+}
-+
-+int fpu_emulator_save_context(struct sigcontext __user *sc)
-+{
-+	return 0;
-+}
-+
-+int fpu_emulator_restore_context(struct sigcontext __user *sc)
-+{
-+	return 0;
-+}
-+
-+int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
-+{
-+	return 0;
-+}
-+
-+int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
-+{
-+	return 0;
-+}
-+
-+#ifdef CONFIG_64BIT
-+#endif	/* CONFIG_64BIT */
-+#endif /* CONFIG_MIPS_FPU_EMU */
diff --git a/target/linux/generic/patches-2.6.38/305-mips_module_reloc.patch b/target/linux/generic/patches-2.6.38/305-mips_module_reloc.patch
deleted file mode 100644
index 5513962cb2..0000000000
--- a/target/linux/generic/patches-2.6.38/305-mips_module_reloc.patch
+++ /dev/null
@@ -1,370 +0,0 @@
---- a/arch/mips/Makefile
-+++ b/arch/mips/Makefile
-@@ -90,8 +90,8 @@ all-$(CONFIG_SYS_SUPPORTS_ZBOOT)+= vmlin
- cflags-y			+= -G 0 -mno-abicalls -fno-pic -pipe
- cflags-y			+= -msoft-float
- LDFLAGS_vmlinux			+= -G 0 -static -n -nostdlib
--KBUILD_AFLAGS_MODULE		+= -mlong-calls
--KBUILD_CFLAGS_MODULE		+= -mlong-calls
-+KBUILD_AFLAGS_MODULE		+= -mno-long-calls
-+KBUILD_CFLAGS_MODULE		+= -mno-long-calls
- 
- cflags-y += -ffreestanding
- 
---- a/arch/mips/include/asm/module.h
-+++ b/arch/mips/include/asm/module.h
-@@ -9,6 +9,11 @@ struct mod_arch_specific {
- 	struct list_head dbe_list;
- 	const struct exception_table_entry *dbe_start;
- 	const struct exception_table_entry *dbe_end;
-+
-+	void *phys_plt_tbl;
-+	void *virt_plt_tbl;
-+	unsigned int phys_plt_offset;
-+	unsigned int virt_plt_offset;
- };
- 
- typedef uint8_t Elf64_Byte;		/* Type for a 8-bit quantity.  */
---- a/arch/mips/kernel/module.c
-+++ b/arch/mips/kernel/module.c
-@@ -45,6 +45,117 @@ static struct mips_hi16 *mips_hi16_list;
- static LIST_HEAD(dbe_list);
- static DEFINE_SPINLOCK(dbe_lock);
- 
-+/*
-+ * Get the potential max trampolines size required of the init and
-+ * non-init sections. Only used if we cannot find enough contiguous
-+ * physically mapped memory to put the module into.
-+ */
-+static unsigned int
-+get_plt_size(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs,
-+             const char *secstrings, unsigned int symindex, bool is_init)
-+{
-+	unsigned long ret = 0;
-+	unsigned int i, j;
-+	Elf_Sym *syms;
-+
-+	/* Everything marked ALLOC (this includes the exported symbols) */
-+	for (i = 1; i < hdr->e_shnum; ++i) {
-+		unsigned int info = sechdrs[i].sh_info;
-+
-+		if (sechdrs[i].sh_type != SHT_REL
-+		    && sechdrs[i].sh_type != SHT_RELA)
-+			continue;
-+
-+		/* Not a valid relocation section? */
-+		if (info >= hdr->e_shnum)
-+			continue;
-+
-+		/* Don't bother with non-allocated sections */
-+		if (!(sechdrs[info].sh_flags & SHF_ALLOC))
-+			continue;
-+
-+		/* If it's called *.init*, and we're not init, we're
-+                   not interested */
-+		if ((strstr(secstrings + sechdrs[i].sh_name, ".init") != 0)
-+		    != is_init)
-+			continue;
-+
-+		syms = (Elf_Sym *) sechdrs[symindex].sh_addr;
-+		if (sechdrs[i].sh_type == SHT_REL) {
-+			Elf_Mips_Rel *rel = (void *) sechdrs[i].sh_addr;
-+			unsigned int size = sechdrs[i].sh_size / sizeof(*rel);
-+
-+			for (j = 0; j < size; ++j) {
-+				Elf_Sym *sym;
-+
-+				if (ELF_MIPS_R_TYPE(rel[j]) != R_MIPS_26)
-+					continue;
-+
-+				sym = syms + ELF_MIPS_R_SYM(rel[j]);
-+				if (!is_init && sym->st_shndx != SHN_UNDEF)
-+					continue;
-+
-+				ret += 4 * sizeof(int);
-+			}
-+		} else {
-+			Elf_Mips_Rela *rela = (void *) sechdrs[i].sh_addr;
-+			unsigned int size = sechdrs[i].sh_size / sizeof(*rela);
-+
-+			for (j = 0; j < size; ++j) {
-+				Elf_Sym *sym;
-+
-+				if (ELF_MIPS_R_TYPE(rela[j]) != R_MIPS_26)
-+					continue;
-+
-+				sym = syms + ELF_MIPS_R_SYM(rela[j]);
-+				if (!is_init && sym->st_shndx != SHN_UNDEF)
-+					continue;
-+
-+				ret += 4 * sizeof(int);
-+			}
-+		}
-+	}
-+
-+	return ret;
-+}
-+
-+#ifndef MODULE_START
-+static void *alloc_phys(unsigned long size)
-+{
-+	unsigned order;
-+	struct page *page;
-+	struct page *p;
-+
-+	size = PAGE_ALIGN(size);
-+	order = get_order(size);
-+
-+	page = alloc_pages(GFP_KERNEL | __GFP_NORETRY | __GFP_NOWARN |
-+			__GFP_THISNODE, order);
-+	if (!page)
-+		return NULL;
-+
-+	split_page(page, order);
-+
-+	for (p = page + (size >> PAGE_SHIFT); p < page + (1 << order); ++p)
-+		__free_page(p);
-+
-+	return page_address(page);
-+}
-+#endif
-+
-+static void free_phys(void *ptr, unsigned long size)
-+{
-+	struct page *page;
-+	struct page *end;
-+
-+	page = virt_to_page(ptr);
-+	end = page + (PAGE_ALIGN(size) >> PAGE_SHIFT);
-+
-+	for (; page < end; ++page)
-+		__free_page(page);
-+}
-+
-+
- void *module_alloc(unsigned long size)
- {
- #ifdef MODULE_START
-@@ -52,21 +163,99 @@ void *module_alloc(unsigned long size)
- 				GFP_KERNEL, PAGE_KERNEL, -1,
- 				__builtin_return_address(0));
- #else
-+	void *ptr;
-+
- 	if (size == 0)
- 		return NULL;
--	return vmalloc(size);
-+
-+	ptr = alloc_phys(size);
-+
-+	/* If we failed to allocate physically contiguous memory,
-+	 * fall back to regular vmalloc. The module loader code will
-+	 * create jump tables to handle long jumps */
-+	if (!ptr)
-+		return vmalloc(size);
-+
-+	return ptr;
-+#endif
-+}
-+
-+static inline bool is_phys_addr(void *ptr)
-+{
-+#ifdef CONFIG_64BIT
-+	return (KSEGX((unsigned long)ptr) == CKSEG0);
-+#else
-+	return (KSEGX(ptr) == KSEG0);
- #endif
- }
- 
- /* Free memory returned from module_alloc */
- void module_free(struct module *mod, void *module_region)
- {
--	vfree(module_region);
-+	if (is_phys_addr(module_region)) {
-+		if (mod->module_init == module_region)
-+			free_phys(module_region, mod->init_size);
-+		else if (mod->module_core == module_region)
-+			free_phys(module_region, mod->core_size);
-+		else
-+			BUG();
-+	} else {
-+		vfree(module_region);
-+	}
-+}
-+
-+static void *__module_alloc(int size, bool phys)
-+{
-+	void *ptr;
-+
-+	if (phys)
-+		ptr = kmalloc(size, GFP_KERNEL);
-+	else
-+		ptr = vmalloc(size);
-+	return ptr;
-+}
-+
-+static void __module_free(void *ptr)
-+{
-+	if (is_phys_addr(ptr))
-+		kfree(ptr);
-+	else
-+		vfree(ptr);
- }
- 
- int module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
- 			      char *secstrings, struct module *mod)
- {
-+	unsigned int symindex = 0;
-+	unsigned int core_size, init_size;
-+	int i;
-+
-+	for (i = 1; i < hdr->e_shnum; i++)
-+		if (sechdrs[i].sh_type == SHT_SYMTAB)
-+			symindex = i;
-+
-+	core_size = get_plt_size(hdr, sechdrs, secstrings, symindex, false);
-+	init_size = get_plt_size(hdr, sechdrs, secstrings, symindex, true);
-+
-+	mod->arch.phys_plt_offset = 0;
-+	mod->arch.virt_plt_offset = 0;
-+	mod->arch.phys_plt_tbl = NULL;
-+	mod->arch.virt_plt_tbl = NULL;
-+
-+	if ((core_size + init_size) == 0)
-+		return 0;
-+
-+	mod->arch.phys_plt_tbl = __module_alloc(core_size + init_size, 1);
-+	if (!mod->arch.phys_plt_tbl)
-+		return -ENOMEM;
-+
-+	mod->arch.virt_plt_tbl = __module_alloc(core_size + init_size, 0);
-+	if (!mod->arch.virt_plt_tbl) {
-+		__module_free(mod->arch.phys_plt_tbl);
-+		mod->arch.phys_plt_tbl = NULL;
-+		return -ENOMEM;
-+	}
-+
- 	return 0;
- }
- 
-@@ -89,28 +278,36 @@ static int apply_r_mips_32_rela(struct m
- 	return 0;
- }
- 
--static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
-+static Elf_Addr add_plt_entry_to(unsigned *plt_offset,
-+				 void *start, Elf_Addr v)
- {
--	if (v % 4) {
--		pr_err("module %s: dangerous R_MIPS_26 REL relocation\n",
--		       me->name);
--		return -ENOEXEC;
--	}
-+	unsigned *tramp = start + *plt_offset;
-+	*plt_offset += 4 * sizeof(int);
- 
--	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
--		printk(KERN_ERR
--		       "module %s: relocation overflow\n",
--		       me->name);
--		return -ENOEXEC;
--	}
-+	/* adjust carry for addiu */
-+	if (v & 0x00008000)
-+		v += 0x10000;
- 
--	*location = (*location & ~0x03ffffff) |
--	            ((*location + (v >> 2)) & 0x03ffffff);
-+	tramp[0] = 0x3c190000 | (v >> 16);      /* lui t9, hi16 */
-+	tramp[1] = 0x27390000 | (v & 0xffff);   /* addiu t9, t9, lo16 */
-+	tramp[2] = 0x03200008;                  /* jr t9 */
-+	tramp[3] = 0x00000000;                  /* nop */
- 
--	return 0;
-+	return (Elf_Addr) tramp;
- }
- 
--static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
-+static Elf_Addr add_plt_entry(struct module *me, void *location, Elf_Addr v)
-+{
-+	if (is_phys_addr(location))
-+		return add_plt_entry_to(&me->arch.phys_plt_offset,
-+				me->arch.phys_plt_tbl, v);
-+	else
-+		return add_plt_entry_to(&me->arch.virt_plt_offset,
-+				me->arch.virt_plt_tbl, v);
-+
-+}
-+
-+static int set_r_mips_26(struct module *me, u32 *location, u32 ofs, Elf_Addr v)
- {
- 	if (v % 4) {
- 		pr_err("module %s: dangerous R_MIPS_26 RELArelocation\n",
-@@ -119,17 +316,31 @@ static int apply_r_mips_26_rela(struct m
- 	}
- 
- 	if ((v & 0xf0000000) != (((unsigned long)location + 4) & 0xf0000000)) {
--		printk(KERN_ERR
-+	    v = add_plt_entry(me, location, v + (ofs << 2));
-+		if (!v) {
-+			printk(KERN_ERR
- 		       "module %s: relocation overflow\n",
- 		       me->name);
--		return -ENOEXEC;
-+			return -ENOEXEC;
-+		}
-+		ofs = 0;
- 	}
- 
--	*location = (*location & ~0x03ffffff) | ((v >> 2) & 0x03ffffff);
-+	*location = (*location & ~0x03ffffff) | ((ofs + (v >> 2)) & 0x03ffffff);
- 
- 	return 0;
- }
- 
-+static int apply_r_mips_26_rel(struct module *me, u32 *location, Elf_Addr v)
-+{
-+	return set_r_mips_26(me, location, *location & 0x03ffffff, v);
-+}
-+
-+static int apply_r_mips_26_rela(struct module *me, u32 *location, Elf_Addr v)
-+{
-+	return set_r_mips_26(me, location, 0, v);
-+}
-+
- static int apply_r_mips_hi16_rel(struct module *me, u32 *location, Elf_Addr v)
- {
- 	struct mips_hi16 *n;
-@@ -397,11 +608,32 @@ int module_finalize(const Elf_Ehdr *hdr,
- 		list_add(&me->arch.dbe_list, &dbe_list);
- 		spin_unlock_irq(&dbe_lock);
- 	}
-+
-+	/* Get rid of the fixup trampoline if we're running the module
-+	 * from physically mapped address space */
-+	if (me->arch.phys_plt_offset == 0) {
-+		__module_free(me->arch.phys_plt_tbl);
-+		me->arch.phys_plt_tbl = NULL;
-+	}
-+	if (me->arch.virt_plt_offset == 0) {
-+		__module_free(me->arch.virt_plt_tbl);
-+		me->arch.virt_plt_tbl = NULL;
-+	}
-+
- 	return 0;
- }
- 
- void module_arch_cleanup(struct module *mod)
- {
-+	if (mod->arch.phys_plt_tbl) {
-+		__module_free(mod->arch.phys_plt_tbl);
-+		mod->arch.phys_plt_tbl = NULL;
-+	}
-+	if (mod->arch.virt_plt_tbl) {
-+		__module_free(mod->arch.virt_plt_tbl);
-+		mod->arch.virt_plt_tbl = NULL;
-+	}
-+
- 	spin_lock_irq(&dbe_lock);
- 	list_del(&mod->arch.dbe_list);
- 	spin_unlock_irq(&dbe_lock);
diff --git a/target/linux/generic/patches-2.6.38/306-mips_mem_functions_performance.patch b/target/linux/generic/patches-2.6.38/306-mips_mem_functions_performance.patch
deleted file mode 100644
index e4324717b4..0000000000
--- a/target/linux/generic/patches-2.6.38/306-mips_mem_functions_performance.patch
+++ /dev/null
@@ -1,83 +0,0 @@
---- a/arch/mips/include/asm/string.h
-+++ b/arch/mips/include/asm/string.h
-@@ -133,11 +133,44 @@ strncmp(__const__ char *__cs, __const__
- 
- #define __HAVE_ARCH_MEMSET
- extern void *memset(void *__s, int __c, size_t __count);
-+#define memset(__s, __c, len)					\
-+({								\
-+	size_t __len = (len);					\
-+	void *__ret;						\
-+	if (__builtin_constant_p(len) && __len >= 64)		\
-+		__ret = memset((__s), (__c), __len);		\
-+	else							\
-+		__ret = __builtin_memset((__s), (__c), __len);	\
-+	__ret;							\
-+})
- 
- #define __HAVE_ARCH_MEMCPY
- extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
-+#define memcpy(dst, src, len)					\
-+({								\
-+	size_t __len = (len);					\
-+	void *__ret;						\
-+	if (__builtin_constant_p(len) && __len >= 64)		\
-+		__ret = memcpy((dst), (src), __len);		\
-+	else							\
-+		__ret = __builtin_memcpy((dst), (src), __len);	\
-+	__ret;							\
-+})
- 
- #define __HAVE_ARCH_MEMMOVE
- extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
-+#define memmove(dst, src, len)					\
-+({								\
-+	size_t __len = (len);					\
-+	void *__ret;						\
-+	if (__builtin_constant_p(len) && __len >= 64)		\
-+		__ret = memmove((dst), (src), __len);		\
-+	else							\
-+		__ret = __builtin_memmove((dst), (src), __len);	\
-+	__ret;							\
-+})
-+
-+#define __HAVE_ARCH_MEMCMP
-+#define memcmp(src1, src2, len) __builtin_memcmp((src1), (src2), (len))
- 
- #endif /* _ASM_STRING_H */
---- a/arch/mips/lib/Makefile
-+++ b/arch/mips/lib/Makefile
-@@ -3,7 +3,7 @@
- #
- 
- lib-y	+= csum_partial.o delay.o memcpy.o memcpy-inatomic.o memset.o \
--	   strlen_user.o strncpy_user.o strnlen_user.o uncached.o
-+	   strlen_user.o strncpy_user.o strnlen_user.o uncached.o memcmp.o
- 
- obj-y			+= iomap.o
- obj-$(CONFIG_PCI)	+= iomap-pci.o
---- /dev/null
-+++ b/arch/mips/lib/memcmp.c
-@@ -0,0 +1,22 @@
-+/*
-+ *  copied from linux/lib/string.c
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/string.h>
-+
-+#undef memcmp
-+int memcmp(const void *cs, const void *ct, size_t count)
-+{
-+	const unsigned char *su1, *su2;
-+	int res = 0;
-+
-+	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
-+		if ((res = *su1 - *su2) != 0)
-+			break;
-+	return res;
-+}
-+EXPORT_SYMBOL(memcmp);
-+
diff --git a/target/linux/generic/patches-2.6.38/307-mips_oprofile_fix.patch b/target/linux/generic/patches-2.6.38/307-mips_oprofile_fix.patch
deleted file mode 100644
index f83c96bb81..0000000000
--- a/target/linux/generic/patches-2.6.38/307-mips_oprofile_fix.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/arch/mips/oprofile/op_model_mipsxx.c
-+++ b/arch/mips/oprofile/op_model_mipsxx.c
-@@ -298,6 +298,11 @@ static void reset_counters(void *arg)
- 	}
- }
- 
-+static irqreturn_t mipsxx_perfcount_int(int irq, void *dev_id)
-+{
-+	return mipsxx_perfcount_handler();
-+}
-+
- static int __init mipsxx_init(void)
- {
- 	int counters;
-@@ -374,6 +379,10 @@ static int __init mipsxx_init(void)
- 	save_perf_irq = perf_irq;
- 	perf_irq = mipsxx_perfcount_handler;
- 
-+	if (cp0_perfcount_irq >= 0)
-+		return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int,
-+			IRQF_SHARED, "Perfcounter", save_perf_irq);
-+
- 	return 0;
- }
- 
-@@ -381,6 +390,9 @@ static void mipsxx_exit(void)
- {
- 	int counters = op_model_mipsxx_ops.num_counters;
- 
-+	if (cp0_perfcount_irq >= 0)
-+		free_irq(cp0_perfcount_irq, save_perf_irq);
-+
- 	counters = counters_per_cpu_to_total(counters);
- 	on_each_cpu(reset_counters, (void *)(long)counters, 1);
- 
diff --git a/target/linux/generic/patches-2.6.38/310-arm_module_unresolved_weak_sym.patch b/target/linux/generic/patches-2.6.38/310-arm_module_unresolved_weak_sym.patch
deleted file mode 100644
index fe7027c070..0000000000
--- a/target/linux/generic/patches-2.6.38/310-arm_module_unresolved_weak_sym.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/arch/arm/kernel/module.c
-+++ b/arch/arm/kernel/module.c
-@@ -98,6 +98,10 @@ apply_relocate(Elf32_Shdr *sechdrs, cons
- 			return -ENOEXEC;
- 		}
- 
-+		if ((IS_ERR_VALUE(sym->st_value) || !sym->st_value) &&
-+		    ELF_ST_BIND(sym->st_info) == STB_WEAK)
-+			continue;
-+
- 		loc = dstsec->sh_addr + rel->r_offset;
- 
- 		switch (ELF32_R_TYPE(rel->r_info)) {
diff --git a/target/linux/generic/patches-2.6.38/311-arm_update_mach_types.patch b/target/linux/generic/patches-2.6.38/311-arm_update_mach_types.patch
deleted file mode 100644
index 543900348d..0000000000
--- a/target/linux/generic/patches-2.6.38/311-arm_update_mach_types.patch
+++ /dev/null
@@ -1,260 +0,0 @@
---- a/arch/arm/tools/mach-types
-+++ b/arch/arm/tools/mach-types
-@@ -12,7 +12,7 @@
- #
- #   http://www.arm.linux.org.uk/developer/machines/?action=new
- #
--# Last update: Mon Feb 7 08:59:27 2011
-+# Last update: Tue Mar 1 10:53:16 2011
- #
- # machine_is_xxx	CONFIG_xxxx		MACH_TYPE_xxx		number
- #
-@@ -1319,7 +1319,6 @@ mistral			MACH_MISTRAL		MISTRAL			1315
- msm			MACH_MSM		MSM			1316
- ct5910			MACH_CT5910		CT5910			1317
- ct5912			MACH_CT5912		CT5912			1318
--hynet_ine		MACH_HYNET_INE		HYNET_INE		1319
- hynet_app		MACH_HYNET_APP		HYNET_APP		1320
- msm7200			MACH_MSM7200		MSM7200			1321
- msm7600			MACH_MSM7600		MSM7600			1322
-@@ -1777,7 +1776,6 @@ wdg002			MACH_WDG002		WDG002			1785
- sg560adsl		MACH_SG560ADSL		SG560ADSL		1786
- nextio_n2800_ica	MACH_NEXTIO_N2800_ICA	NEXTIO_N2800_ICA	1787
- dove_db			MACH_DOVE_DB		DOVE_DB			1788
--marvell_newdb		MACH_MARVELL_NEWDB	MARVELL_NEWDB		1789
- vandihud		MACH_VANDIHUD		VANDIHUD		1790
- magx_e8			MACH_MAGX_E8		MAGX_E8			1791
- magx_z6			MACH_MAGX_Z6		MAGX_Z6			1792
-@@ -1877,7 +1875,6 @@ ued			MACH_UED		UED			1885
- esiblade		MACH_ESIBLADE		ESIBLADE		1886
- eye02			MACH_EYE02		EYE02			1887
- imx27kbd		MACH_IMX27KBD		IMX27KBD		1888
--sst61vc010_fpga		MACH_SST61VC010_FPGA	SST61VC010_FPGA		1889
- kixvp435		MACH_KIXVP435		KIXVP435		1890
- kixnp435		MACH_KIXNP435		KIXNP435		1891
- africa			MACH_AFRICA		AFRICA			1892
-@@ -2308,7 +2305,6 @@ ecac2378		MACH_ECAC2378		ECAC2378		2319
- tazkiosk		MACH_TAZKIOSK		TAZKIOSK		2320
- whiterabbit_mch		MACH_WHITERABBIT_MCH	WHITERABBIT_MCH		2321
- sbox9263		MACH_SBOX9263		SBOX9263		2322
--oreo			MACH_OREO		OREO			2323
- smdk6442		MACH_SMDK6442		SMDK6442		2324
- openrd_base		MACH_OPENRD_BASE	OPENRD_BASE		2325
- incredible		MACH_INCREDIBLE		INCREDIBLE		2326
-@@ -2374,7 +2370,6 @@ sch_m490		MACH_SCH_M490		SCH_M490		2386
- rbl01			MACH_RBL01		RBL01			2387
- omnifi			MACH_OMNIFI		OMNIFI			2388
- otavalo			MACH_OTAVALO		OTAVALO			2389
--sienna			MACH_SIENNA		SIENNA			2390
- htc_excalibur_s620	MACH_HTC_EXCALIBUR_S620	HTC_EXCALIBUR_S620	2391
- htc_opal		MACH_HTC_OPAL		HTC_OPAL		2392
- touchbook		MACH_TOUCHBOOK		TOUCHBOOK		2393
-@@ -2446,7 +2441,6 @@ siogentoo1		MACH_SIOGENTOO1		SIOGENTOO1
- siogentoo2		MACH_SIOGENTOO2		SIOGENTOO2		2459
- sm3k			MACH_SM3K		SM3K			2460
- acer_tempo_f900		MACH_ACER_TEMPO_F900	ACER_TEMPO_F900		2461
--sst61vc010_dev		MACH_SST61VC010_DEV	SST61VC010_DEV		2462
- glittertind		MACH_GLITTERTIND	GLITTERTIND		2463
- omap_zoom3		MACH_OMAP_ZOOM3		OMAP_ZOOM3		2464
- omap_3630sdp		MACH_OMAP_3630SDP	OMAP_3630SDP		2465
-@@ -2498,7 +2492,6 @@ hiram			MACH_HIRAM		HIRAM			2510
- phy3250			MACH_PHY3250		PHY3250			2511
- ea3250			MACH_EA3250		EA3250			2512
- fdi3250			MACH_FDI3250		FDI3250			2513
--whitestone		MACH_WHITESTONE		WHITESTONE		2514
- at91sam9263nit		MACH_AT91SAM9263NIT	AT91SAM9263NIT		2515
- ccmx51			MACH_CCMX51		CCMX51			2516
- ccmx51js		MACH_CCMX51JS		CCMX51JS		2517
-@@ -2561,7 +2554,6 @@ magnolia2		MACH_MAGNOLIA2		MAGNOLIA2		25
- emxx			MACH_EMXX		EMXX			2574
- outlaw			MACH_OUTLAW		OUTLAW			2575
- riot_bei2		MACH_RIOT_BEI2		RIOT_BEI2		2576
--riot_vox		MACH_RIOT_VOX		RIOT_VOX		2577
- riot_x37		MACH_RIOT_X37		RIOT_X37		2578
- mega25mx		MACH_MEGA25MX		MEGA25MX		2579
- benzina2		MACH_BENZINA2		BENZINA2		2580
-@@ -2582,7 +2574,6 @@ omap3_bulldog		MACH_OMAP3_BULLDOG	OMAP3_
- pca101			MACH_PCA101		PCA101			2595
- buzzc			MACH_BUZZC		BUZZC			2596
- sasie2			MACH_SASIE2		SASIE2			2597
--davinci_cio		MACH_DAVINCI_CIO	DAVINCI_CIO		2598
- smartmeter_dl		MACH_SMARTMETER_DL	SMARTMETER_DL		2599
- wzl6410			MACH_WZL6410		WZL6410			2600
- wzl6410m		MACH_WZL6410M		WZL6410M		2601
-@@ -2591,7 +2582,6 @@ wzl6410i		MACH_WZL6410I		WZL6410I		2603
- spacecom1		MACH_SPACECOM1		SPACECOM1		2604
- pingu920		MACH_PINGU920		PINGU920		2605
- bravoc			MACH_BRAVOC		BRAVOC			2606
--cybo2440		MACH_CYBO2440		CYBO2440		2607
- vdssw			MACH_VDSSW		VDSSW			2608
- romulus			MACH_ROMULUS		ROMULUS			2609
- omap_magic		MACH_OMAP_MAGIC		OMAP_MAGIC		2610
-@@ -2683,7 +2673,6 @@ lkevm			MACH_LKEVM		LKEVM			2695
- mw6410			MACH_MW6410		MW6410			2696
- terastation_wxl		MACH_TERASTATION_WXL	TERASTATION_WXL		2697
- cpu8000e		MACH_CPU8000E		CPU8000E		2698
--catania			MACH_CATANIA		CATANIA			2699
- tokyo			MACH_TOKYO		TOKYO			2700
- msm7201a_surf		MACH_MSM7201A_SURF	MSM7201A_SURF		2701
- msm7201a_ffa		MACH_MSM7201A_FFA	MSM7201A_FFA		2702
-@@ -2741,7 +2730,6 @@ wbd222			MACH_WBD222		WBD222			2753
- mt65xx			MACH_MT65XX		MT65XX			2754
- msm8x60_surf		MACH_MSM8X60_SURF	MSM8X60_SURF		2755
- msm8x60_sim		MACH_MSM8X60_SIM	MSM8X60_SIM		2756
--vmc300			MACH_VMC300		VMC300			2757
- tcc8000_sdk		MACH_TCC8000_SDK	TCC8000_SDK		2758
- nanos			MACH_NANOS		NANOS			2759
- stamp9g10		MACH_STAMP9G10		STAMP9G10		2760
-@@ -2750,7 +2738,6 @@ h6053			MACH_H6053		H6053			2762
- smint01			MACH_SMINT01		SMINT01			2763
- prtlvt2			MACH_PRTLVT2		PRTLVT2			2764
- ap420			MACH_AP420		AP420			2765
--htcshift		MACH_HTCSHIFT		HTCSHIFT		2766
- davinci_dm365_fc	MACH_DAVINCI_DM365_FC	DAVINCI_DM365_FC	2767
- msm8x55_surf		MACH_MSM8X55_SURF	MSM8X55_SURF		2768
- msm8x55_ffa		MACH_MSM8X55_FFA	MSM8X55_FFA		2769
-@@ -2761,7 +2748,6 @@ oreo_controller		MACH_OREO_CONTROLLER	OR
- kopin_models		MACH_KOPIN_MODELS	KOPIN_MODELS		2774
- ttc_vision2		MACH_TTC_VISION2	TTC_VISION2		2775
- cns3420vb		MACH_CNS3420VB		CNS3420VB		2776
--lpc2			MACH_LPC2		LPC2			2777
- olympus			MACH_OLYMPUS		OLYMPUS			2778
- vortex			MACH_VORTEX		VORTEX			2779
- s5pc200			MACH_S5PC200		S5PC200			2780
-@@ -2788,7 +2774,6 @@ ti8168evm		MACH_TI8168EVM		TI8168EVM		28
- neocoreomap		MACH_NEOCOREOMAP	NEOCOREOMAP		2801
- withings_wbp		MACH_WITHINGS_WBP	WITHINGS_WBP		2802
- dbps			MACH_DBPS		DBPS			2803
--sbc9261			MACH_SBC9261		SBC9261			2804
- pcbfp0001		MACH_PCBFP0001		PCBFP0001		2805
- speedy			MACH_SPEEDY		SPEEDY			2806
- chrysaor		MACH_CHRYSAOR		CHRYSAOR		2807
-@@ -2812,7 +2797,6 @@ p565			MACH_P565		P565			2824
- acer_a4			MACH_ACER_A4		ACER_A4			2825
- davinci_dm368_bip	MACH_DAVINCI_DM368_BIP	DAVINCI_DM368_BIP	2826
- eshare			MACH_ESHARE		ESHARE			2827
--hw_omapl138_europa	MACH_HW_OMAPL138_EUROPA	HW_OMAPL138_EUROPA	2828
- wlbargn			MACH_WLBARGN		WLBARGN			2829
- bm170			MACH_BM170		BM170			2830
- netspace_mini_v2	MACH_NETSPACE_MINI_V2	NETSPACE_MINI_V2	2831
-@@ -2879,7 +2863,6 @@ davinci_picto		MACH_DAVINCI_PICTO	DAVINC
- mecha			MACH_MECHA		MECHA			2892
- bubba3			MACH_BUBBA3		BUBBA3			2893
- pupitre			MACH_PUPITRE		PUPITRE			2894
--tegra_harmony		MACH_TEGRA_HARMONY	TEGRA_HARMONY		2895
- tegra_vogue		MACH_TEGRA_VOGUE	TEGRA_VOGUE		2896
- tegra_e1165		MACH_TEGRA_E1165	TEGRA_E1165		2897
- simplenet		MACH_SIMPLENET		SIMPLENET		2898
-@@ -2969,7 +2952,6 @@ netspace_lite_v2	MACH_NETSPACE_LITE_V2	N
- ssc			MACH_SSC		SSC			2984
- premierwave_en		MACH_PREMIERWAVE_EN	PREMIERWAVE_EN		2985
- wasabi			MACH_WASABI		WASABI			2986
--vivow			MACH_VIVOW		VIVOW			2987
- mx50_rdp		MACH_MX50_RDP		MX50_RDP		2988
- universal_c210		MACH_UNIVERSAL_C210	UNIVERSAL_C210		2989
- real6410		MACH_REAL6410		REAL6410		2990
-@@ -3017,12 +2999,10 @@ remus			MACH_REMUS		REMUS			3031
- at91cap7xdk		MACH_AT91CAP7XDK	AT91CAP7XDK		3032
- at91cap7stk		MACH_AT91CAP7STK	AT91CAP7STK		3033
- kt_sbc_sam9_1		MACH_KT_SBC_SAM9_1	KT_SBC_SAM9_1		3034
--oratisrouter		MACH_ORATISROUTER	ORATISROUTER		3035
- armada_xp_db		MACH_ARMADA_XP_DB	ARMADA_XP_DB		3036
- spdm			MACH_SPDM		SPDM			3037
- gtib			MACH_GTIB		GTIB			3038
- dgm3240			MACH_DGM3240		DGM3240			3039
--atlas_i_lpe		MACH_ATLAS_I_LPE	ATLAS_I_LPE		3040
- htcmega			MACH_HTCMEGA		HTCMEGA			3041
- tricorder		MACH_TRICORDER		TRICORDER		3042
- tx28			MACH_TX28		TX28			3043
-@@ -3062,7 +3042,6 @@ clod			MACH_CLOD		CLOD			3077
- rump			MACH_RUMP		RUMP			3078
- tenderloin		MACH_TENDERLOIN		TENDERLOIN		3079
- shortloin		MACH_SHORTLOIN		SHORTLOIN		3080
--crespo			MACH_CRESPO		CRESPO			3081
- antares			MACH_ANTARES		ANTARES			3082
- wb40n			MACH_WB40N		WB40N			3083
- herring			MACH_HERRING		HERRING			3084
-@@ -3109,9 +3088,7 @@ msm8x60_fluid		MACH_MSM8X60_FLUID	MSM8X6
- smartqv5		MACH_SMARTQV5		SMARTQV5		3125
- smartqv3		MACH_SMARTQV3		SMARTQV3		3126
- smartqv7		MACH_SMARTQV7		SMARTQV7		3127
--paz00			MACH_PAZ00		PAZ00			3128
- acmenetusfoxg20		MACH_ACMENETUSFOXG20	ACMENETUSFOXG20		3129
--htcwillow		MACH_HTCWILLOW		HTCWILLOW		3130
- fwbd_0404		MACH_FWBD_0404		FWBD_0404		3131
- hdgu			MACH_HDGU		HDGU			3132
- pyramid			MACH_PYRAMID		PYRAMID			3133
-@@ -3162,7 +3139,6 @@ b5500			MACH_B5500		B5500			3177
- s5500			MACH_S5500		S5500			3178
- icon			MACH_ICON		ICON			3179
- elephant		MACH_ELEPHANT		ELEPHANT		3180
--msm8x60_fusion		MACH_MSM8X60_FUSION	MSM8X60_FUSION		3181
- shooter			MACH_SHOOTER		SHOOTER			3182
- spade_lte		MACH_SPADE_LTE		SPADE_LTE		3183
- philhwani		MACH_PHILHWANI		PHILHWANI		3184
-@@ -3174,13 +3150,11 @@ ag5evm			MACH_AG5EVM		AG5EVM			3189
- sc575plc		MACH_SC575PLC		SC575PLC		3190
- sc575hmi		MACH_SC575IPC		SC575IPC		3191
- omap3_tdm3730		MACH_OMAP3_TDM3730	OMAP3_TDM3730		3192
--g7			MACH_G7			G7			3193
- top9000_eval		MACH_TOP9000_EVAL	TOP9000_EVAL		3194
- top9000_su		MACH_TOP9000_SU		TOP9000_SU		3195
- utm300			MACH_UTM300		UTM300			3196
- tsunagi			MACH_TSUNAGI		TSUNAGI			3197
- ts75xx			MACH_TS75XX		TS75XX			3198
--msm8x60_fusn_ffa	MACH_MSM8X60_FUSN_FFA	MSM8X60_FUSN_FFA	3199
- ts47xx			MACH_TS47XX		TS47XX			3200
- da850_k5		MACH_DA850_K5		DA850_K5		3201
- ax502			MACH_AX502		AX502			3202
-@@ -3316,3 +3290,51 @@ rover_g8		MACH_ROVER_G8		ROVER_G8		3335
- t5388p			MACH_T5388P		T5388P			3336
- dingo			MACH_DINGO		DINGO			3337
- goflexhome		MACH_GOFLEXHOME		GOFLEXHOME		3338
-+lanreadyfn511		MACH_LANREADYFN511	LANREADYFN511		3340
-+omap3_baia		MACH_OMAP3_BAIA		OMAP3_BAIA		3341
-+omap3smartdisplay	MACH_OMAP3SMARTDISPLAY	OMAP3SMARTDISPLAY	3342
-+xilinx			MACH_XILINX		XILINX			3343
-+a2f			MACH_A2F		A2F			3344
-+sky25			MACH_SKY25		SKY25			3345
-+ccmx53			MACH_CCMX53		CCMX53			3346
-+ccmx53js		MACH_CCMX53JS		CCMX53JS		3347
-+ccwmx53			MACH_CCWMX53		CCWMX53			3348
-+ccwmx53js		MACH_CCWMX53JS		CCWMX53JS		3349
-+frisms			MACH_FRISMS		FRISMS			3350
-+msm7x27a_ffa		MACH_MSM7X27A_FFA	MSM7X27A_FFA		3351
-+msm7x27a_surf		MACH_MSM7X27A_SURF	MSM7X27A_SURF		3352
-+msm7x27a_rumi3		MACH_MSM7X27A_RUMI3	MSM7X27A_RUMI3		3353
-+dimmsam9g20		MACH_DIMMSAM9G20	DIMMSAM9G20		3354
-+dimm_imx28		MACH_DIMM_IMX28		DIMM_IMX28		3355
-+amk_a4			MACH_AMK_A4		AMK_A4			3356
-+gnet_sgme		MACH_GNET_SGME		GNET_SGME		3357
-+shooter_u		MACH_SHOOTER_U		SHOOTER_U		3358
-+vmx53			MACH_VMX53		VMX53			3359
-+rhino			MACH_RHINO		RHINO			3360
-+armlex4210		MACH_ARMLEX4210		ARMLEX4210		3361
-+swarcoextmodem		MACH_SWARCOEXTMODEM	SWARCOEXTMODEM		3362
-+snowball		MACH_SNOWBALL		SNOWBALL		3363
-+pcm049			MACH_PCM049		PCM049			3364
-+vigor			MACH_VIGOR		VIGOR			3365
-+oslo_amundsen		MACH_OSLO_AMUNDSEN	OSLO_AMUNDSEN		3366
-+gsl_diamond		MACH_GSL_DIAMOND	GSL_DIAMOND		3367
-+cv2201			MACH_CV2201		CV2201			3368
-+cv2202			MACH_CV2202		CV2202			3369
-+cv2203			MACH_CV2203		CV2203			3370
-+vit_ibox		MACH_VIT_IBOX		VIT_IBOX		3371
-+dm6441_esp		MACH_DM6441_ESP		DM6441_ESP		3372
-+at91sam9x5ek		MACH_AT91SAM9X5EK	AT91SAM9X5EK		3373
-+libra			MACH_LIBRA		LIBRA			3374
-+easycrrh		MACH_EASYCRRH		EASYCRRH		3375
-+tripel			MACH_TRIPEL		TRIPEL			3376
-+endian_mini		MACH_ENDIAN_MINI	ENDIAN_MINI		3377
-+xilinx_ep107		MACH_XILINX_EP107	XILINX_EP107		3378
-+nuri			MACH_NURI		NURI			3379
-+janus			MACH_JANUS		JANUS			3380
-+ddnas			MACH_DDNAS		DDNAS			3381
-+tag			MACH_TAG		TAG			3382
-+tagw			MACH_TAGW		TAGW			3383
-+nitrogen_vm_imx51	MACH_NITROGEN_VM_IMX51	NITROGEN_VM_IMX51	3384
-+viprinet		MACH_VIPRINET		VIPRINET		3385
-+bockw			MACH_BOCKW		BOCKW			3386
-+eva2000			MACH_EVA2000		EVA2000			3387
diff --git a/target/linux/generic/patches-2.6.38/320-ppc4xx_optimization.patch b/target/linux/generic/patches-2.6.38/320-ppc4xx_optimization.patch
deleted file mode 100644
index 49d3659286..0000000000
--- a/target/linux/generic/patches-2.6.38/320-ppc4xx_optimization.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-Upstream doesn't optimize the kernel and bootwrappers for ppc44x because
-they still want to support gcc 3.3 -- well, we don't.
-
---- a/arch/powerpc/Makefile
-+++ b/arch/powerpc/Makefile
-@@ -130,7 +130,8 @@ ifeq ($(CONFIG_FUNCTION_TRACER),y)
- KBUILD_CFLAGS		+= -mno-sched-epilog
- endif
- 
--cpu-as-$(CONFIG_4xx)		+= -Wa,-m405
-+cpu-as-$(CONFIG_40x)		+= -Wa,-m405
-+cpu-as-$(CONFIG_44x)		+= -Wa,-m440
- cpu-as-$(CONFIG_6xx)		+= -Wa,-maltivec
- cpu-as-$(CONFIG_POWER4)		+= -Wa,-maltivec
- cpu-as-$(CONFIG_E500)		+= -Wa,-me500
---- a/arch/powerpc/boot/Makefile
-+++ b/arch/powerpc/boot/Makefile
-@@ -38,10 +38,10 @@ BOOTCFLAGS	+= -I$(obj) -I$(srctree)/$(ob
- DTC_FLAGS	?= -p 1024
- 
- $(obj)/4xx.o: BOOTCFLAGS += -mcpu=405
--$(obj)/ebony.o: BOOTCFLAGS += -mcpu=405
-+$(obj)/ebony.o: BOOTCFLAGS += -mcpu=440
- $(obj)/cuboot-hotfoot.o: BOOTCFLAGS += -mcpu=405
--$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=405
--$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=405
-+$(obj)/cuboot-taishan.o: BOOTCFLAGS += -mcpu=440
-+$(obj)/cuboot-katmai.o: BOOTCFLAGS += -mcpu=440
- $(obj)/cuboot-acadia.o: BOOTCFLAGS += -mcpu=405
- $(obj)/treeboot-walnut.o: BOOTCFLAGS += -mcpu=405
- $(obj)/treeboot-iss4xx.o: BOOTCFLAGS += -mcpu=405
diff --git a/target/linux/generic/patches-2.6.38/321-powerpc_crtsavres_prereq.patch b/target/linux/generic/patches-2.6.38/321-powerpc_crtsavres_prereq.patch
deleted file mode 100644
index 941aa909de..0000000000
--- a/target/linux/generic/patches-2.6.38/321-powerpc_crtsavres_prereq.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/arch/powerpc/Makefile
-+++ b/arch/powerpc/Makefile
-@@ -94,7 +94,6 @@ else
- endif
- endif
- 
--KBUILD_LDFLAGS_MODULE += arch/powerpc/lib/crtsavres.o
- 
- ifeq ($(CONFIG_TUNE_CELL),y)
- 	KBUILD_CFLAGS += $(call cc-option,-mtune=cell)
diff --git a/target/linux/generic/patches-2.6.38/322-powerpc_unused_var.patch b/target/linux/generic/patches-2.6.38/322-powerpc_unused_var.patch
deleted file mode 100644
index a9eed21776..0000000000
--- a/target/linux/generic/patches-2.6.38/322-powerpc_unused_var.patch
+++ /dev/null
@@ -1,61 +0,0 @@
---- a/arch/powerpc/kernel/align.c
-+++ b/arch/powerpc/kernel/align.c
-@@ -701,7 +701,7 @@ static int emulate_vsx(unsigned char __u
- 
- int fix_alignment(struct pt_regs *regs)
- {
--	unsigned int instr, nb, flags, instruction = 0;
-+	unsigned int instr, nb, flags, instruction __maybe_unused = 0;
- 	unsigned int reg, areg;
- 	unsigned int dsisr;
- 	unsigned char __user *addr;
---- a/arch/powerpc/kernel/signal_32.c
-+++ b/arch/powerpc/kernel/signal_32.c
-@@ -935,7 +935,7 @@ long sys_swapcontext(struct ucontext __u
- 		     struct ucontext __user *new_ctx,
- 		     int ctx_size, int r6, int r7, int r8, struct pt_regs *regs)
- {
--	unsigned char tmp;
-+	unsigned char tmp __maybe_unused;
- 	int ctx_has_vsx_region = 0;
- 
- #ifdef CONFIG_PPC64
-@@ -1076,7 +1076,7 @@ int sys_debug_setcontext(struct ucontext
- {
- 	struct sig_dbg_op op;
- 	int i;
--	unsigned char tmp;
-+	unsigned char tmp __maybe_unused;
- 	unsigned long new_msr = regs->msr;
- #ifdef CONFIG_PPC_ADV_DEBUG_REGS
- 	unsigned long new_dbcr0 = current->thread.dbcr0;
---- a/arch/powerpc/mm/mem.c
-+++ b/arch/powerpc/mm/mem.c
-@@ -171,7 +171,7 @@ void __init do_init_bootmem(void)
- 	unsigned long start, bootmap_pages;
- 	unsigned long total_pages;
- 	struct memblock_region *reg;
--	int boot_mapsize;
-+	int boot_mapsize __maybe_unused;
- 
- 	max_low_pfn = max_pfn = memblock_end_of_DRAM() >> PAGE_SHIFT;
- 	total_pages = (memblock_end_of_DRAM() - memstart_addr) >> PAGE_SHIFT;
---- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
-+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
-@@ -327,7 +327,7 @@ void __init qe_ic_init(struct device_nod
- {
- 	struct qe_ic *qe_ic;
- 	struct resource res;
--	u32 temp = 0, ret, high_active = 0;
-+	u32 temp = 0, ret;
- 
- 	ret = of_address_to_resource(node, 0, &res);
- 	if (ret)
-@@ -376,7 +376,6 @@ void __init qe_ic_init(struct device_nod
- 	/* choose destination signal for highest priority interrupt */
- 	if (flags & QE_IC_HIGH_SIGNAL) {
- 		temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
--		high_active = 1;
- 	}
- 
- 	qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
diff --git a/target/linux/generic/patches-2.6.38/400-rootfs_split.patch b/target/linux/generic/patches-2.6.38/400-rootfs_split.patch
deleted file mode 100644
index 9b7c2dc0b7..0000000000
--- a/target/linux/generic/patches-2.6.38/400-rootfs_split.patch
+++ /dev/null
@@ -1,332 +0,0 @@
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -55,6 +55,16 @@ config MTD_PARTITIONS
- 
- if MTD_PARTITIONS
- 
-+config MTD_ROOTFS_ROOT_DEV
-+	bool "Automatically set 'rootfs' partition to be root filesystem"
-+	depends on MTD_PARTITIONS
-+	default y
-+
-+config MTD_ROOTFS_SPLIT
-+	bool "Automatically split 'rootfs' partition for squashfs"
-+	depends on MTD_PARTITIONS
-+	default y
-+
- config MTD_REDBOOT_PARTS
- 	tristate "RedBoot partition table parsing"
- 	---help---
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -29,6 +29,8 @@
- #include <linux/kmod.h>
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
-+#include <linux/root_dev.h>
-+#include <linux/magic.h>
- #include <linux/err.h>
- 
- /* Our partition linked list */
-@@ -48,7 +50,7 @@ struct mtd_part {
-  * the pointer to that structure with this macro.
-  */
- #define PART(x)  ((struct mtd_part *)(x))
--
-+#define IS_PART(mtd) (mtd->read == part_read)
- 
- /*
-  * MTD methods which simply translate the effective address and pass through
-@@ -636,6 +638,155 @@ int mtd_del_partition(struct mtd_info *m
- }
- EXPORT_SYMBOL_GPL(mtd_del_partition);
- 
-+#ifdef CONFIG_MTD_ROOTFS_SPLIT
-+#define ROOTFS_SPLIT_NAME "rootfs_data"
-+#define ROOTFS_REMOVED_NAME "<removed>"
-+
-+struct squashfs_super_block {
-+	__le32 s_magic;
-+	__le32 pad0[9];
-+	__le64 bytes_used;
-+};
-+
-+
-+static int split_squashfs(struct mtd_info *master, int offset, int *split_offset)
-+{
-+	struct squashfs_super_block sb;
-+	int len, ret;
-+
-+	ret = master->read(master, offset, sizeof(sb), &len, (void *) &sb);
-+	if (ret || (len != sizeof(sb))) {
-+		printk(KERN_ALERT "split_squashfs: error occured while reading "
-+			"from \"%s\"\n", master->name);
-+		return -EINVAL;
-+	}
-+
-+	if (SQUASHFS_MAGIC != le32_to_cpu(sb.s_magic) ) {
-+		printk(KERN_ALERT "split_squashfs: no squashfs found in \"%s\"\n",
-+			master->name);
-+		*split_offset = 0;
-+		return 0;
-+	}
-+
-+	if (le64_to_cpu((sb.bytes_used)) <= 0) {
-+		printk(KERN_ALERT "split_squashfs: squashfs is empty in \"%s\"\n",
-+			master->name);
-+		*split_offset = 0;
-+		return 0;
-+	}
-+
-+	len = (u32) le64_to_cpu(sb.bytes_used);
-+	len += (offset & 0x000fffff);
-+	len +=  (master->erasesize - 1);
-+	len &= ~(master->erasesize - 1);
-+	len -= (offset & 0x000fffff);
-+	*split_offset = offset + len;
-+
-+	return 0;
-+}
-+
-+static int split_rootfs_data(struct mtd_info *master, struct mtd_info *rpart, const struct mtd_partition *part)
-+{
-+	struct mtd_partition *dpart;
-+	struct mtd_part *slave = NULL;
-+	struct mtd_part *spart;
-+	int ret, split_offset = 0;
-+
-+	spart = PART(rpart);
-+	ret = split_squashfs(master, spart->offset, &split_offset);
-+	if (ret)
-+		return ret;
-+
-+	if (split_offset <= 0)
-+		return 0;
-+
-+	dpart = kmalloc(sizeof(*part)+sizeof(ROOTFS_SPLIT_NAME)+1, GFP_KERNEL);
-+	if (dpart == NULL) {
-+		printk(KERN_INFO "split_squashfs: no memory for partition \"%s\"\n",
-+			ROOTFS_SPLIT_NAME);
-+		return -ENOMEM;
-+	}
-+
-+	memcpy(dpart, part, sizeof(*part));
-+	strcpy((char *)&dpart[1], ROOTFS_SPLIT_NAME);
-+	dpart->name = (unsigned char *)&dpart[1];
-+
-+	dpart->size = rpart->size - (split_offset - spart->offset);
-+	dpart->offset = split_offset;
-+
-+	if (dpart == NULL)
-+		return 1;
-+
-+	printk(KERN_INFO "mtd: partition \"%s\" created automatically, ofs=%llX, len=%llX \n",
-+		ROOTFS_SPLIT_NAME, dpart->offset, dpart->size);
-+
-+	slave = allocate_partition(master, dpart, 0, split_offset);
-+	if (IS_ERR(slave))
-+		return PTR_ERR(slave);
-+	mutex_lock(&mtd_partitions_mutex);
-+	list_add(&slave->list, &mtd_partitions);
-+	mutex_unlock(&mtd_partitions_mutex);
-+
-+	add_mtd_device(&slave->mtd);
-+
-+	rpart->split = &slave->mtd;
-+
-+	return 0;
-+}
-+
-+static int refresh_rootfs_split(struct mtd_info *mtd)
-+{
-+	struct mtd_partition tpart;
-+	struct mtd_part *part;
-+	char *name;
-+	//int index = 0;
-+	int offset, size;
-+	int ret;
-+
-+	part = PART(mtd);
-+
-+	/* check for the new squashfs offset first */
-+	ret = split_squashfs(part->master, part->offset, &offset);
-+	if (ret)
-+		return ret;
-+
-+	if ((offset > 0) && !mtd->split) {
-+		printk(KERN_INFO "%s: creating new split partition for \"%s\"\n", __func__, mtd->name);
-+		/* if we don't have a rootfs split partition, create a new one */
-+		tpart.name = (char *) mtd->name;
-+		tpart.size = mtd->size;
-+		tpart.offset = part->offset;
-+
-+		return split_rootfs_data(part->master, &part->mtd, &tpart);
-+	} else if ((offset > 0) && mtd->split) {
-+		/* update the offsets of the existing partition */
-+		size = mtd->size + part->offset - offset;
-+
-+		part = PART(mtd->split);
-+		part->offset = offset;
-+		part->mtd.size = size;
-+		printk(KERN_INFO "%s: %s partition \"" ROOTFS_SPLIT_NAME "\", offset: 0x%06x (0x%06x)\n",
-+			__func__, (!strcmp(part->mtd.name, ROOTFS_SPLIT_NAME) ? "updating" : "creating"),
-+			(u32) part->offset, (u32) part->mtd.size);
-+		name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL);
-+		strcpy(name, ROOTFS_SPLIT_NAME);
-+		part->mtd.name = name;
-+	} else if ((offset <= 0) && mtd->split) {
-+		printk(KERN_INFO "%s: removing partition \"%s\"\n", __func__, mtd->split->name);
-+
-+		/* mark existing partition as removed */
-+		part = PART(mtd->split);
-+		name = kmalloc(sizeof(ROOTFS_SPLIT_NAME) + 1, GFP_KERNEL);
-+		strcpy(name, ROOTFS_REMOVED_NAME);
-+		part->mtd.name = name;
-+		part->offset = 0;
-+		part->mtd.size = 0;
-+	}
-+
-+	return 0;
-+}
-+#endif /* CONFIG_MTD_ROOTFS_SPLIT */
-+
- /*
-  * This function, given a master MTD object and a partition table, creates
-  * and registers slave MTD objects which are bound to the master according to
-@@ -652,6 +803,9 @@ int add_mtd_partitions(struct mtd_info *
- 	struct mtd_part *slave;
- 	uint64_t cur_offset = 0;
- 	int i;
-+#ifdef CONFIG_MTD_ROOTFS_SPLIT
-+	int ret;
-+#endif
- 
- 	printk(KERN_NOTICE "Creating %d MTD partitions on \"%s\":\n", nbparts, master->name);
- 
-@@ -666,6 +820,21 @@ int add_mtd_partitions(struct mtd_info *
- 
- 		add_mtd_device(&slave->mtd);
- 
-+		if (!strcmp(parts[i].name, "rootfs")) {
-+#ifdef CONFIG_MTD_ROOTFS_ROOT_DEV
-+			if (ROOT_DEV == 0) {
-+				printk(KERN_NOTICE "mtd: partition \"rootfs\" "
-+					"set to be root filesystem\n");
-+				ROOT_DEV = MKDEV(MTD_BLOCK_MAJOR, slave->mtd.index);
-+			}
-+#endif
-+#ifdef CONFIG_MTD_ROOTFS_SPLIT
-+			ret = split_rootfs_data(master, &slave->mtd, &parts[i]);
-+			/* if (ret == 0)
-+			 * 	j++; */
-+#endif
-+		}
-+
- 		cur_offset = slave->offset + slave->mtd.size;
- 	}
- 
-@@ -673,6 +842,32 @@ int add_mtd_partitions(struct mtd_info *
- }
- EXPORT_SYMBOL(add_mtd_partitions);
- 
-+int refresh_mtd_partitions(struct mtd_info *mtd)
-+{
-+	int ret = 0;
-+
-+	if (IS_PART(mtd)) {
-+		struct mtd_part *part;
-+		struct mtd_info *master;
-+
-+		part = PART(mtd);
-+		master = part->master;
-+		if (master->refresh_device)
-+			ret = master->refresh_device(master);
-+	}
-+
-+	if (!ret && mtd->refresh_device)
-+		ret = mtd->refresh_device(mtd);
-+
-+#ifdef CONFIG_MTD_ROOTFS_SPLIT
-+	if (!ret && IS_PART(mtd) && !strcmp(mtd->name, "rootfs"))
-+		refresh_rootfs_split(mtd);
-+#endif
-+
-+	return 0;
-+}
-+EXPORT_SYMBOL_GPL(refresh_mtd_partitions);
-+
- static DEFINE_SPINLOCK(part_parser_lock);
- static LIST_HEAD(part_parsers);
- 
---- a/drivers/mtd/mtdchar.c
-+++ b/drivers/mtd/mtdchar.c
-@@ -956,6 +956,13 @@ static int mtd_ioctl(struct file *file,
- 		break;
- 	}
- #endif
-+#ifdef CONFIG_MTD_PARTITIONS
-+	case MTDREFRESH:
-+	{
-+		ret = refresh_mtd_partitions(mtd);
-+		break;
-+	}
-+#endif
- 
- 	default:
- 		ret = -ENOTTY;
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -125,6 +125,7 @@ struct nand_ecclayout {
- 	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES_LARGE];
- };
- 
-+struct mtd_info;
- struct mtd_info {
- 	u_char type;
- 	uint32_t flags;
-@@ -277,6 +278,9 @@ struct mtd_info {
- 	struct device dev;
- 	int usecount;
- 
-+	int (*refresh_device)(struct mtd_info *mtd);
-+	struct mtd_info *split;
-+
- 	/* If the driver is something smart, like UBI, it may need to maintain
- 	 * its own reference counting. The below functions are only for driver.
- 	 * The driver may register its callbacks. These callbacks are not
---- a/include/linux/mtd/partitions.h
-+++ b/include/linux/mtd/partitions.h
-@@ -34,12 +34,14 @@
-  * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
-  */
- 
-+struct mtd_partition;
- struct mtd_partition {
--	char *name;			/* identifier string */
-+	const char *name;		/* identifier string */
- 	uint64_t size;			/* partition size */
- 	uint64_t offset;		/* offset within the master MTD space */
- 	uint32_t mask_flags;		/* master MTD flags to mask out for this partition */
- 	struct nand_ecclayout *ecclayout;	/* out of band layout for this partition (NAND only) */
-+	int (*refresh_partition)(struct mtd_info *);
- };
- 
- #define MTDPART_OFS_NXTBLK	(-2)
-@@ -51,6 +53,7 @@ struct mtd_info;
- 
- int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
- int del_mtd_partitions(struct mtd_info *);
-+int refresh_mtd_partitions(struct mtd_info *);
- 
- /*
-  * Functions dealing with the various ways of partitioning the space
---- a/include/mtd/mtd-abi.h
-+++ b/include/mtd/mtd-abi.h
-@@ -127,6 +127,7 @@ struct otp_info {
- #define MEMWRITEOOB64		_IOWR('M', 21, struct mtd_oob_buf64)
- #define MEMREADOOB64		_IOWR('M', 22, struct mtd_oob_buf64)
- #define MEMISLOCKED		_IOR('M', 23, struct erase_info_user)
-+#define MTDREFRESH		_IO('M', 50)
- 
- /*
-  * Obsolete legacy interface. Keep it in order not to break userspace
diff --git a/target/linux/generic/patches-2.6.38/401-partial_eraseblock_write.patch b/target/linux/generic/patches-2.6.38/401-partial_eraseblock_write.patch
deleted file mode 100644
index 873c0d1cb1..0000000000
--- a/target/linux/generic/patches-2.6.38/401-partial_eraseblock_write.patch
+++ /dev/null
@@ -1,145 +0,0 @@
---- a/drivers/mtd/mtdpart.c
-+++ b/drivers/mtd/mtdpart.c
-@@ -33,6 +33,8 @@
- #include <linux/magic.h>
- #include <linux/err.h>
- 
-+#define MTD_ERASE_PARTIAL	0x8000 /* partition only covers parts of an erase block */
-+
- /* Our partition linked list */
- static LIST_HEAD(mtd_partitions);
- static DEFINE_MUTEX(mtd_partitions_mutex);
-@@ -256,13 +258,60 @@ static int part_erase(struct mtd_info *m
- 		return -EROFS;
- 	if (instr->addr >= mtd->size)
- 		return -EINVAL;
-+
-+	instr->partial_start = false;
-+	if (mtd->flags & MTD_ERASE_PARTIAL) {
-+		size_t readlen = 0;
-+		u64 mtd_ofs;
-+
-+		instr->erase_buf = kmalloc(part->master->erasesize, GFP_ATOMIC);
-+		if (!instr->erase_buf)
-+			return -ENOMEM;
-+
-+		mtd_ofs = part->offset + instr->addr;
-+		instr->erase_buf_ofs = do_div(mtd_ofs, part->master->erasesize);
-+
-+		if (instr->erase_buf_ofs > 0) {
-+			instr->addr -= instr->erase_buf_ofs;
-+			ret = part->master->read(part->master,
-+				instr->addr + part->offset,
-+				part->master->erasesize,
-+				&readlen, instr->erase_buf);
-+
-+			instr->partial_start = true;
-+		} else {
-+			mtd_ofs = part->offset + part->mtd.size;
-+			instr->erase_buf_ofs = part->master->erasesize -
-+				do_div(mtd_ofs, part->master->erasesize);
-+
-+			if (instr->erase_buf_ofs > 0) {
-+				instr->len += instr->erase_buf_ofs;
-+				ret = part->master->read(part->master,
-+					part->offset + instr->addr +
-+					instr->len - part->master->erasesize,
-+					part->master->erasesize, &readlen,
-+					instr->erase_buf);
-+			} else {
-+				ret = 0;
-+			}
-+		}
-+		if (ret < 0) {
-+			kfree(instr->erase_buf);
-+			return ret;
-+		}
-+
-+	}
-+
- 	instr->addr += part->offset;
- 	ret = part->master->erase(part->master, instr);
- 	if (ret) {
- 		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
- 			instr->fail_addr -= part->offset;
- 		instr->addr -= part->offset;
-+		if (mtd->flags & MTD_ERASE_PARTIAL)
-+			kfree(instr->erase_buf);
- 	}
-+
- 	return ret;
- }
- 
-@@ -270,7 +319,25 @@ void mtd_erase_callback(struct erase_inf
- {
- 	if (instr->mtd->erase == part_erase) {
- 		struct mtd_part *part = PART(instr->mtd);
-+		size_t wrlen = 0;
- 
-+		if (instr->mtd->flags & MTD_ERASE_PARTIAL) {
-+			if (instr->partial_start) {
-+				part->master->write(part->master,
-+					instr->addr, instr->erase_buf_ofs,
-+					&wrlen, instr->erase_buf);
-+				instr->addr += instr->erase_buf_ofs;
-+			} else {
-+				instr->len -= instr->erase_buf_ofs;
-+				part->master->write(part->master,
-+					instr->addr + instr->len,
-+					instr->erase_buf_ofs, &wrlen,
-+					instr->erase_buf +
-+					part->master->erasesize -
-+					instr->erase_buf_ofs);
-+			}
-+			kfree(instr->erase_buf);
-+		}
- 		if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN)
- 			instr->fail_addr -= part->offset;
- 		instr->addr -= part->offset;
-@@ -529,18 +596,24 @@ static struct mtd_part *allocate_partiti
- 	if ((slave->mtd.flags & MTD_WRITEABLE) &&
- 	    mtd_mod_by_eb(slave->offset, &slave->mtd)) {
- 		/* Doesn't start on a boundary of major erase size */
--		/* FIXME: Let it be writable if it is on a boundary of
--		 * _minor_ erase size though */
--		slave->mtd.flags &= ~MTD_WRITEABLE;
--		printk(KERN_WARNING"mtd: partition \"%s\" doesn't start on an erase block boundary -- force read-only\n",
--			part->name);
-+		slave->mtd.flags |= MTD_ERASE_PARTIAL;
-+		if (((u32) slave->mtd.size) > master->erasesize)
-+			slave->mtd.flags &= ~MTD_WRITEABLE;
-+		else
-+			slave->mtd.erasesize = slave->mtd.size;
- 	}
- 	if ((slave->mtd.flags & MTD_WRITEABLE) &&
--	    mtd_mod_by_eb(slave->mtd.size, &slave->mtd)) {
--		slave->mtd.flags &= ~MTD_WRITEABLE;
--		printk(KERN_WARNING"mtd: partition \"%s\" doesn't end on an erase block -- force read-only\n",
--			part->name);
-+	    mtd_mod_by_eb(slave->offset + slave->mtd.size, &slave->mtd)) {
-+		slave->mtd.flags |= MTD_ERASE_PARTIAL;
-+
-+		if ((u32) slave->mtd.size > master->erasesize)
-+			slave->mtd.flags &= ~MTD_WRITEABLE;
-+		else
-+			slave->mtd.erasesize = slave->mtd.size;
- 	}
-+	if ((slave->mtd.flags & (MTD_ERASE_PARTIAL|MTD_WRITEABLE)) == MTD_ERASE_PARTIAL)
-+		printk(KERN_WARNING"mtd: partition \"%s\" must either start or end on erase block boundary or be smaller than an erase block -- forcing read-only\n",
-+				part->name);
- 
- 	slave->mtd.ecclayout = master->ecclayout;
- 	if (master->block_isbad) {
---- a/include/linux/mtd/mtd.h
-+++ b/include/linux/mtd/mtd.h
-@@ -57,6 +57,10 @@ struct erase_info {
- 	u_long priv;
- 	u_char state;
- 	struct erase_info *next;
-+
-+	u8 *erase_buf;
-+	u32 erase_buf_ofs;
-+	bool partial_start;
- };
- 
- struct mtd_erase_region_info {
diff --git a/target/linux/generic/patches-2.6.38/410-mtd_info_move_forward_decl.patch b/target/linux/generic/patches-2.6.38/410-mtd_info_move_forward_decl.patch
deleted file mode 100644
index 13f0a217d4..0000000000
--- a/target/linux/generic/patches-2.6.38/410-mtd_info_move_forward_decl.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/include/linux/mtd/partitions.h
-+++ b/include/linux/mtd/partitions.h
-@@ -33,6 +33,7 @@
-  * Note: writeable partitions require their size and offset be
-  * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
-  */
-+struct mtd_info;
- 
- struct mtd_partition;
- struct mtd_partition {
-@@ -49,7 +50,6 @@ struct mtd_partition {
- #define MTDPART_SIZ_FULL	(0)
- 
- 
--struct mtd_info;
- 
- int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int);
- int del_mtd_partitions(struct mtd_info *);
diff --git a/target/linux/generic/patches-2.6.38/420-redboot_space.patch b/target/linux/generic/patches-2.6.38/420-redboot_space.patch
deleted file mode 100644
index fb6700b07e..0000000000
--- a/target/linux/generic/patches-2.6.38/420-redboot_space.patch
+++ /dev/null
@@ -1,30 +0,0 @@
---- a/drivers/mtd/redboot.c
-+++ b/drivers/mtd/redboot.c
-@@ -267,14 +267,21 @@ static int parse_redboot_partitions(stru
- #endif
- 		names += strlen(names)+1;
- 
--#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
- 		if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) {
--			i++;
--			parts[i].offset = parts[i-1].size + parts[i-1].offset;
--			parts[i].size = fl->next->img->flash_base - parts[i].offset;
--			parts[i].name = nullname;
--		}
-+			if (!strcmp(parts[i].name, "rootfs")) {
-+				parts[i].size = fl->next->img->flash_base;
-+				parts[i].size &= ~(master->erasesize - 1);
-+				parts[i].size -= parts[i].offset;
-+#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
-+				nrparts--;
-+			} else {
-+				i++;
-+				parts[i].offset = parts[i-1].size + parts[i-1].offset;
-+				parts[i].size = fl->next->img->flash_base - parts[i].offset;
-+				parts[i].name = nullname;
- #endif
-+			}
-+		}
- 		tmp_fl = fl;
- 		fl = fl->next;
- 		kfree(tmp_fl);
diff --git a/target/linux/generic/patches-2.6.38/421-redboot_boardconfig.patch b/target/linux/generic/patches-2.6.38/421-redboot_boardconfig.patch
deleted file mode 100644
index 9188cee29c..0000000000
--- a/target/linux/generic/patches-2.6.38/421-redboot_boardconfig.patch
+++ /dev/null
@@ -1,60 +0,0 @@
---- a/drivers/mtd/redboot.c
-+++ b/drivers/mtd/redboot.c
-@@ -29,6 +29,8 @@
- #include <linux/mtd/mtd.h>
- #include <linux/mtd/partitions.h>
- 
-+#define BOARD_CONFIG_PART		"boardconfig"
-+
- struct fis_image_desc {
-     unsigned char name[16];      // Null terminated name
-     uint32_t	  flash_base;    // Address within FLASH of image
-@@ -59,6 +61,7 @@ static int parse_redboot_partitions(stru
-                              struct mtd_partition **pparts,
-                              unsigned long fis_origin)
- {
-+	unsigned long max_offset = 0;
- 	int nrparts = 0;
- 	struct fis_image_desc *buf;
- 	struct mtd_partition *parts;
-@@ -227,14 +230,14 @@ static int parse_redboot_partitions(stru
- 		}
- 	}
- #endif
--	parts = kzalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL);
-+	parts = kzalloc(sizeof(*parts) * (nrparts + 1) + nulllen + namelen + sizeof(BOARD_CONFIG_PART), GFP_KERNEL);
- 
- 	if (!parts) {
- 		ret = -ENOMEM;
- 		goto out;
- 	}
- 
--	nullname = (char *)&parts[nrparts];
-+	nullname = (char *)&parts[nrparts + 1];
- #ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
- 	if (nulllen > 0) {
- 		strcpy(nullname, nullstring);
-@@ -253,6 +256,8 @@ static int parse_redboot_partitions(stru
- 	}
- #endif
- 	for ( ; i<nrparts; i++) {
-+		if(max_offset < buf[i].flash_base + buf[i].size)
-+			max_offset = buf[i].flash_base + buf[i].size;
- 		parts[i].size = fl->img->size;
- 		parts[i].offset = fl->img->flash_base;
- 		parts[i].name = names;
-@@ -286,6 +291,14 @@ static int parse_redboot_partitions(stru
- 		fl = fl->next;
- 		kfree(tmp_fl);
- 	}
-+	if(master->size - max_offset >= master->erasesize)
-+	{
-+		parts[nrparts].size = master->size - max_offset;
-+		parts[nrparts].offset = max_offset;
-+		parts[nrparts].name = names;
-+		strcpy(names, BOARD_CONFIG_PART);
-+		nrparts++;
-+	}
- 	ret = nrparts;
- 	*pparts = parts;
-  out:
diff --git a/target/linux/generic/patches-2.6.38/430-mtd_myloader_partition_parser.patch b/target/linux/generic/patches-2.6.38/430-mtd_myloader_partition_parser.patch
deleted file mode 100644
index 6e3e3b7085..0000000000
--- a/target/linux/generic/patches-2.6.38/430-mtd_myloader_partition_parser.patch
+++ /dev/null
@@ -1,35 +0,0 @@
---- a/drivers/mtd/Kconfig
-+++ b/drivers/mtd/Kconfig
-@@ -184,6 +184,22 @@ config MTD_AR7_PARTS
- 
- endif # MTD_PARTITIONS
- 
-+config MTD_MYLOADER_PARTS
-+	tristate "MyLoader partition parsing"
-+	depends on MTD_PARTITIONS && (ADM5120 || ATHEROS_AR231X || ATHEROS_AR71XX)
-+	---help---
-+	  MyLoader is a bootloader which allows the user to define partitions
-+	  in flash devices, by putting a table in the second erase block
-+	  on the device, similar to a partition table. This table gives the 
-+	  offsets and lengths of the user defined partitions.
-+
-+	  If you need code which can detect and parse these tables, and
-+	  register MTD 'partitions' corresponding to each image detected,
-+	  enable this option.
-+
-+	  You will still need the parsing functions to be called by the driver
-+	  for your particular device. It won't happen automatically.
-+
- comment "User Modules And Translation Layers"
- 
- config MTD_CHAR
---- a/drivers/mtd/Makefile
-+++ b/drivers/mtd/Makefile
-@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_REDBOOT_PARTS) += redbo
- obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o
- obj-$(CONFIG_MTD_AFS_PARTS)	+= afs.o
- obj-$(CONFIG_MTD_AR7_PARTS)	+= ar7part.o
-+obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
- 
- # 'Users' - code which presents functionality to userspace.
- obj-$(CONFIG_MTD_CHAR)		+= mtdchar.o
diff --git a/target/linux/generic/patches-2.6.38/440-block2mtd_init.patch b/target/linux/generic/patches-2.6.38/440-block2mtd_init.patch
deleted file mode 100644
index f8495b4e80..0000000000
--- a/target/linux/generic/patches-2.6.38/440-block2mtd_init.patch
+++ /dev/null
@@ -1,116 +0,0 @@
---- a/drivers/mtd/devices/block2mtd.c
-+++ b/drivers/mtd/devices/block2mtd.c
-@@ -14,6 +14,7 @@
- #include <linux/list.h>
- #include <linux/init.h>
- #include <linux/mtd/mtd.h>
-+#include <linux/mtd/partitions.h>
- #include <linux/buffer_head.h>
- #include <linux/mutex.h>
- #include <linux/mount.h>
-@@ -232,11 +233,12 @@ static void block2mtd_free_device(struct
- 
- 
- /* FIXME: ensure that mtd->size % erase_size == 0 */
--static struct block2mtd_dev *add_device(char *devname, int erase_size)
-+static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
- {
- 	const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
- 	struct block_device *bdev;
- 	struct block2mtd_dev *dev;
-+	struct mtd_partition *part;
- 	char *name;
- 
- 	if (!devname)
-@@ -275,13 +277,16 @@ static struct block2mtd_dev *add_device(
- 
- 	/* Setup the MTD structure */
- 	/* make the name contain the block device in */
--	name = kasprintf(GFP_KERNEL, "block2mtd: %s", devname);
-+	if (!mtdname)
-+		mtdname = devname;
-+	name = kmalloc(strlen(mtdname) + 1, GFP_KERNEL);
- 	if (!name)
- 		goto devinit_err;
- 
-+	strcpy(name, mtdname);
- 	dev->mtd.name = name;
- 
--	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
-+	dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK & ~(erase_size - 1);
- 	dev->mtd.erasesize = erase_size;
- 	dev->mtd.writesize = 1;
- 	dev->mtd.type = MTD_RAM;
-@@ -294,14 +299,17 @@ static struct block2mtd_dev *add_device(
- 	dev->mtd.priv = dev;
- 	dev->mtd.owner = THIS_MODULE;
- 
--	if (add_mtd_device(&dev->mtd)) {
-+	part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
-+	part->name = name;
-+	part->offset = 0;
-+	part->size = dev->mtd.size;
-+	if (add_mtd_partitions(&dev->mtd, part, 1)) {
- 		/* Device didnt get added, so free the entry */
- 		goto devinit_err;
- 	}
- 	list_add(&dev->list, &blkmtd_device_list);
- 	INFO("mtd%d: [%s] erase_size = %dKiB [%d]", dev->mtd.index,
--			dev->mtd.name + strlen("block2mtd: "),
--			dev->mtd.erasesize >> 10, dev->mtd.erasesize);
-+			mtdname, dev->mtd.erasesize >> 10, dev->mtd.erasesize);
- 	return dev;
- 
- devinit_err:
-@@ -374,9 +382,9 @@ static char block2mtd_paramline[80 + 12]
- 
- static int block2mtd_setup2(const char *val)
- {
--	char buf[80 + 12]; /* 80 for device, 12 for erase size */
-+	char buf[80 + 12 + 80]; /* 80 for device, 12 for erase size, 80 for name */
- 	char *str = buf;
--	char *token[2];
-+	char *token[3];
- 	char *name;
- 	size_t erase_size = PAGE_SIZE;
- 	int i, ret;
-@@ -387,7 +395,7 @@ static int block2mtd_setup2(const char *
- 	strcpy(str, val);
- 	kill_final_newline(str);
- 
--	for (i = 0; i < 2; i++)
-+	for (i = 0; i < 3; i++)
- 		token[i] = strsep(&str, ",");
- 
- 	if (str)
-@@ -406,8 +414,10 @@ static int block2mtd_setup2(const char *
- 			parse_err("illegal erase size");
- 		}
- 	}
-+	if (token[2] && (strlen(token[2]) + 1 > 80))
-+		parse_err("mtd device name too long");
- 
--	add_device(name, erase_size);
-+	add_device(name, erase_size, token[2]);
- 
- 	return 0;
- }
-@@ -441,7 +451,7 @@ static int block2mtd_setup(const char *v
- 
- 
- module_param_call(block2mtd, block2mtd_setup, NULL, NULL, 0200);
--MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>]\"");
-+MODULE_PARM_DESC(block2mtd, "Device to use. \"block2mtd=<dev>[,<erasesize>[,<name>]]\"");
- 
- static int __init block2mtd_init(void)
- {
---- a/fs/partitions/check.c
-+++ b/fs/partitions/check.c
-@@ -663,6 +663,7 @@ rescan:
- 	kfree(state);
- 	return 0;
- }
-+EXPORT_SYMBOL(rescan_partitions);
- 
- unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
- {
diff --git a/target/linux/generic/patches-2.6.38/441-block2mtd_refresh.patch b/target/linux/generic/patches-2.6.38/441-block2mtd_refresh.patch
deleted file mode 100644
index 24ee22f5f6..0000000000
--- a/target/linux/generic/patches-2.6.38/441-block2mtd_refresh.patch
+++ /dev/null
@@ -1,291 +0,0 @@
---- a/drivers/mtd/devices/block2mtd.c
-+++ b/drivers/mtd/devices/block2mtd.c
-@@ -30,6 +30,8 @@ struct block2mtd_dev {
- 	struct block_device *blkdev;
- 	struct mtd_info mtd;
- 	struct mutex write_mutex;
-+	rwlock_t bdev_mutex;
-+	char devname[0];
- };
- 
- 
-@@ -82,6 +84,12 @@ static int block2mtd_erase(struct mtd_in
- 	size_t len = instr->len;
- 	int err;
- 
-+	read_lock(&dev->bdev_mutex);
-+	if (!dev->blkdev) {
-+		err = -EINVAL;
-+		goto done;
-+	}
-+
- 	instr->state = MTD_ERASING;
- 	mutex_lock(&dev->write_mutex);
- 	err = _block2mtd_erase(dev, from, len);
-@@ -93,6 +101,10 @@ static int block2mtd_erase(struct mtd_in
- 		instr->state = MTD_ERASE_DONE;
- 
- 	mtd_erase_callback(instr);
-+
-+done:
-+	read_unlock(&dev->bdev_mutex);
-+
- 	return err;
- }
- 
-@@ -104,10 +116,14 @@ static int block2mtd_read(struct mtd_inf
- 	struct page *page;
- 	int index = from >> PAGE_SHIFT;
- 	int offset = from & (PAGE_SIZE-1);
--	int cpylen;
-+	int cpylen, err = 0;
-+
-+	read_lock(&dev->bdev_mutex);
-+	if (!dev->blkdev || (from > mtd->size)) {
-+		err = -EINVAL;
-+		goto done;
-+	}
- 
--	if (from > mtd->size)
--		return -EINVAL;
- 	if (from + len > mtd->size)
- 		len = mtd->size - from;
- 
-@@ -122,10 +138,14 @@ static int block2mtd_read(struct mtd_inf
- 		len = len - cpylen;
- 
- 		page = page_read(dev->blkdev->bd_inode->i_mapping, index);
--		if (!page)
--			return -ENOMEM;
--		if (IS_ERR(page))
--			return PTR_ERR(page);
-+		if (!page) {
-+			err = -ENOMEM;
-+			goto done;
-+		}
-+		if (IS_ERR(page)) {
-+			err = PTR_ERR(page);
-+			goto done;
-+		}
- 
- 		memcpy(buf, page_address(page) + offset, cpylen);
- 		page_cache_release(page);
-@@ -136,7 +156,10 @@ static int block2mtd_read(struct mtd_inf
- 		offset = 0;
- 		index++;
- 	}
--	return 0;
-+
-+done:
-+	read_unlock(&dev->bdev_mutex);
-+	return err;
- }
- 
- 
-@@ -188,12 +211,22 @@ static int block2mtd_write(struct mtd_in
- 		size_t *retlen, const u_char *buf)
- {
- 	struct block2mtd_dev *dev = mtd->priv;
--	int err;
-+	int err = 0;
-+
-+	read_lock(&dev->bdev_mutex);
-+	if (!dev->blkdev) {
-+		err = -EINVAL;
-+		goto done;
-+	}
- 
- 	if (!len)
--		return 0;
--	if (to >= mtd->size)
--		return -ENOSPC;
-+		goto done;
-+
-+	if (to >= mtd->size) {
-+		err = -ENOSPC;
-+		goto done;
-+	}
-+
- 	if (to + len > mtd->size)
- 		len = mtd->size - to;
- 
-@@ -202,6 +235,9 @@ static int block2mtd_write(struct mtd_in
- 	mutex_unlock(&dev->write_mutex);
- 	if (err > 0)
- 		err = 0;
-+
-+done:
-+	read_unlock(&dev->bdev_mutex);
- 	return err;
- }
- 
-@@ -210,33 +246,110 @@ static int block2mtd_write(struct mtd_in
- static void block2mtd_sync(struct mtd_info *mtd)
- {
- 	struct block2mtd_dev *dev = mtd->priv;
-+	read_lock(&dev->bdev_mutex);
-+	if (dev->blkdev)
- 	sync_blockdev(dev->blkdev);
-+	read_unlock(&dev->bdev_mutex);
-+
- 	return;
- }
- 
- 
-+static int _open_bdev(struct block2mtd_dev *dev)
-+{
-+	const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
-+	struct block_device *bdev;
-+
-+	/* Get a handle on the device */
-+	bdev = blkdev_get_by_path(dev->devname, mode, dev);
-+#ifndef MODULE
-+	if (IS_ERR(bdev)) {
-+		dev_t devt;
-+
-+		/* We might not have rootfs mounted at this point. Try
-+		   to resolve the device name by other means. */
-+
-+		devt = name_to_dev_t(dev->devname);
-+		if (devt)
-+			bdev = blkdev_get_by_dev(devt, mode, dev);
-+	}
-+#endif
-+
-+	if (IS_ERR(bdev)) {
-+		ERROR("error: cannot open device %s", dev->devname);
-+		return 1;
-+	}
-+	dev->blkdev = bdev;
-+
-+	if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
-+		ERROR("attempting to use an MTD device as a block device");
-+		return 1;
-+	}
-+
-+	return 0;
-+}
-+
-+static void _close_bdev(struct block2mtd_dev *dev)
-+{
-+	struct block_device *bdev;
-+
-+	if (!dev->blkdev)
-+		return;
-+
-+	bdev = dev->blkdev;
-+	invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1);
-+	blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
-+	dev->blkdev = NULL;
-+}
-+
- static void block2mtd_free_device(struct block2mtd_dev *dev)
- {
- 	if (!dev)
- 		return;
- 
- 	kfree(dev->mtd.name);
--
--	if (dev->blkdev) {
--		invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping,
--					0, -1);
--		blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
--	}
--
-+	_close_bdev(dev);
- 	kfree(dev);
- }
- 
- 
--/* FIXME: ensure that mtd->size % erase_size == 0 */
--static struct block2mtd_dev *add_device(char *devname, int erase_size, const char *mtdname)
-+static int block2mtd_refresh(struct mtd_info *mtd)
- {
--	const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL;
-+	struct block2mtd_dev *dev = mtd->priv;
- 	struct block_device *bdev;
-+	dev_t devt;
-+	int err = 0;
-+
-+	/* no other mtd function can run at this point */
-+	write_lock(&dev->bdev_mutex);
-+
-+	/* get the device number for the whole disk */
-+	devt = MKDEV(MAJOR(dev->blkdev->bd_dev), 0);
-+
-+	/* close the old block device */
-+	_close_bdev(dev);
-+
-+	/* open the whole disk, issue a partition rescan, then */
-+	bdev = blkdev_get_by_dev(devt, FMODE_WRITE | FMODE_READ, mtd);
-+	if (!bdev || !bdev->bd_disk)
-+		err = -EINVAL;
-+#ifndef CONFIG_MTD_BLOCK2MTD_MODULE
-+	else
-+		err = rescan_partitions(bdev->bd_disk, bdev);
-+#endif
-+	if (bdev)
-+		blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
-+
-+	/* try to open the partition block device again */
-+	_open_bdev(dev);
-+	write_unlock(&dev->bdev_mutex);
-+
-+	return err;
-+}
-+
-+/* FIXME: ensure that mtd->size % erase_size == 0 */
-+static struct block2mtd_dev *add_device(char *devname, int erase_size, char *mtdname)
-+{
- 	struct block2mtd_dev *dev;
- 	struct mtd_partition *part;
- 	char *name;
-@@ -244,36 +357,17 @@ static struct block2mtd_dev *add_device(
- 	if (!devname)
- 		return NULL;
- 
--	dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);
-+	dev = kzalloc(sizeof(struct block2mtd_dev) + strlen(devname) + 1, GFP_KERNEL);
- 	if (!dev)
- 		return NULL;
- 
--	/* Get a handle on the device */
--	bdev = blkdev_get_by_path(devname, mode, dev);
--#ifndef MODULE
--	if (IS_ERR(bdev)) {
--
--		/* We might not have rootfs mounted at this point. Try
--		   to resolve the device name by other means. */
-+	strcpy(dev->devname, devname);
- 
--		dev_t devt = name_to_dev_t(devname);
--		if (devt)
--			bdev = blkdev_get_by_dev(devt, mode, dev);
--	}
--#endif
--
--	if (IS_ERR(bdev)) {
--		ERROR("error: cannot open device %s", devname);
-+	if (_open_bdev(dev))
- 		goto devinit_err;
--	}
--	dev->blkdev = bdev;
--
--	if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) {
--		ERROR("attempting to use an MTD device as a block device");
--		goto devinit_err;
--	}
- 
- 	mutex_init(&dev->write_mutex);
-+	rwlock_init(&dev->bdev_mutex);
- 
- 	/* Setup the MTD structure */
- 	/* make the name contain the block device in */
-@@ -298,6 +392,7 @@ static struct block2mtd_dev *add_device(
- 	dev->mtd.read = block2mtd_read;
- 	dev->mtd.priv = dev;
- 	dev->mtd.owner = THIS_MODULE;
-+	dev->mtd.refresh_device = block2mtd_refresh;
- 
- 	part = kzalloc(sizeof(struct mtd_partition), GFP_KERNEL);
- 	part->name = name;
diff --git a/target/linux/generic/patches-2.6.38/442-block2mtd_probe.patch b/target/linux/generic/patches-2.6.38/442-block2mtd_probe.patch
deleted file mode 100644
index 780dd28fd2..0000000000
--- a/target/linux/generic/patches-2.6.38/442-block2mtd_probe.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/mtd/devices/block2mtd.c
-+++ b/drivers/mtd/devices/block2mtd.c
-@@ -269,6 +269,7 @@ static int _open_bdev(struct block2mtd_d
- 		/* We might not have rootfs mounted at this point. Try
- 		   to resolve the device name by other means. */
- 
-+		wait_for_device_probe();
- 		devt = name_to_dev_t(dev->devname);
- 		if (devt)
- 			bdev = blkdev_get_by_dev(devt, mode, dev);
diff --git a/target/linux/generic/patches-2.6.38/450-mtd_plat_nand_chip_fixup.patch b/target/linux/generic/patches-2.6.38/450-mtd_plat_nand_chip_fixup.patch
deleted file mode 100644
index 8ad32a8aad..0000000000
--- a/target/linux/generic/patches-2.6.38/450-mtd_plat_nand_chip_fixup.patch
+++ /dev/null
@@ -1,37 +0,0 @@
----
- drivers/mtd/nand/plat_nand.c |   13 ++++++++++++-
- include/linux/mtd/nand.h     |    1 +
- 2 files changed, 13 insertions(+), 1 deletion(-)
-
---- a/include/linux/mtd/nand.h
-+++ b/include/linux/mtd/nand.h
-@@ -622,6 +622,7 @@ struct platform_nand_chip {
- 	int chip_delay;
- 	unsigned int options;
- 	const char **part_probe_types;
-+	int (*chip_fixup)(struct mtd_info *mtd);
- 	void (*set_parts)(uint64_t size, struct platform_nand_chip *chip);
- 	void *priv;
- };
---- a/drivers/mtd/nand/plat_nand.c
-+++ b/drivers/mtd/nand/plat_nand.c
-@@ -96,7 +96,18 @@ static int __devinit plat_nand_probe(str
- 	}
- 
- 	/* Scan to find existance of the device */
--	if (nand_scan(&data->mtd, pdata->chip.nr_chips)) {
-+	if (nand_scan_ident(&data->mtd, pdata->chip.nr_chips, NULL)) {
-+		res = -ENXIO;
-+		goto out;
-+	}
-+
-+	if (pdata->chip.chip_fixup) {
-+		res = pdata->chip.chip_fixup(&data->mtd);
-+		if (res)
-+			goto out;
-+	}
-+
-+	if (nand_scan_tail(&data->mtd)) {
- 		err = -ENXIO;
- 		goto out;
- 	}
diff --git a/target/linux/generic/patches-2.6.38/451-mtd_fix_nand_correct_data_return_code.patch b/target/linux/generic/patches-2.6.38/451-mtd_fix_nand_correct_data_return_code.patch
deleted file mode 100644
index f630059e87..0000000000
--- a/target/linux/generic/patches-2.6.38/451-mtd_fix_nand_correct_data_return_code.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/drivers/mtd/nand/nand_ecc.c
-+++ b/drivers/mtd/nand/nand_ecc.c
-@@ -507,8 +507,7 @@ int __nand_correct_data(unsigned char *b
- 	if ((bitsperbyte[b0] + bitsperbyte[b1] + bitsperbyte[b2]) == 1)
- 		return 1;	/* error in ecc data; no action needed */
- 
--	printk(KERN_ERR "uncorrectable error : ");
--	return -1;
-+	return -EBADMSG;
- }
- EXPORT_SYMBOL(__nand_correct_data);
- 
diff --git a/target/linux/generic/patches-2.6.38/460-cfi_show_amd_extended_table_version.patch b/target/linux/generic/patches-2.6.38/460-cfi_show_amd_extended_table_version.patch
deleted file mode 100644
index 2369a19fac..0000000000
--- a/target/linux/generic/patches-2.6.38/460-cfi_show_amd_extended_table_version.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- a/drivers/mtd/chips/cfi_cmdset_0002.c
-+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
-@@ -462,9 +462,9 @@ struct mtd_info *cfi_cmdset_0002(struct
- 
- 			/*
- 			 * Valid primary extension versions are: 1.0, 1.1, 1.2, 1.3, 1.4
--			 * see: http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19 
--			 *      http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf
--			 *      http://www.spansion.com/Support/Datasheets/s29ws-p_00_a12_e.pdf
-+ 			 * see: Spec 1.3 http://cs.ozerki.net/zap/pub/axim-x5/docs/cfi_r20.pdf, page 19 
-+ 			 *               http://www.spansion.com/Support/AppNotes/cfi_100_20011201.pdf
-+			 *      Spec 1.4 http://www.spansion.com/Support/AppNotes/CFI_Spec_AN_03.pdf, page 9
- 			 */
- 			if (extp->MajorVersion != '1' ||
- 			    (extp->MajorVersion == '1' && (extp->MinorVersion < '0' || extp->MinorVersion > '4'))) {
diff --git a/target/linux/generic/patches-2.6.38/470-mtd_m25p80_add_pm25lv_flash_support.patch b/target/linux/generic/patches-2.6.38/470-mtd_m25p80_add_pm25lv_flash_support.patch
deleted file mode 100644
index 91cdd9763e..0000000000
--- a/target/linux/generic/patches-2.6.38/470-mtd_m25p80_add_pm25lv_flash_support.patch
+++ /dev/null
@@ -1,39 +0,0 @@
---- a/drivers/mtd/devices/m25p80.c
-+++ b/drivers/mtd/devices/m25p80.c
-@@ -43,6 +43,7 @@
- #define	OPCODE_BE_4K		0x20	/* Erase 4KiB block */
- #define	OPCODE_BE_32K		0x52	/* Erase 32KiB block */
- #define	OPCODE_CHIP_ERASE	0xc7	/* Erase whole flash chip */
-+#define	OPCODE_BE_4K_PMC	0xd7	/* Erase 4KiB block on PMC chips*/
- #define	OPCODE_SE		0xd8	/* Sector erase (usually 64KiB) */
- #define	OPCODE_RDID		0x9f	/* Read JEDEC ID */
- 
-@@ -617,6 +618,7 @@ struct flash_info {
- 	u16		flags;
- #define	SECT_4K		0x01		/* OPCODE_BE_4K works uniformly */
- #define	M25P_NO_ERASE	0x02		/* No erase command needed */
-+#define	SECT_4K_PMC	0x04		/* OPCODE_BE_4K_PMC works uniformly */
- };
- 
- #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-@@ -674,6 +676,10 @@ static const struct spi_device_id m25p_i
- 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
- 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
- 
-+	/* PMC -- pm25x "blocks" are 32K, sectors are 4K */
-+	{ "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) },
-+	{ "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) },
-+
- 	/* Spansion -- single (large) sector size only, at least
- 	 * for the chips listed here (without boot sectors).
- 	 */
-@@ -894,6 +900,9 @@ static int __devinit m25p_probe(struct s
- 	if (info->flags & SECT_4K) {
- 		flash->erase_opcode = OPCODE_BE_4K;
- 		flash->mtd.erasesize = 4096;
-+	} else if (info->flags & SECT_4K_PMC) {
-+		flash->erase_opcode = OPCODE_BE_4K_PMC;
-+		flash->mtd.erasesize = 4096;
- 	} else {
- 		flash->erase_opcode = OPCODE_SE;
- 		flash->mtd.erasesize = info->sector_size;
diff --git a/target/linux/generic/patches-2.6.38/471-mtd_m25p80_add_en25f32_chip_support.patch b/target/linux/generic/patches-2.6.38/471-mtd_m25p80_add_en25f32_chip_support.patch
deleted file mode 100644
index d0b3496222..0000000000
--- a/target/linux/generic/patches-2.6.38/471-mtd_m25p80_add_en25f32_chip_support.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/drivers/mtd/devices/m25p80.c
-+++ b/drivers/mtd/devices/m25p80.c
-@@ -657,7 +657,8 @@ static const struct spi_device_id m25p_i
- 	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
- 	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
- 
--	/* EON -- en25pxx */
-+	/* EON -- en25xxx */
-+	{ "en25f32", INFO(0x1c3116, 0, 64 * 1024,  64, SECT_4K) },
- 	{ "en25p32", INFO(0x1c2016, 0, 64 * 1024,  64, 0) },
- 	{ "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) },
- 
diff --git a/target/linux/generic/patches-2.6.38/472-mtd_m25p80_add_MX25L1606E_support.patch b/target/linux/generic/patches-2.6.38/472-mtd_m25p80_add_MX25L1606E_support.patch
deleted file mode 100644
index b5937a3557..0000000000
--- a/target/linux/generic/patches-2.6.38/472-mtd_m25p80_add_MX25L1606E_support.patch
+++ /dev/null
@@ -1,20 +0,0 @@
-From da9c4c174ad5086e5ccff23a5ffd1f9750b77c85 Mon Sep 17 00:00:00 2001
-From: Gabor Juhos <juhosg@openwrt.org>
-Date: Thu, 24 Mar 2011 21:43:48 +0100
-Subject: [PATCH] mtd: m25p80: add support for the MX25L1606E chip
-
-Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
----
- drivers/mtd/devices/m25p80.c |    1 +
- 1 files changed, 1 insertions(+), 0 deletions(-)
-
---- a/drivers/mtd/devices/m25p80.c
-+++ b/drivers/mtd/devices/m25p80.c
-@@ -670,6 +670,7 @@ static const struct spi_device_id m25p_i
- 	/* Macronix */
- 	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
- 	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
-+	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
- 	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, 0) },
- 	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, 0) },
- 	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
diff --git a/target/linux/generic/patches-2.6.38/473-mtd_m25p80_add_w25q128.patch b/target/linux/generic/patches-2.6.38/473-mtd_m25p80_add_w25q128.patch
deleted file mode 100644
index 9114555e61..0000000000
--- a/target/linux/generic/patches-2.6.38/473-mtd_m25p80_add_w25q128.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/mtd/devices/m25p80.c
-+++ b/drivers/mtd/devices/m25p80.c
-@@ -746,6 +746,7 @@ static const struct spi_device_id m25p_i
- 	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
- 	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
- 	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
-+	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
- 
- 	/* Catalyst / On Semiconductor -- non-JEDEC */
- 	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1) },
diff --git a/target/linux/generic/patches-2.6.38/474-mtd_concat_sync_fix.patch b/target/linux/generic/patches-2.6.38/474-mtd_concat_sync_fix.patch
deleted file mode 100644
index ff3759e220..0000000000
--- a/target/linux/generic/patches-2.6.38/474-mtd_concat_sync_fix.patch
+++ /dev/null
@@ -1,12 +0,0 @@
---- a/drivers/mtd/mtdconcat.c
-+++ b/drivers/mtd/mtdconcat.c
-@@ -619,7 +619,8 @@ static void concat_sync(struct mtd_info
- 
- 	for (i = 0; i < concat->num_subdev; i++) {
- 		struct mtd_info *subdev = concat->subdev[i];
--		subdev->sync(subdev);
-+		if (subdev->sync)
-+			subdev->sync(subdev);
- 	}
- }
- 
diff --git a/target/linux/generic/patches-2.6.38/500-yaffs_support.patch b/target/linux/generic/patches-2.6.38/500-yaffs_support.patch
deleted file mode 100644
index e7c87b8b13..0000000000
--- a/target/linux/generic/patches-2.6.38/500-yaffs_support.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -35,6 +35,7 @@ source "fs/gfs2/Kconfig"
- source "fs/ocfs2/Kconfig"
- source "fs/btrfs/Kconfig"
- source "fs/nilfs2/Kconfig"
-+source "fs/yaffs2/Kconfig"
- 
- endif # BLOCK
- 
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -122,3 +122,5 @@ obj-$(CONFIG_BTRFS_FS)		+= btrfs/
- obj-$(CONFIG_GFS2_FS)           += gfs2/
- obj-$(CONFIG_EXOFS_FS)          += exofs/
- obj-$(CONFIG_CEPH_FS)		+= ceph/
-+obj-$(CONFIG_YAFFS_FS)		+= yaffs2/
-+
diff --git a/target/linux/generic/patches-2.6.38/501-yaffs_cvs_2009_04_24.patch b/target/linux/generic/patches-2.6.38/501-yaffs_cvs_2009_04_24.patch
deleted file mode 100644
index c334b17d08..0000000000
--- a/target/linux/generic/patches-2.6.38/501-yaffs_cvs_2009_04_24.patch
+++ /dev/null
@@ -1,12344 +0,0 @@
---- a/fs/yaffs2/devextras.h
-+++ b/fs/yaffs2/devextras.h
-@@ -14,194 +14,135 @@
-  */
- 
- /*
-- * This file is just holds extra declarations used during development.
-- * Most of these are from kernel includes placed here so we can use them in
-- * applications.
-+ * This file is just holds extra declarations of macros that would normally
-+ * be providesd in the Linux kernel. These macros have been written from
-+ * scratch but are functionally equivalent to the Linux ones.
-  *
-  */
- 
- #ifndef __EXTRAS_H__
- #define __EXTRAS_H__
- 
--#if defined WIN32
--#define __inline__ __inline
--#define new newHack
--#endif
--
--#if !(defined __KERNEL__) || (defined WIN32)
- 
--/* User space defines */
-+#if !(defined __KERNEL__)
- 
-+/* Definition of types */
- typedef unsigned char __u8;
- typedef unsigned short __u16;
- typedef unsigned __u32;
- 
-+#endif
-+
- /*
-- * Simple doubly linked list implementation.
-- *
-- * Some of the internal functions ("__xxx") are useful when
-- * manipulating whole lists rather than single entries, as
-- * sometimes we already know the next/prev entries and we can
-- * generate better code by using them directly rather than
-- * using the generic single-entry routines.
-+ * This is a simple doubly linked list implementation that matches the
-+ * way the Linux kernel doubly linked list implementation works.
-  */
- 
--#define prefetch(x) 1
--
--struct list_head {
--	struct list_head *next, *prev;
-+struct ylist_head {
-+	struct ylist_head *next; /* next in chain */
-+	struct ylist_head *prev; /* previous in chain */
- };
- 
--#define LIST_HEAD_INIT(name) { &(name), &(name) }
- 
--#define LIST_HEAD(name) \
--	struct list_head name = LIST_HEAD_INIT(name)
-+/* Initialise a static list */
-+#define YLIST_HEAD(name) \
-+struct ylist_head name = { &(name), &(name)}
-+
- 
--#define INIT_LIST_HEAD(ptr) do { \
--	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
-+
-+/* Initialise a list head to an empty list */
-+#define YINIT_LIST_HEAD(p) \
-+do { \
-+	(p)->next = (p);\
-+	(p)->prev = (p); \
- } while (0)
- 
--/*
-- * Insert a new entry between two known consecutive entries.
-- *
-- * This is only for internal list manipulation where we know
-- * the prev/next entries already!
-- */
--static __inline__ void __list_add(struct list_head *new,
--				  struct list_head *prev,
--				  struct list_head *next)
--{
--	next->prev = new;
--	new->next = next;
--	new->prev = prev;
--	prev->next = new;
--}
- 
--/**
-- * list_add - add a new entry
-- * @new: new entry to be added
-- * @head: list head to add it after
-- *
-- * Insert a new entry after the specified head.
-- * This is good for implementing stacks.
-- */
--static __inline__ void list_add(struct list_head *new, struct list_head *head)
-+/* Add an element to a list */
-+static __inline__ void ylist_add(struct ylist_head *newEntry,
-+				struct ylist_head *list)
- {
--	__list_add(new, head, head->next);
--}
-+	struct ylist_head *listNext = list->next;
-+
-+	list->next = newEntry;
-+	newEntry->prev = list;
-+	newEntry->next = listNext;
-+	listNext->prev = newEntry;
- 
--/**
-- * list_add_tail - add a new entry
-- * @new: new entry to be added
-- * @head: list head to add it before
-- *
-- * Insert a new entry before the specified head.
-- * This is useful for implementing queues.
-- */
--static __inline__ void list_add_tail(struct list_head *new,
--				     struct list_head *head)
--{
--	__list_add(new, head->prev, head);
- }
- 
--/*
-- * Delete a list entry by making the prev/next entries
-- * point to each other.
-- *
-- * This is only for internal list manipulation where we know
-- * the prev/next entries already!
-- */
--static __inline__ void __list_del(struct list_head *prev,
--				  struct list_head *next)
-+static __inline__ void ylist_add_tail(struct ylist_head *newEntry,
-+				 struct ylist_head *list)
- {
--	next->prev = prev;
--	prev->next = next;
-+	struct ylist_head *listPrev = list->prev;
-+
-+	list->prev = newEntry;
-+	newEntry->next = list;
-+	newEntry->prev = listPrev;
-+	listPrev->next = newEntry;
-+
- }
- 
--/**
-- * list_del - deletes entry from list.
-- * @entry: the element to delete from the list.
-- * Note: list_empty on entry does not return true after this, the entry is
-- * in an undefined state.
-- */
--static __inline__ void list_del(struct list_head *entry)
-+
-+/* Take an element out of its current list, with or without
-+ * reinitialising the links.of the entry*/
-+static __inline__ void ylist_del(struct ylist_head *entry)
- {
--	__list_del(entry->prev, entry->next);
-+	struct ylist_head *listNext = entry->next;
-+	struct ylist_head *listPrev = entry->prev;
-+
-+	listNext->prev = listPrev;
-+	listPrev->next = listNext;
-+
- }
- 
--/**
-- * list_del_init - deletes entry from list and reinitialize it.
-- * @entry: the element to delete from the list.
-- */
--static __inline__ void list_del_init(struct list_head *entry)
-+static __inline__ void ylist_del_init(struct ylist_head *entry)
- {
--	__list_del(entry->prev, entry->next);
--	INIT_LIST_HEAD(entry);
-+	ylist_del(entry);
-+	entry->next = entry->prev = entry;
- }
- 
--/**
-- * list_empty - tests whether a list is empty
-- * @head: the list to test.
-- */
--static __inline__ int list_empty(struct list_head *head)
-+
-+/* Test if the list is empty */
-+static __inline__ int ylist_empty(struct ylist_head *entry)
- {
--	return head->next == head;
-+	return (entry->next == entry);
- }
- 
--/**
-- * list_splice - join two lists
-- * @list: the new list to add.
-- * @head: the place to add it in the first list.
-+
-+/* ylist_entry takes a pointer to a list entry and offsets it to that
-+ * we can find a pointer to the object it is embedded in.
-  */
--static __inline__ void list_splice(struct list_head *list,
--				   struct list_head *head)
--{
--	struct list_head *first = list->next;
- 
--	if (first != list) {
--		struct list_head *last = list->prev;
--		struct list_head *at = head->next;
--
--		first->prev = head;
--		head->next = first;
--
--		last->next = at;
--		at->prev = last;
--	}
--}
- 
--/**
-- * list_entry - get the struct for this entry
-- * @ptr:	the &struct list_head pointer.
-- * @type:	the type of the struct this is embedded in.
-- * @member:	the name of the list_struct within the struct.
-- */
--#define list_entry(ptr, type, member) \
--	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
--
--/**
-- * list_for_each	-	iterate over a list
-- * @pos:	the &struct list_head to use as a loop counter.
-- * @head:	the head for your list.
-- */
--#define list_for_each(pos, head) \
--	for (pos = (head)->next, prefetch(pos->next); pos != (head); \
--        	pos = pos->next, prefetch(pos->next))
--
--/**
-- * list_for_each_safe	-	iterate over a list safe against removal
-- *                              of list entry
-- * @pos:	the &struct list_head to use as a loop counter.
-- * @n:		another &struct list_head to use as temporary storage
-- * @head:	the head for your list.
-- */
--#define list_for_each_safe(pos, n, head) \
--	for (pos = (head)->next, n = pos->next; pos != (head); \
--		pos = n, n = pos->next)
-+#define ylist_entry(entry, type, member) \
-+	((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))
- 
--/*
-- * File types
-+
-+/* ylist_for_each and list_for_each_safe  iterate over lists.
-+ * ylist_for_each_safe uses temporary storage to make the list delete safe
-  */
-+
-+#define ylist_for_each(itervar, list) \
-+	for (itervar = (list)->next; itervar != (list); itervar = itervar->next)
-+
-+#define ylist_for_each_safe(itervar, saveVar, list) \
-+	for (itervar = (list)->next, saveVar = (list)->next->next; \
-+		itervar != (list); itervar = saveVar, saveVar = saveVar->next)
-+
-+
-+#if !(defined __KERNEL__)
-+
-+
-+#ifndef WIN32
-+#include <sys/stat.h>
-+#endif
-+
-+
-+#ifdef CONFIG_YAFFS_PROVIDE_DEFS
-+/* File types */
-+
-+
- #define DT_UNKNOWN	0
- #define DT_FIFO		1
- #define DT_CHR		2
-@@ -212,6 +153,7 @@ static __inline__ void list_splice(struc
- #define DT_SOCK		12
- #define DT_WHT		14
- 
-+
- #ifndef WIN32
- #include <sys/stat.h>
- #endif
-@@ -227,10 +169,6 @@ static __inline__ void list_splice(struc
- #define ATTR_ATIME	16
- #define ATTR_MTIME	32
- #define ATTR_CTIME	64
--#define ATTR_ATIME_SET	128
--#define ATTR_MTIME_SET	256
--#define ATTR_FORCE	512	/* Not a change, but a change it */
--#define ATTR_ATTR_FLAG	1024
- 
- struct iattr {
- 	unsigned int ia_valid;
-@@ -244,21 +182,15 @@ struct iattr {
- 	unsigned int ia_attr_flags;
- };
- 
--#define KERN_DEBUG
-+#endif
- 
- #else
- 
--#ifndef WIN32
- #include <linux/types.h>
--#include <linux/list.h>
- #include <linux/fs.h>
- #include <linux/stat.h>
--#endif
- 
- #endif
- 
--#if defined WIN32
--#undef new
--#endif
- 
- #endif
---- a/fs/yaffs2/Kconfig
-+++ b/fs/yaffs2/Kconfig
-@@ -5,7 +5,7 @@
- config YAFFS_FS
- 	tristate "YAFFS2 file system support"
- 	default n
--	depends on MTD
-+	depends on MTD_BLOCK
- 	select YAFFS_YAFFS1
- 	select YAFFS_YAFFS2
- 	help
-@@ -43,7 +43,8 @@ config YAFFS_9BYTE_TAGS
- 	  format that you need to continue to support.  New data written
- 	  also uses the older-style format.  Note: Use of this option
- 	  generally requires that MTD's oob layout be adjusted to use the
--	  older-style format.  See notes on tags formats and MTD versions.
-+	  older-style format.  See notes on tags formats and MTD versions
-+	  in yaffs_mtdif1.c.
- 
- 	  If unsure, say N.
- 
-@@ -109,26 +110,6 @@ config YAFFS_DISABLE_LAZY_LOAD
- 
- 	  If unsure, say N.
- 
--config YAFFS_CHECKPOINT_RESERVED_BLOCKS
--	int "Reserved blocks for checkpointing"
--	depends on YAFFS_YAFFS2
--	default 10
--	help
--          Give the number of Blocks to reserve for checkpointing.
--	  Checkpointing saves the state at unmount so that mounting is
--	  much faster as a scan of all the flash to regenerate this state
--	  is not needed.  These Blocks are reserved per partition, so if
--	  you have very small partitions the default (10) may be a mess
--	  for you.  You can set this value to 0, but that does not mean
--	  checkpointing is disabled at all. There only won't be any
--	  specially reserved blocks for checkpointing, so if there is
--	  enough free space on the filesystem, it will be used for
--	  checkpointing.
--
--	  If unsure, leave at default (10), but don't wonder if there are
--	  always 2MB used on your large page device partition (10 x 2k
--	  pagesize). When using small partitions or when being very small
--	  on space, you probably want to set this to zero.
- 
- config YAFFS_DISABLE_WIDE_TNODES
- 	bool "Turn off wide tnodes"
---- a/fs/yaffs2/Makefile
-+++ b/fs/yaffs2/Makefile
-@@ -5,7 +5,6 @@
- obj-$(CONFIG_YAFFS_FS) += yaffs.o
- 
- yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
--yaffs-y += yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
-+yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
- yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
--yaffs-y += yaffs_mtdif1.o yaffs_packedtags1.o
--yaffs-y += yaffs_mtdif.o yaffs_mtdif2.o
-+yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
---- a/fs/yaffs2/moduleconfig.h
-+++ b/fs/yaffs2/moduleconfig.h
-@@ -27,12 +27,12 @@
- 
- /* Default: Not selected */
- /* Meaning: Yaffs does its own ECC, rather than using MTD ECC */
--//#define CONFIG_YAFFS_DOES_ECC
-+/* #define CONFIG_YAFFS_DOES_ECC */
- 
- /* Default: Not selected */
- /* Meaning: ECC byte order is 'wrong'.  Only meaningful if */
- /*          CONFIG_YAFFS_DOES_ECC is set */
--//#define CONFIG_YAFFS_ECC_WRONG_ORDER
-+/* #define CONFIG_YAFFS_ECC_WRONG_ORDER */
- 
- /* Default: Selected */
- /* Meaning: Disables testing whether chunks are erased before writing to them*/
-@@ -54,11 +54,11 @@ that you need to continue to support.  N
- older-style format.
- Note: Use of this option generally requires that MTD's oob layout be
- adjusted to use the older-style format.  See notes on tags formats and
--MTD versions.
-+MTD versions in yaffs_mtdif1.c.
- */
- /* Default: Not selected */
- /* Meaning: Use older-style on-NAND data format with pageStatus byte */
--#define CONFIG_YAFFS_9BYTE_TAGS
-+/* #define CONFIG_YAFFS_9BYTE_TAGS */
- 
- #endif /* YAFFS_OUT_OF_TREE */
- 
---- a/fs/yaffs2/yaffs_checkptrw.c
-+++ b/fs/yaffs2/yaffs_checkptrw.c
-@@ -12,48 +12,43 @@
-  */
- 
- const char *yaffs_checkptrw_c_version =
--    "$Id: yaffs_checkptrw.c,v 1.14 2007-05-15 20:07:40 charles Exp $";
-+	"$Id: yaffs_checkptrw.c,v 1.18 2009-03-06 17:20:49 wookey Exp $";
- 
- 
- #include "yaffs_checkptrw.h"
--
-+#include "yaffs_getblockinfo.h"
- 
- static int yaffs_CheckpointSpaceOk(yaffs_Device *dev)
- {
--
- 	int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
- 
- 	T(YAFFS_TRACE_CHECKPOINT,
- 		(TSTR("checkpt blocks available = %d" TENDSTR),
- 		blocksAvailable));
- 
--
- 	return (blocksAvailable <= 0) ? 0 : 1;
- }
- 
- 
- static int yaffs_CheckpointErase(yaffs_Device *dev)
- {
--
- 	int i;
- 
--
--	if(!dev->eraseBlockInNAND)
-+	if (!dev->eraseBlockInNAND)
- 		return 0;
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("checking blocks %d to %d"TENDSTR),
--		dev->internalStartBlock,dev->internalEndBlock));
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checking blocks %d to %d"TENDSTR),
-+		dev->internalStartBlock, dev->internalEndBlock));
- 
--	for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
--		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
--		if(bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT){
--			T(YAFFS_TRACE_CHECKPOINT,(TSTR("erasing checkpt block %d"TENDSTR),i));
--			if(dev->eraseBlockInNAND(dev,i- dev->blockOffset /* realign */)){
-+	for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
-+		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
-+		if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) {
-+			T(YAFFS_TRACE_CHECKPOINT, (TSTR("erasing checkpt block %d"TENDSTR), i));
-+			if (dev->eraseBlockInNAND(dev, i - dev->blockOffset /* realign */)) {
- 				bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
- 				dev->nErasedBlocks++;
- 				dev->nFreeChunks += dev->nChunksPerBlock;
--			}
--			else {
--				dev->markNANDBlockBad(dev,i);
-+			} else {
-+				dev->markNANDBlockBad(dev, i);
- 				bi->blockState = YAFFS_BLOCK_STATE_DEAD;
- 			}
- 		}
-@@ -71,23 +66,23 @@ static void yaffs_CheckpointFindNextEras
- 	int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
- 	T(YAFFS_TRACE_CHECKPOINT,
- 		(TSTR("allocating checkpt block: erased %d reserved %d avail %d next %d "TENDSTR),
--		dev->nErasedBlocks,dev->nReservedBlocks,blocksAvailable,dev->checkpointNextBlock));
-+		dev->nErasedBlocks, dev->nReservedBlocks, blocksAvailable, dev->checkpointNextBlock));
- 
--	if(dev->checkpointNextBlock >= 0 &&
--	   dev->checkpointNextBlock <= dev->internalEndBlock &&
--	   blocksAvailable > 0){
--
--		for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){
--			yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
--			if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY){
-+	if (dev->checkpointNextBlock >= 0 &&
-+			dev->checkpointNextBlock <= dev->internalEndBlock &&
-+			blocksAvailable > 0) {
-+
-+		for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
-+			yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
-+			if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY) {
- 				dev->checkpointNextBlock = i + 1;
- 				dev->checkpointCurrentBlock = i;
--				T(YAFFS_TRACE_CHECKPOINT,(TSTR("allocating checkpt block %d"TENDSTR),i));
-+				T(YAFFS_TRACE_CHECKPOINT, (TSTR("allocating checkpt block %d"TENDSTR), i));
- 				return;
- 			}
- 		}
- 	}
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("out of checkpt blocks"TENDSTR)));
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("out of checkpt blocks"TENDSTR)));
- 
- 	dev->checkpointNextBlock = -1;
- 	dev->checkpointCurrentBlock = -1;
-@@ -98,30 +93,31 @@ static void yaffs_CheckpointFindNextChec
- 	int  i;
- 	yaffs_ExtendedTags tags;
- 
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: start:  blocks %d next %d" TENDSTR),
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: start:  blocks %d next %d" TENDSTR),
- 		dev->blocksInCheckpoint, dev->checkpointNextBlock));
- 
--	if(dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
--		for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){
-+	if (dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
-+		for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
- 			int chunk = i * dev->nChunksPerBlock;
- 			int realignedChunk = chunk - dev->chunkOffset;
- 
--			dev->readChunkWithTagsFromNAND(dev,realignedChunk,NULL,&tags);
--			T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR),
--				i, tags.objectId,tags.sequenceNumber,tags.eccResult));
-+			dev->readChunkWithTagsFromNAND(dev, realignedChunk,
-+					NULL, &tags);
-+			T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR),
-+				i, tags.objectId, tags.sequenceNumber, tags.eccResult));
- 
--			if(tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA){
-+			if (tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA) {
- 				/* Right kind of block */
- 				dev->checkpointNextBlock = tags.objectId;
- 				dev->checkpointCurrentBlock = i;
- 				dev->checkpointBlockList[dev->blocksInCheckpoint] = i;
- 				dev->blocksInCheckpoint++;
--				T(YAFFS_TRACE_CHECKPOINT,(TSTR("found checkpt block %d"TENDSTR),i));
-+				T(YAFFS_TRACE_CHECKPOINT, (TSTR("found checkpt block %d"TENDSTR), i));
- 				return;
- 			}
- 		}
- 
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("found no more checkpt blocks"TENDSTR)));
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("found no more checkpt blocks"TENDSTR)));
- 
- 	dev->checkpointNextBlock = -1;
- 	dev->checkpointCurrentBlock = -1;
-@@ -133,17 +129,17 @@ int yaffs_CheckpointOpen(yaffs_Device *d
- 
- 	/* Got the functions we need? */
- 	if (!dev->writeChunkWithTagsToNAND ||
--	    !dev->readChunkWithTagsFromNAND ||
--	    !dev->eraseBlockInNAND ||
--	    !dev->markNANDBlockBad)
-+			!dev->readChunkWithTagsFromNAND ||
-+			!dev->eraseBlockInNAND ||
-+			!dev->markNANDBlockBad)
- 		return 0;
- 
--	if(forWriting && !yaffs_CheckpointSpaceOk(dev))
-+	if (forWriting && !yaffs_CheckpointSpaceOk(dev))
- 		return 0;
- 
--	if(!dev->checkpointBuffer)
--		dev->checkpointBuffer = YMALLOC_DMA(dev->nDataBytesPerChunk);
--	if(!dev->checkpointBuffer)
-+	if (!dev->checkpointBuffer)
-+		dev->checkpointBuffer = YMALLOC_DMA(dev->totalBytesPerChunk);
-+	if (!dev->checkpointBuffer)
- 		return 0;
- 
- 
-@@ -159,12 +155,10 @@ int yaffs_CheckpointOpen(yaffs_Device *d
- 	dev->checkpointNextBlock = dev->internalStartBlock;
- 
- 	/* Erase all the blocks in the checkpoint area */
--	if(forWriting){
--		memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
-+	if (forWriting) {
-+		memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
- 		dev->checkpointByteOffset = 0;
- 		return yaffs_CheckpointErase(dev);
--
--
- 	} else {
- 		int i;
- 		/* Set to a value that will kick off a read */
-@@ -174,7 +168,7 @@ int yaffs_CheckpointOpen(yaffs_Device *d
- 		dev->blocksInCheckpoint = 0;
- 		dev->checkpointMaxBlocks = (dev->internalEndBlock - dev->internalStartBlock)/16 + 2;
- 		dev->checkpointBlockList = YMALLOC(sizeof(int) * dev->checkpointMaxBlocks);
--		for(i = 0; i < dev->checkpointMaxBlocks; i++)
-+		for (i = 0; i < dev->checkpointMaxBlocks; i++)
- 			dev->checkpointBlockList[i] = -1;
- 	}
- 
-@@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device
- 
- static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
- {
--
- 	int chunk;
- 	int realignedChunk;
- 
- 	yaffs_ExtendedTags tags;
- 
--	if(dev->checkpointCurrentBlock < 0){
-+	if (dev->checkpointCurrentBlock < 0) {
- 		yaffs_CheckpointFindNextErasedBlock(dev);
- 		dev->checkpointCurrentChunk = 0;
- 	}
- 
--	if(dev->checkpointCurrentBlock < 0)
-+	if (dev->checkpointCurrentBlock < 0)
- 		return 0;
- 
- 	tags.chunkDeleted = 0;
-@@ -210,10 +203,10 @@ static int yaffs_CheckpointFlushBuffer(y
- 	tags.chunkId = dev->checkpointPageSequence + 1;
- 	tags.sequenceNumber =  YAFFS_SEQUENCE_CHECKPOINT_DATA;
- 	tags.byteCount = dev->nDataBytesPerChunk;
--	if(dev->checkpointCurrentChunk == 0){
-+	if (dev->checkpointCurrentChunk == 0) {
- 		/* First chunk we write for the block? Set block state to
- 		   checkpoint */
--		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointCurrentBlock);
-+		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointCurrentBlock);
- 		bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
- 		dev->blocksInCheckpoint++;
- 	}
-@@ -221,28 +214,29 @@ static int yaffs_CheckpointFlushBuffer(y
- 	chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk;
- 
- 
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
--		chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk,tags.objectId,tags.chunkId));
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
-+		chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk, tags.objectId, tags.chunkId));
- 
- 	realignedChunk = chunk - dev->chunkOffset;
- 
--	dev->writeChunkWithTagsToNAND(dev,realignedChunk,dev->checkpointBuffer,&tags);
-+	dev->writeChunkWithTagsToNAND(dev, realignedChunk,
-+			dev->checkpointBuffer, &tags);
- 	dev->checkpointByteOffset = 0;
- 	dev->checkpointPageSequence++;
- 	dev->checkpointCurrentChunk++;
--	if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock){
-+	if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock) {
- 		dev->checkpointCurrentChunk = 0;
- 		dev->checkpointCurrentBlock = -1;
- 	}
--	memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
-+	memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
- 
- 	return 1;
- }
- 
- 
--int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
-+int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes)
- {
--	int i=0;
-+	int i = 0;
- 	int ok = 1;
- 
- 
-@@ -250,17 +244,14 @@ int yaffs_CheckpointWrite(yaffs_Device *
- 
- 
- 
--	if(!dev->checkpointBuffer)
-+	if (!dev->checkpointBuffer)
- 		return 0;
- 
--	if(!dev->checkpointOpenForWrite)
-+	if (!dev->checkpointOpenForWrite)
- 		return -1;
- 
--	while(i < nBytes && ok) {
--
--
--
--		dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes ;
-+	while (i < nBytes && ok) {
-+		dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes;
- 		dev->checkpointSum += *dataBytes;
- 		dev->checkpointXor ^= *dataBytes;
- 
-@@ -270,18 +261,17 @@ int yaffs_CheckpointWrite(yaffs_Device *
- 		dev->checkpointByteCount++;
- 
- 
--		if(dev->checkpointByteOffset < 0 ||
-+		if (dev->checkpointByteOffset < 0 ||
- 		   dev->checkpointByteOffset >= dev->nDataBytesPerChunk)
- 			ok = yaffs_CheckpointFlushBuffer(dev);
--
- 	}
- 
--	return 	i;
-+	return i;
- }
- 
- int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
- {
--	int i=0;
-+	int i = 0;
- 	int ok = 1;
- 	yaffs_ExtendedTags tags;
- 
-@@ -291,52 +281,54 @@ int yaffs_CheckpointRead(yaffs_Device *d
- 
- 	__u8 *dataBytes = (__u8 *)data;
- 
--	if(!dev->checkpointBuffer)
-+	if (!dev->checkpointBuffer)
- 		return 0;
- 
--	if(dev->checkpointOpenForWrite)
-+	if (dev->checkpointOpenForWrite)
- 		return -1;
- 
--	while(i < nBytes && ok) {
-+	while (i < nBytes && ok) {
- 
- 
--		if(dev->checkpointByteOffset < 0 ||
--		   dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
-+		if (dev->checkpointByteOffset < 0 ||
-+			dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
- 
--		   	if(dev->checkpointCurrentBlock < 0){
-+			if (dev->checkpointCurrentBlock < 0) {
- 				yaffs_CheckpointFindNextCheckpointBlock(dev);
- 				dev->checkpointCurrentChunk = 0;
- 			}
- 
--			if(dev->checkpointCurrentBlock < 0)
-+			if (dev->checkpointCurrentBlock < 0)
- 				ok = 0;
- 			else {
--
--				chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock +
--				          dev->checkpointCurrentChunk;
-+				chunk = dev->checkpointCurrentBlock *
-+					dev->nChunksPerBlock +
-+					dev->checkpointCurrentChunk;
- 
- 				realignedChunk = chunk - dev->chunkOffset;
- 
--	   			/* read in the next chunk */
--	   			/* printf("read checkpoint page %d\n",dev->checkpointPage); */
--				dev->readChunkWithTagsFromNAND(dev, realignedChunk,
--							       dev->checkpointBuffer,
--							      &tags);
--
--				if(tags.chunkId != (dev->checkpointPageSequence + 1) ||
--				   tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
--				   ok = 0;
-+				/* read in the next chunk */
-+				/* printf("read checkpoint page %d\n",dev->checkpointPage); */
-+				dev->readChunkWithTagsFromNAND(dev,
-+						realignedChunk,
-+						dev->checkpointBuffer,
-+						&tags);
-+
-+				if (tags.chunkId != (dev->checkpointPageSequence + 1) ||
-+					tags.eccResult > YAFFS_ECC_RESULT_FIXED ||
-+					tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
-+					ok = 0;
- 
- 				dev->checkpointByteOffset = 0;
- 				dev->checkpointPageSequence++;
- 				dev->checkpointCurrentChunk++;
- 
--				if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
-+				if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
- 					dev->checkpointCurrentBlock = -1;
- 			}
- 		}
- 
--		if(ok){
-+		if (ok) {
- 			*dataBytes = dev->checkpointBuffer[dev->checkpointByteOffset];
- 			dev->checkpointSum += *dataBytes;
- 			dev->checkpointXor ^= *dataBytes;
-@@ -353,17 +345,17 @@ int yaffs_CheckpointRead(yaffs_Device *d
- int yaffs_CheckpointClose(yaffs_Device *dev)
- {
- 
--	if(dev->checkpointOpenForWrite){
--		if(dev->checkpointByteOffset != 0)
-+	if (dev->checkpointOpenForWrite) {
-+		if (dev->checkpointByteOffset != 0)
- 			yaffs_CheckpointFlushBuffer(dev);
- 	} else {
- 		int i;
--		for(i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++){
--			yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointBlockList[i]);
--			if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
-+		for (i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++) {
-+			yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointBlockList[i]);
-+			if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
- 				bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
- 			else {
--				// Todo this looks odd...
-+				/* Todo this looks odd... */
- 			}
- 		}
- 		YFREE(dev->checkpointBlockList);
-@@ -374,27 +366,25 @@ int yaffs_CheckpointClose(yaffs_Device *
- 	dev->nErasedBlocks -= dev->blocksInCheckpoint;
- 
- 
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint byte count %d" TENDSTR),
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint byte count %d" TENDSTR),
- 			dev->checkpointByteCount));
- 
--	if(dev->checkpointBuffer){
-+	if (dev->checkpointBuffer) {
- 		/* free the buffer */
- 		YFREE(dev->checkpointBuffer);
- 		dev->checkpointBuffer = NULL;
- 		return 1;
--	}
--	else
-+	} else
- 		return 0;
--
- }
- 
- int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
- {
- 	/* Erase the first checksum block */
- 
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint invalidate"TENDSTR)));
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate"TENDSTR)));
- 
--	if(!yaffs_CheckpointSpaceOk(dev))
-+	if (!yaffs_CheckpointSpaceOk(dev))
- 		return 0;
- 
- 	return yaffs_CheckpointErase(dev);
---- a/fs/yaffs2/yaffs_checkptrw.h
-+++ b/fs/yaffs2/yaffs_checkptrw.h
-@@ -20,9 +20,9 @@
- 
- int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting);
- 
--int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes);
-+int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes);
- 
--int yaffs_CheckpointRead(yaffs_Device *dev,void *data, int nBytes);
-+int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes);
- 
- int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum);
- 
---- a/fs/yaffs2/yaffs_ecc.c
-+++ b/fs/yaffs2/yaffs_ecc.c
-@@ -29,7 +29,7 @@
-  */
- 
- const char *yaffs_ecc_c_version =
--    "$Id: yaffs_ecc.c,v 1.9 2007-02-14 01:09:06 wookey Exp $";
-+	"$Id: yaffs_ecc.c,v 1.11 2009-03-06 17:20:50 wookey Exp $";
- 
- #include "yportenv.h"
- 
-@@ -109,12 +109,10 @@ void yaffs_ECCCalculate(const unsigned c
- 		b = column_parity_table[*data++];
- 		col_parity ^= b;
- 
--		if (b & 0x01)	// odd number of bits in the byte
--		{
-+		if (b & 0x01) {		/* odd number of bits in the byte */
- 			line_parity ^= i;
- 			line_parity_prime ^= ~i;
- 		}
--
- 	}
- 
- 	ecc[2] = (~col_parity) | 0x03;
-@@ -158,7 +156,7 @@ void yaffs_ECCCalculate(const unsigned c
- 	ecc[0] = ~t;
- 
- #ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
--	// Swap the bytes into the wrong order
-+	/* Swap the bytes into the wrong order */
- 	t = ecc[0];
- 	ecc[0] = ecc[1];
- 	ecc[1] = t;
-@@ -189,7 +187,7 @@ int yaffs_ECCCorrect(unsigned char *data
- 		unsigned bit;
- 
- #ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
--		// swap the bytes to correct for the wrong order
-+		/* swap the bytes to correct for the wrong order */
- 		unsigned char t;
- 
- 		t = d0;
-@@ -251,7 +249,7 @@ int yaffs_ECCCorrect(unsigned char *data
-  * ECCxxxOther does ECC calcs on arbitrary n bytes of data
-  */
- void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
--			     yaffs_ECCOther * eccOther)
-+				yaffs_ECCOther *eccOther)
- {
- 	unsigned int i;
- 
-@@ -278,8 +276,8 @@ void yaffs_ECCCalculateOther(const unsig
- }
- 
- int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
--			  yaffs_ECCOther * read_ecc,
--			  const yaffs_ECCOther * test_ecc)
-+			yaffs_ECCOther *read_ecc,
-+			const yaffs_ECCOther *test_ecc)
- {
- 	unsigned char cDelta;	/* column parity delta */
- 	unsigned lDelta;	/* line parity delta */
-@@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char
- 		return 0; /* no error */
- 
- 	if (lDelta == ~lDeltaPrime &&
--	    (((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15))
--	{
-+	    (((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15)) {
- 		/* Single bit (recoverable) error in data */
- 
- 		bit = 0;
-@@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char
- 		if (cDelta & 0x02)
- 			bit |= 0x01;
- 
--		if(lDelta >= nBytes)
-+		if (lDelta >= nBytes)
- 			return -1;
- 
- 		data[lDelta] ^= (1 << bit);
-@@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char
- 	}
- 
- 	if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
--	     yaffs_CountBits(cDelta)) == 1) {
-+			yaffs_CountBits(cDelta)) == 1) {
- 		/* Reccoverable error in ecc */
- 
- 		*read_ecc = *test_ecc;
-@@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char
- 	/* Unrecoverable error */
- 
- 	return -1;
--
- }
--
---- a/fs/yaffs2/yaffs_ecc.h
-+++ b/fs/yaffs2/yaffs_ecc.h
-@@ -13,15 +13,15 @@
-  * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-  */
- 
-- /*
--  * This code implements the ECC algorithm used in SmartMedia.
--  *
--  * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
--  * The two unused bit are set to 1.
--  * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
--  * blocks are used on a 512-byte NAND page.
--  *
--  */
-+/*
-+ * This code implements the ECC algorithm used in SmartMedia.
-+ *
-+ * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
-+ * The two unused bit are set to 1.
-+ * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
-+ * blocks are used on a 512-byte NAND page.
-+ *
-+ */
- 
- #ifndef __YAFFS_ECC_H__
- #define __YAFFS_ECC_H__
-@@ -34,11 +34,11 @@ typedef struct {
- 
- void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc);
- int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
--		     const unsigned char *test_ecc);
-+		const unsigned char *test_ecc);
- 
- void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
--			     yaffs_ECCOther * ecc);
-+			yaffs_ECCOther *ecc);
- int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
--			  yaffs_ECCOther * read_ecc,
--			  const yaffs_ECCOther * test_ecc);
-+			yaffs_ECCOther *read_ecc,
-+			const yaffs_ECCOther *test_ecc);
- #endif
---- a/fs/yaffs2/yaffs_fs.c
-+++ b/fs/yaffs2/yaffs_fs.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2009 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -32,18 +32,17 @@
-  */
- 
- const char *yaffs_fs_c_version =
--    "$Id: yaffs_fs.c,v 1.63 2007-09-19 20:35:40 imcd Exp $";
-+    "$Id: yaffs_fs.c,v 1.79 2009-03-17 01:12:00 wookey Exp $";
- extern const char *yaffs_guts_c_version;
- 
- #include <linux/version.h>
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
- #include <linux/config.h>
- #endif
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/slab.h>
- #include <linux/init.h>
--#include <linux/list.h>
- #include <linux/fs.h>
- #include <linux/proc_fs.h>
- #include <linux/smp_lock.h>
-@@ -53,10 +52,12 @@ extern const char *yaffs_guts_c_version;
- #include <linux/string.h>
- #include <linux/ctype.h>
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#include "asm/div64.h"
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- 
- #include <linux/statfs.h>	/* Added NCB 15-8-2003 */
--#include <asm/statfs.h>
-+#include <linux/statfs.h>
- #define UnlockPage(p) unlock_page(p)
- #define Page_Uptodate(page)	test_bit(PG_uptodate, &(page)->flags)
- 
-@@ -69,22 +70,45 @@ extern const char *yaffs_guts_c_version;
- #define	BDEVNAME_SIZE		0
- #define	yaffs_devname(sb, buf)	kdevname(sb->s_dev)
- 
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
- /* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */
- #define __user
- #endif
- 
- #endif
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
-+#define YPROC_ROOT  (&proc_root)
-+#else
-+#define YPROC_ROOT  NULL
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- #define WRITE_SIZE_STR "writesize"
--#define WRITE_SIZE(mtd) (mtd)->writesize
-+#define WRITE_SIZE(mtd) ((mtd)->writesize)
- #else
- #define WRITE_SIZE_STR "oobblock"
--#define WRITE_SIZE(mtd) (mtd)->oobblock
-+#define WRITE_SIZE(mtd) ((mtd)->oobblock)
- #endif
- 
--#include <asm/uaccess.h>
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
-+#define YAFFS_USE_WRITE_BEGIN_END 1
-+#else
-+#define YAFFS_USE_WRITE_BEGIN_END 0
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
-+static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
-+{
-+	uint64_t result = partition_size;
-+	do_div(result, block_size);
-+	return (uint32_t)result;
-+}
-+#else
-+#define YCALCBLOCKS(s, b) ((s)/(b))
-+#endif
-+
-+#include <linux/uaccess.h>
- 
- #include "yportenv.h"
- #include "yaffs_guts.h"
-@@ -96,28 +120,44 @@ extern const char *yaffs_guts_c_version;
- 
- unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS;
- unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
-+unsigned int yaffs_auto_checkpoint = 1;
- 
- /* Module Parameters */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
--module_param(yaffs_traceMask,uint,0644);
--module_param(yaffs_wr_attempts,uint,0644);
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+module_param(yaffs_traceMask, uint, 0644);
-+module_param(yaffs_wr_attempts, uint, 0644);
-+module_param(yaffs_auto_checkpoint, uint, 0644);
-+#else
-+MODULE_PARM(yaffs_traceMask, "i");
-+MODULE_PARM(yaffs_wr_attempts, "i");
-+MODULE_PARM(yaffs_auto_checkpoint, "i");
-+#endif
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
-+/* use iget and read_inode */
-+#define Y_IGET(sb, inum) iget((sb), (inum))
-+static void yaffs_read_inode(struct inode *inode);
-+
- #else
--MODULE_PARM(yaffs_traceMask,"i");
--MODULE_PARM(yaffs_wr_attempts,"i");
-+/* Call local equivalent */
-+#define YAFFS_USE_OWN_IGET
-+#define Y_IGET(sb, inum) yaffs_iget((sb), (inum))
-+
-+static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino);
- #endif
- 
- /*#define T(x) printk x */
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
--#define yaffs_InodeToObjectLV(iptr) (iptr)->i_private
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
-+#define yaffs_InodeToObjectLV(iptr) ((iptr)->i_private)
- #else
--#define yaffs_InodeToObjectLV(iptr) (iptr)->u.generic_ip
-+#define yaffs_InodeToObjectLV(iptr) ((iptr)->u.generic_ip)
- #endif
- 
- #define yaffs_InodeToObject(iptr) ((yaffs_Object *)(yaffs_InodeToObjectLV(iptr)))
- #define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode)
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- #define yaffs_SuperToDevice(sb)	((yaffs_Device *)sb->s_fs_info)
- #else
- #define yaffs_SuperToDevice(sb)	((yaffs_Device *)sb->u.generic_sbp)
-@@ -126,47 +166,49 @@ MODULE_PARM(yaffs_wr_attempts,"i");
- static void yaffs_put_super(struct super_block *sb);
- 
- static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
--				loff_t * pos);
-+				loff_t *pos);
-+static ssize_t yaffs_hold_space(struct file *f);
-+static void yaffs_release_space(struct file *f);
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static int yaffs_file_flush(struct file *file, fl_owner_t id);
- #else
- static int yaffs_file_flush(struct file *file);
- #endif
- 
- static int yaffs_sync_object(struct file *file, struct dentry *dentry,
--			     int datasync);
-+				int datasync);
- 
- static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir);
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
- 			struct nameidata *n);
- static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
--				   struct nameidata *n);
-+					struct nameidata *n);
- #else
- static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode);
- static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry);
- #endif
- static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
--		      struct dentry *dentry);
-+			struct dentry *dentry);
- static int yaffs_unlink(struct inode *dir, struct dentry *dentry);
- static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
--			 const char *symname);
-+			const char *symname);
- static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
--		       dev_t dev);
-+			dev_t dev);
- #else
- static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
--		       int dev);
-+			int dev);
- #endif
- static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
- 			struct inode *new_dir, struct dentry *new_dentry);
- static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static int yaffs_sync_fs(struct super_block *sb, int wait);
- static void yaffs_write_super(struct super_block *sb);
- #else
-@@ -174,33 +216,47 @@ static int yaffs_sync_fs(struct super_bl
- static int yaffs_write_super(struct super_block *sb);
- #endif
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf);
--#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
- #else
- static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
- #endif
--static void yaffs_read_inode(struct inode *inode);
- 
-+#ifdef YAFFS_HAS_PUT_INODE
- static void yaffs_put_inode(struct inode *inode);
-+#endif
-+
- static void yaffs_delete_inode(struct inode *);
- static void yaffs_clear_inode(struct inode *);
- 
- static int yaffs_readpage(struct file *file, struct page *page);
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_writepage(struct page *page, struct writeback_control *wbc);
- #else
- static int yaffs_writepage(struct page *page);
- #endif
-+
-+
-+#if (YAFFS_USE_WRITE_BEGIN_END != 0)
-+static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
-+				loff_t pos, unsigned len, unsigned flags,
-+				struct page **pagep, void **fsdata);
-+static int yaffs_write_end(struct file *filp, struct address_space *mapping,
-+				loff_t pos, unsigned len, unsigned copied,
-+				struct page *pg, void *fsdadata);
-+#else
- static int yaffs_prepare_write(struct file *f, struct page *pg,
--			       unsigned offset, unsigned to);
-+				unsigned offset, unsigned to);
- static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
--			      unsigned to);
-+				unsigned to);
- 
--static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
--			  int buflen);
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
-+#endif
-+
-+static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
-+				int buflen);
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
- static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
- #else
- static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
-@@ -209,12 +265,17 @@ static int yaffs_follow_link(struct dent
- static struct address_space_operations yaffs_file_address_operations = {
- 	.readpage = yaffs_readpage,
- 	.writepage = yaffs_writepage,
-+#if (YAFFS_USE_WRITE_BEGIN_END > 0)
-+	.write_begin = yaffs_write_begin,
-+	.write_end = yaffs_write_end,
-+#else
- 	.prepare_write = yaffs_prepare_write,
- 	.commit_write = yaffs_commit_write,
-+#endif
- };
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
--static struct file_operations yaffs_file_operations = {
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
-+static const struct file_operations yaffs_file_operations = {
- 	.read = do_sync_read,
- 	.write = do_sync_write,
- 	.aio_read = generic_file_aio_read,
-@@ -224,11 +285,12 @@ static struct file_operations yaffs_file
- 	.fsync = yaffs_sync_object,
- 	.splice_read = generic_file_splice_read,
- 	.splice_write = generic_file_splice_write,
-+	.llseek = generic_file_llseek,
- };
- 
--#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
-+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
- 
--static struct file_operations yaffs_file_operations = {
-+static const struct file_operations yaffs_file_operations = {
- 	.read = do_sync_read,
- 	.write = do_sync_write,
- 	.aio_read = generic_file_aio_read,
-@@ -241,29 +303,29 @@ static struct file_operations yaffs_file
- 
- #else
- 
--static struct file_operations yaffs_file_operations = {
-+static const struct file_operations yaffs_file_operations = {
- 	.read = generic_file_read,
- 	.write = generic_file_write,
- 	.mmap = generic_file_mmap,
- 	.flush = yaffs_file_flush,
- 	.fsync = yaffs_sync_object,
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- 	.sendfile = generic_file_sendfile,
- #endif
- };
- #endif
- 
--static struct inode_operations yaffs_file_inode_operations = {
-+static const struct inode_operations yaffs_file_inode_operations = {
- 	.setattr = yaffs_setattr,
- };
- 
--static struct inode_operations yaffs_symlink_inode_operations = {
-+static const struct inode_operations yaffs_symlink_inode_operations = {
- 	.readlink = yaffs_readlink,
- 	.follow_link = yaffs_follow_link,
- 	.setattr = yaffs_setattr,
- };
- 
--static struct inode_operations yaffs_dir_inode_operations = {
-+static const struct inode_operations yaffs_dir_inode_operations = {
- 	.create = yaffs_create,
- 	.lookup = yaffs_lookup,
- 	.link = yaffs_link,
-@@ -276,16 +338,21 @@ static struct inode_operations yaffs_dir
- 	.setattr = yaffs_setattr,
- };
- 
--static struct file_operations yaffs_dir_operations = {
-+static const struct file_operations yaffs_dir_operations = {
- 	.read = generic_read_dir,
- 	.readdir = yaffs_readdir,
- 	.fsync = yaffs_sync_object,
- };
- 
--static struct super_operations yaffs_super_ops = {
-+static const struct super_operations yaffs_super_ops = {
- 	.statfs = yaffs_statfs,
-+
-+#ifndef YAFFS_USE_OWN_IGET
- 	.read_inode = yaffs_read_inode,
-+#endif
-+#ifdef YAFFS_HAS_PUT_INODE
- 	.put_inode = yaffs_put_inode,
-+#endif
- 	.put_super = yaffs_put_super,
- 	.delete_inode = yaffs_delete_inode,
- 	.clear_inode = yaffs_clear_inode,
-@@ -293,22 +360,21 @@ static struct super_operations yaffs_sup
- 	.write_super = yaffs_write_super,
- };
- 
--static void yaffs_GrossLock(yaffs_Device * dev)
-+static void yaffs_GrossLock(yaffs_Device *dev)
- {
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs locking\n"));
--
-+	T(YAFFS_TRACE_OS, ("yaffs locking %p\n", current));
- 	down(&dev->grossLock);
-+	T(YAFFS_TRACE_OS, ("yaffs locked %p\n", current));
- }
- 
--static void yaffs_GrossUnlock(yaffs_Device * dev)
-+static void yaffs_GrossUnlock(yaffs_Device *dev)
- {
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs unlocking\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs unlocking %p\n", current));
- 	up(&dev->grossLock);
--
- }
- 
--static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
--			  int buflen)
-+static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
-+			int buflen)
- {
- 	unsigned char *alias;
- 	int ret;
-@@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry
- 	return ret;
- }
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
- static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
- #else
- static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
-@@ -345,32 +411,31 @@ static int yaffs_follow_link(struct dent
- 
- 	yaffs_GrossUnlock(dev);
- 
--	if (!alias)
--        {
-+	if (!alias) {
- 		ret = -ENOMEM;
- 		goto out;
--        }
-+	}
- 
- 	ret = vfs_follow_link(nd, alias);
- 	kfree(alias);
- out:
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
--	return ERR_PTR (ret);
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
-+	return ERR_PTR(ret);
- #else
- 	return ret;
- #endif
- }
- 
- struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
--			      yaffs_Object * obj);
-+				yaffs_Object *obj);
- 
- /*
-  * Lookup is used to find objects in the fs
-  */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- 
- static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
--				   struct nameidata *n)
-+				struct nameidata *n)
- #else
- static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
- #endif
-@@ -383,12 +448,11 @@ static struct dentry *yaffs_lookup(struc
- 	yaffs_GrossLock(dev);
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_lookup for %d:%s\n",
--	   yaffs_InodeToObject(dir)->objectId, dentry->d_name.name));
-+		("yaffs_lookup for %d:%s\n",
-+		yaffs_InodeToObject(dir)->objectId, dentry->d_name.name));
- 
--	obj =
--	    yaffs_FindObjectByName(yaffs_InodeToObject(dir),
--				   dentry->d_name.name);
-+	obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),
-+					dentry->d_name.name);
- 
- 	obj = yaffs_GetEquivalentObject(obj);	/* in case it was a hardlink */
- 
-@@ -397,13 +461,13 @@ static struct dentry *yaffs_lookup(struc
- 
- 	if (obj) {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_lookup found %d\n", obj->objectId));
-+			("yaffs_lookup found %d\n", obj->objectId));
- 
- 		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
- 
- 		if (inode) {
- 			T(YAFFS_TRACE_OS,
--			  (KERN_DEBUG "yaffs_loookup dentry \n"));
-+				("yaffs_loookup dentry \n"));
- /* #if 0 asserted by NCB for 2.5/6 compatability - falls through to
-  * d_add even if NULL inode */
- #if 0
-@@ -416,7 +480,7 @@ static struct dentry *yaffs_lookup(struc
- 		}
- 
- 	} else {
--		T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_lookup not found\n"));
-+		T(YAFFS_TRACE_OS, ("yaffs_lookup not found\n"));
- 
- 	}
- 
-@@ -425,20 +489,22 @@ static struct dentry *yaffs_lookup(struc
- 	d_add(dentry, inode);
- 
- 	return NULL;
--	/*      return (ERR_PTR(-EIO)); */
--
- }
- 
-+
-+#ifdef YAFFS_HAS_PUT_INODE
-+
- /* For now put inode is just for debugging
-  * Put inode is called when the inode **structure** is put.
-  */
- static void yaffs_put_inode(struct inode *inode)
- {
- 	T(YAFFS_TRACE_OS,
--	  ("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino,
--	   atomic_read(&inode->i_count)));
-+		("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino,
-+		atomic_read(&inode->i_count)));
- 
- }
-+#endif
- 
- /* clear is called to tell the fs to release any per-inode data it holds */
- static void yaffs_clear_inode(struct inode *inode)
-@@ -449,9 +515,9 @@ static void yaffs_clear_inode(struct ino
- 	obj = yaffs_InodeToObject(inode);
- 
- 	T(YAFFS_TRACE_OS,
--	  ("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino,
--	   atomic_read(&inode->i_count),
--	   obj ? "object exists" : "null object"));
-+		("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino,
-+		atomic_read(&inode->i_count),
-+		obj ? "object exists" : "null object"));
- 
- 	if (obj) {
- 		dev = obj->myDev;
-@@ -486,23 +552,23 @@ static void yaffs_delete_inode(struct in
- 	yaffs_Device *dev;
- 
- 	T(YAFFS_TRACE_OS,
--	  ("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino,
--	   atomic_read(&inode->i_count),
--	   obj ? "object exists" : "null object"));
-+		("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino,
-+		atomic_read(&inode->i_count),
-+		obj ? "object exists" : "null object"));
- 
- 	if (obj) {
- 		dev = obj->myDev;
- 		yaffs_GrossLock(dev);
--		yaffs_DeleteFile(obj);
-+		yaffs_DeleteObject(obj);
- 		yaffs_GrossUnlock(dev);
- 	}
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
--        truncate_inode_pages (&inode->i_data, 0);
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
-+	truncate_inode_pages(&inode->i_data, 0);
- #endif
- 	clear_inode(inode);
- }
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static int yaffs_file_flush(struct file *file, fl_owner_t id)
- #else
- static int yaffs_file_flush(struct file *file)
-@@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file
- 	yaffs_Device *dev = obj->myDev;
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_file_flush object %d (%s)\n", obj->objectId,
--	   obj->dirty ? "dirty" : "clean"));
-+		("yaffs_file_flush object %d (%s)\n", obj->objectId,
-+		obj->dirty ? "dirty" : "clean"));
- 
- 	yaffs_GrossLock(dev);
- 
-@@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct
- 
- 	yaffs_Device *dev;
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage at %08x, size %08x\n",
--			   (unsigned)(pg->index << PAGE_CACHE_SHIFT),
--			   (unsigned)PAGE_CACHE_SIZE));
-+	T(YAFFS_TRACE_OS, ("yaffs_readpage at %08x, size %08x\n",
-+			(unsigned)(pg->index << PAGE_CACHE_SHIFT),
-+			(unsigned)PAGE_CACHE_SIZE));
- 
- 	obj = yaffs_DentryToObject(f->f_dentry);
- 
- 	dev = obj->myDev;
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- 	BUG_ON(!PageLocked(pg));
- #else
- 	if (!PageLocked(pg))
-@@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct
- 
- 	yaffs_GrossLock(dev);
- 
--	ret =
--	    yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT,
--				   PAGE_CACHE_SIZE);
-+	ret = yaffs_ReadDataFromFile(obj, pg_buf,
-+				pg->index << PAGE_CACHE_SHIFT,
-+				PAGE_CACHE_SIZE);
- 
- 	yaffs_GrossUnlock(dev);
- 
-@@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct
- 	flush_dcache_page(pg);
- 	kunmap(pg);
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage done\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_readpage done\n"));
- 	return ret;
- }
- 
-@@ -593,7 +659,7 @@ static int yaffs_readpage(struct file *f
- 
- /* writepage inspired by/stolen from smbfs */
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_writepage(struct page *page, struct writeback_control *wbc)
- #else
- static int yaffs_writepage(struct page *page)
-@@ -616,12 +682,11 @@ static int yaffs_writepage(struct page *
- 
- 	if (offset > inode->i_size) {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG
--		   "yaffs_writepage at %08x, inode size = %08x!!!\n",
--		   (unsigned)(page->index << PAGE_CACHE_SHIFT),
--		   (unsigned)inode->i_size));
-+			("yaffs_writepage at %08x, inode size = %08x!!!\n",
-+			(unsigned)(page->index << PAGE_CACHE_SHIFT),
-+			(unsigned)inode->i_size));
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "                -> don't care!!\n"));
-+			("                -> don't care!!\n"));
- 		unlock_page(page);
- 		return 0;
- 	}
-@@ -629,11 +694,10 @@ static int yaffs_writepage(struct page *
- 	end_index = inode->i_size >> PAGE_CACHE_SHIFT;
- 
- 	/* easy case */
--	if (page->index < end_index) {
-+	if (page->index < end_index)
- 		nBytes = PAGE_CACHE_SIZE;
--	} else {
-+	else
- 		nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1);
--	}
- 
- 	get_page(page);
- 
-@@ -643,19 +707,18 @@ static int yaffs_writepage(struct page *
- 	yaffs_GrossLock(obj->myDev);
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_writepage at %08x, size %08x\n",
--	   (unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes));
-+		("yaffs_writepage at %08x, size %08x\n",
-+		(unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes));
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "writepag0: obj = %05x, ino = %05x\n",
--	   (int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
-+		("writepag0: obj = %05x, ino = %05x\n",
-+		(int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
- 
--	nWritten =
--	    yaffs_WriteDataToFile(obj, buffer, page->index << PAGE_CACHE_SHIFT,
--				  nBytes, 0);
-+	nWritten = yaffs_WriteDataToFile(obj, buffer,
-+			page->index << PAGE_CACHE_SHIFT, nBytes, 0);
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "writepag1: obj = %05x, ino = %05x\n",
--	   (int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
-+		("writepag1: obj = %05x, ino = %05x\n",
-+		(int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
- 
- 	yaffs_GrossUnlock(obj->myDev);
- 
-@@ -667,100 +730,207 @@ static int yaffs_writepage(struct page *
- 	return (nWritten == nBytes) ? 0 : -ENOSPC;
- }
- 
-+
-+#if (YAFFS_USE_WRITE_BEGIN_END > 0)
-+static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
-+				loff_t pos, unsigned len, unsigned flags,
-+				struct page **pagep, void **fsdata)
-+{
-+	struct page *pg = NULL;
-+	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
-+	uint32_t offset = pos & (PAGE_CACHE_SIZE - 1);
-+	uint32_t to = offset + len;
-+
-+	int ret = 0;
-+	int space_held = 0;
-+
-+	T(YAFFS_TRACE_OS, ("start yaffs_write_begin\n"));
-+	/* Get a page */
-+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28)
-+	pg = grab_cache_page_write_begin(mapping, index, flags);
-+#else
-+	pg = __grab_cache_page(mapping, index);
-+#endif
-+
-+	*pagep = pg;
-+	if (!pg) {
-+		ret =  -ENOMEM;
-+		goto out;
-+	}
-+	/* Get fs space */
-+	space_held = yaffs_hold_space(filp);
-+
-+	if (!space_held) {
-+		ret = -ENOSPC;
-+		goto out;
-+	}
-+
-+	/* Update page if required */
-+
-+	if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
-+		ret = yaffs_readpage_nolock(filp, pg);
-+
-+	if (ret)
-+		goto out;
-+
-+	/* Happy path return */
-+	T(YAFFS_TRACE_OS, ("end yaffs_write_begin - ok\n"));
-+
-+	return 0;
-+
-+out:
-+	T(YAFFS_TRACE_OS, ("end yaffs_write_begin fail returning %d\n", ret));
-+	if (space_held)
-+		yaffs_release_space(filp);
-+	if (pg) {
-+		unlock_page(pg);
-+		page_cache_release(pg);
-+	}
-+	return ret;
-+}
-+
-+#else
-+
- static int yaffs_prepare_write(struct file *f, struct page *pg,
--			       unsigned offset, unsigned to)
-+				unsigned offset, unsigned to)
- {
-+	T(YAFFS_TRACE_OS, ("yaffs_prepair_write\n"));
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_prepair_write\n"));
- 	if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
- 		return yaffs_readpage_nolock(f, pg);
--
- 	return 0;
-+}
-+#endif
-+
-+#if (YAFFS_USE_WRITE_BEGIN_END > 0)
-+static int yaffs_write_end(struct file *filp, struct address_space *mapping,
-+				loff_t pos, unsigned len, unsigned copied,
-+				struct page *pg, void *fsdadata)
-+{
-+	int ret = 0;
-+	void *addr, *kva;
-+	uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);
-+
-+	kva = kmap(pg);
-+	addr = kva + offset_into_page;
-+
-+	T(YAFFS_TRACE_OS,
-+		("yaffs_write_end addr %x pos %x nBytes %d\n",
-+		(unsigned) addr,
-+		(int)pos, copied));
-+
-+	ret = yaffs_file_write(filp, addr, copied, &pos);
-+
-+	if (ret != copied) {
-+		T(YAFFS_TRACE_OS,
-+			("yaffs_write_end not same size ret %d  copied %d\n",
-+			ret, copied));
-+		SetPageError(pg);
-+		ClearPageUptodate(pg);
-+	} else {
-+		SetPageUptodate(pg);
-+	}
-+
-+	kunmap(pg);
- 
-+	yaffs_release_space(filp);
-+	unlock_page(pg);
-+	page_cache_release(pg);
-+	return ret;
- }
-+#else
- 
- static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
--			      unsigned to)
-+				unsigned to)
- {
-+	void *addr, *kva;
- 
--	void *addr = page_address(pg) + offset;
- 	loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;
- 	int nBytes = to - offset;
- 	int nWritten;
- 
- 	unsigned spos = pos;
--	unsigned saddr = (unsigned)addr;
-+	unsigned saddr;
-+
-+	kva = kmap(pg);
-+	addr = kva + offset;
-+
-+	saddr = (unsigned) addr;
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_commit_write addr %x pos %x nBytes %d\n", saddr,
--	   spos, nBytes));
-+		("yaffs_commit_write addr %x pos %x nBytes %d\n",
-+		saddr, spos, nBytes));
- 
- 	nWritten = yaffs_file_write(f, addr, nBytes, &pos);
- 
- 	if (nWritten != nBytes) {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG
--		   "yaffs_commit_write not same size nWritten %d  nBytes %d\n",
--		   nWritten, nBytes));
-+			("yaffs_commit_write not same size nWritten %d  nBytes %d\n",
-+			nWritten, nBytes));
- 		SetPageError(pg);
- 		ClearPageUptodate(pg);
- 	} else {
- 		SetPageUptodate(pg);
- 	}
- 
-+	kunmap(pg);
-+
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_commit_write returning %d\n",
--	   nWritten == nBytes ? 0 : nWritten));
-+		("yaffs_commit_write returning %d\n",
-+		nWritten == nBytes ? 0 : nWritten));
- 
- 	return nWritten == nBytes ? 0 : nWritten;
--
- }
-+#endif
-+
- 
--static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj)
-+static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
- {
- 	if (inode && obj) {
- 
- 
- 		/* Check mode against the variant type and attempt to repair if broken. */
-- 		__u32 mode = obj->yst_mode;
-- 		switch( obj->variantType ){
-- 		case YAFFS_OBJECT_TYPE_FILE :
-- 		        if( ! S_ISREG(mode) ){
-- 			        obj->yst_mode &= ~S_IFMT;
-- 			        obj->yst_mode |= S_IFREG;
-- 			}
--
-- 			break;
-- 		case YAFFS_OBJECT_TYPE_SYMLINK :
-- 		        if( ! S_ISLNK(mode) ){
-- 			        obj->yst_mode &= ~S_IFMT;
-- 				obj->yst_mode |= S_IFLNK;
-- 			}
--
-- 			break;
-- 		case YAFFS_OBJECT_TYPE_DIRECTORY :
-- 		        if( ! S_ISDIR(mode) ){
-- 			        obj->yst_mode &= ~S_IFMT;
-- 			        obj->yst_mode |= S_IFDIR;
-- 			}
--
-- 			break;
-- 		case YAFFS_OBJECT_TYPE_UNKNOWN :
-- 		case YAFFS_OBJECT_TYPE_HARDLINK :
-- 		case YAFFS_OBJECT_TYPE_SPECIAL :
-- 		default:
-- 		        /* TODO? */
-- 		        break;
-- 		}
-+		__u32 mode = obj->yst_mode;
-+		switch (obj->variantType) {
-+		case YAFFS_OBJECT_TYPE_FILE:
-+			if (!S_ISREG(mode)) {
-+				obj->yst_mode &= ~S_IFMT;
-+				obj->yst_mode |= S_IFREG;
-+			}
-+
-+			break;
-+		case YAFFS_OBJECT_TYPE_SYMLINK:
-+			if (!S_ISLNK(mode)) {
-+				obj->yst_mode &= ~S_IFMT;
-+				obj->yst_mode |= S_IFLNK;
-+			}
-+
-+			break;
-+		case YAFFS_OBJECT_TYPE_DIRECTORY:
-+			if (!S_ISDIR(mode)) {
-+				obj->yst_mode &= ~S_IFMT;
-+				obj->yst_mode |= S_IFDIR;
-+			}
-+
-+			break;
-+		case YAFFS_OBJECT_TYPE_UNKNOWN:
-+		case YAFFS_OBJECT_TYPE_HARDLINK:
-+		case YAFFS_OBJECT_TYPE_SPECIAL:
-+		default:
-+			/* TODO? */
-+			break;
-+		}
-+
-+		inode->i_flags |= S_NOATIME;
- 
- 		inode->i_ino = obj->objectId;
- 		inode->i_mode = obj->yst_mode;
- 		inode->i_uid = obj->yst_uid;
- 		inode->i_gid = obj->yst_gid;
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
- 		inode->i_blksize = inode->i_sb->s_blocksize;
- #endif
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- 
- 		inode->i_rdev = old_decode_dev(obj->yst_rdev);
- 		inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
-@@ -781,26 +951,25 @@ static void yaffs_FillInodeFromObject(st
- 		inode->i_nlink = yaffs_GetObjectLinkCount(obj);
- 
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG
--		   "yaffs_FillInode mode %x uid %d gid %d size %d count %d\n",
--		   inode->i_mode, inode->i_uid, inode->i_gid,
--		   (int)inode->i_size, atomic_read(&inode->i_count)));
-+			("yaffs_FillInode mode %x uid %d gid %d size %d count %d\n",
-+			inode->i_mode, inode->i_uid, inode->i_gid,
-+			(int)inode->i_size, atomic_read(&inode->i_count)));
- 
- 		switch (obj->yst_mode & S_IFMT) {
- 		default:	/* fifo, device or socket */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- 			init_special_inode(inode, obj->yst_mode,
--					   old_decode_dev(obj->yst_rdev));
-+					old_decode_dev(obj->yst_rdev));
- #else
- 			init_special_inode(inode, obj->yst_mode,
--					   (dev_t) (obj->yst_rdev));
-+					(dev_t) (obj->yst_rdev));
- #endif
- 			break;
- 		case S_IFREG:	/* file */
- 			inode->i_op = &yaffs_file_inode_operations;
- 			inode->i_fop = &yaffs_file_operations;
- 			inode->i_mapping->a_ops =
--			    &yaffs_file_address_operations;
-+				&yaffs_file_address_operations;
- 			break;
- 		case S_IFDIR:	/* directory */
- 			inode->i_op = &yaffs_dir_inode_operations;
-@@ -817,34 +986,36 @@ static void yaffs_FillInodeFromObject(st
- 
- 	} else {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_FileInode invalid parameters\n"));
-+			("yaffs_FileInode invalid parameters\n"));
- 	}
- 
- }
- 
- struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
--			      yaffs_Object * obj)
-+				yaffs_Object *obj)
- {
- 	struct inode *inode;
- 
- 	if (!sb) {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_get_inode for NULL super_block!!\n"));
-+			("yaffs_get_inode for NULL super_block!!\n"));
- 		return NULL;
- 
- 	}
- 
- 	if (!obj) {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_get_inode for NULL object!!\n"));
-+			("yaffs_get_inode for NULL object!!\n"));
- 		return NULL;
- 
- 	}
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId));
-+		("yaffs_get_inode for object %d\n", obj->objectId));
- 
--	inode = iget(sb, obj->objectId);
-+	inode = Y_IGET(sb, obj->objectId);
-+	if (IS_ERR(inode))
-+		return NULL;
- 
- 	/* NB Side effect: iget calls back to yaffs_read_inode(). */
- 	/* iget also increments the inode's i_count */
-@@ -854,7 +1025,7 @@ struct inode *yaffs_get_inode(struct sup
- }
- 
- static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
--				loff_t * pos)
-+				loff_t *pos)
- {
- 	yaffs_Object *obj;
- 	int nWritten, ipos;
-@@ -869,28 +1040,26 @@ static ssize_t yaffs_file_write(struct f
- 
- 	inode = f->f_dentry->d_inode;
- 
--	if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) {
-+	if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
- 		ipos = inode->i_size;
--	} else {
-+	else
- 		ipos = *pos;
--	}
- 
--	if (!obj) {
-+	if (!obj)
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_file_write: hey obj is null!\n"));
--	} else {
-+			("yaffs_file_write: hey obj is null!\n"));
-+	else
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG
--		   "yaffs_file_write about to write writing %d bytes"
--		   "to object %d at %d\n",
--		   n, obj->objectId, ipos));
--	}
-+			("yaffs_file_write about to write writing %zu bytes"
-+			"to object %d at %d\n",
-+			n, obj->objectId, ipos));
- 
- 	nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0);
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_file_write writing %d bytes, %d written at %d\n",
--	   n, nWritten, ipos));
-+		("yaffs_file_write writing %zu bytes, %d written at %d\n",
-+		n, nWritten, ipos));
-+
- 	if (nWritten > 0) {
- 		ipos += nWritten;
- 		*pos = ipos;
-@@ -899,10 +1068,9 @@ static ssize_t yaffs_file_write(struct f
- 			inode->i_blocks = (ipos + 511) >> 9;
- 
- 			T(YAFFS_TRACE_OS,
--			  (KERN_DEBUG
--			   "yaffs_file_write size updated to %d bytes, "
--			   "%d blocks\n",
--			   ipos, (int)(inode->i_blocks)));
-+				("yaffs_file_write size updated to %d bytes, "
-+				"%d blocks\n",
-+				ipos, (int)(inode->i_blocks)));
- 		}
- 
- 	}
-@@ -910,13 +1078,54 @@ static ssize_t yaffs_file_write(struct f
- 	return nWritten == 0 ? -ENOSPC : nWritten;
- }
- 
-+/* Space holding and freeing is done to ensure we have space available for write_begin/end */
-+/* For now we just assume few parallel writes and check against a small number. */
-+/* Todo: need to do this with a counter to handle parallel reads better */
-+
-+static ssize_t yaffs_hold_space(struct file *f)
-+{
-+	yaffs_Object *obj;
-+	yaffs_Device *dev;
-+
-+	int nFreeChunks;
-+
-+
-+	obj = yaffs_DentryToObject(f->f_dentry);
-+
-+	dev = obj->myDev;
-+
-+	yaffs_GrossLock(dev);
-+
-+	nFreeChunks = yaffs_GetNumberOfFreeChunks(dev);
-+
-+	yaffs_GrossUnlock(dev);
-+
-+	return (nFreeChunks > 20) ? 1 : 0;
-+}
-+
-+static void yaffs_release_space(struct file *f)
-+{
-+	yaffs_Object *obj;
-+	yaffs_Device *dev;
-+
-+
-+	obj = yaffs_DentryToObject(f->f_dentry);
-+
-+	dev = obj->myDev;
-+
-+	yaffs_GrossLock(dev);
-+
-+
-+	yaffs_GrossUnlock(dev);
-+}
-+
- static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
- {
- 	yaffs_Object *obj;
- 	yaffs_Device *dev;
- 	struct inode *inode = f->f_dentry->d_inode;
- 	unsigned long offset, curoffs;
--	struct list_head *i;
-+	struct ylist_head *i;
- 	yaffs_Object *l;
- 
- 	char name[YAFFS_MAX_NAME_LENGTH + 1];
-@@ -932,24 +1141,20 @@ static int yaffs_readdir(struct file *f,
- 
- 	if (offset == 0) {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_readdir: entry . ino %d \n",
--		   (int)inode->i_ino));
--		if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR)
--		    < 0) {
-+			("yaffs_readdir: entry . ino %d \n",
-+			(int)inode->i_ino));
-+		if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0)
- 			goto out;
--		}
- 		offset++;
- 		f->f_pos++;
- 	}
- 	if (offset == 1) {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_readdir: entry .. ino %d \n",
--		   (int)f->f_dentry->d_parent->d_inode->i_ino));
--		if (filldir
--		    (dirent, "..", 2, offset,
--		     f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
-+			("yaffs_readdir: entry .. ino %d \n",
-+			(int)f->f_dentry->d_parent->d_inode->i_ino));
-+		if (filldir(dirent, "..", 2, offset,
-+			f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
- 			goto out;
--		}
- 		offset++;
- 		f->f_pos++;
- 	}
-@@ -965,35 +1170,32 @@ static int yaffs_readdir(struct file *f,
- 		f->f_version = inode->i_version;
- 	}
- 
--	list_for_each(i, &obj->variant.directoryVariant.children) {
-+	ylist_for_each(i, &obj->variant.directoryVariant.children) {
- 		curoffs++;
- 		if (curoffs >= offset) {
--			l = list_entry(i, yaffs_Object, siblings);
-+			l = ylist_entry(i, yaffs_Object, siblings);
- 
- 			yaffs_GetObjectName(l, name,
- 					    YAFFS_MAX_NAME_LENGTH + 1);
- 			T(YAFFS_TRACE_OS,
--			  (KERN_DEBUG "yaffs_readdir: %s inode %d\n", name,
-+			  ("yaffs_readdir: %s inode %d\n", name,
- 			   yaffs_GetObjectInode(l)));
- 
- 			if (filldir(dirent,
--				    name,
--				    strlen(name),
--				    offset,
--				    yaffs_GetObjectInode(l),
--				    yaffs_GetObjectType(l))
--			    < 0) {
-+					name,
-+					strlen(name),
-+					offset,
-+					yaffs_GetObjectInode(l),
-+					yaffs_GetObjectType(l)) < 0)
- 				goto up_and_out;
--			}
- 
- 			offset++;
- 			f->f_pos++;
- 		}
- 	}
- 
--      up_and_out:
--      out:
--
-+up_and_out:
-+out:
- 	yaffs_GrossUnlock(dev);
- 
- 	return 0;
-@@ -1002,12 +1204,19 @@ static int yaffs_readdir(struct file *f,
- /*
-  * File creation. Allocate an inode, and we're done..
-  */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
-+#define YCRED(x) x
-+#else
-+#define YCRED(x) (x->cred)
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
--		       dev_t rdev)
-+			dev_t rdev)
- #else
- static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
--		       int rdev)
-+			int rdev)
- #endif
- {
- 	struct inode *inode;
-@@ -1018,25 +1227,25 @@ static int yaffs_mknod(struct inode *dir
- 	yaffs_Object *parent = yaffs_InodeToObject(dir);
- 
- 	int error = -ENOSPC;
--	uid_t uid = current->fsuid;
--	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-+	uid_t uid = YCRED(current)->fsuid;
-+	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
- 
--	if((dir->i_mode & S_ISGID) && S_ISDIR(mode))
-+	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
- 		mode |= S_ISGID;
- 
- 	if (parent) {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_mknod: parent object %d type %d\n",
--		   parent->objectId, parent->variantType));
-+			("yaffs_mknod: parent object %d type %d\n",
-+			parent->objectId, parent->variantType));
- 	} else {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_mknod: could not get parent object\n"));
-+			("yaffs_mknod: could not get parent object\n"));
- 		return -EPERM;
- 	}
- 
- 	T(YAFFS_TRACE_OS, ("yaffs_mknod: making oject for %s, "
--			   "mode %x dev %x\n",
--			   dentry->d_name.name, mode, rdev));
-+			"mode %x dev %x\n",
-+			dentry->d_name.name, mode, rdev));
- 
- 	dev = parent->myDev;
- 
-@@ -1045,33 +1254,28 @@ static int yaffs_mknod(struct inode *dir
- 	switch (mode & S_IFMT) {
- 	default:
- 		/* Special (socket, fifo, device...) */
--		T(YAFFS_TRACE_OS, (KERN_DEBUG
--				   "yaffs_mknod: making special\n"));
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
--		obj =
--		    yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
--				       gid, old_encode_dev(rdev));
--#else
--		obj =
--		    yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
--				       gid, rdev);
-+		T(YAFFS_TRACE_OS, ("yaffs_mknod: making special\n"));
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+		obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
-+				gid, old_encode_dev(rdev));
-+#else
-+		obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
-+				gid, rdev);
- #endif
- 		break;
- 	case S_IFREG:		/* file          */
--		T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n"));
--		obj =
--		    yaffs_MknodFile(parent, dentry->d_name.name, mode, uid,
--				    gid);
-+		T(YAFFS_TRACE_OS, ("yaffs_mknod: making file\n"));
-+		obj = yaffs_MknodFile(parent, dentry->d_name.name, mode, uid,
-+				gid);
- 		break;
- 	case S_IFDIR:		/* directory */
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_mknod: making directory\n"));
--		obj =
--		    yaffs_MknodDirectory(parent, dentry->d_name.name, mode,
--					 uid, gid);
-+			("yaffs_mknod: making directory\n"));
-+		obj = yaffs_MknodDirectory(parent, dentry->d_name.name, mode,
-+					uid, gid);
- 		break;
- 	case S_IFLNK:		/* symlink */
--		T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n"));
-+		T(YAFFS_TRACE_OS, ("yaffs_mknod: making symlink\n"));
- 		obj = NULL;	/* Do we ever get here? */
- 		break;
- 	}
-@@ -1083,12 +1287,12 @@ static int yaffs_mknod(struct inode *dir
- 		inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
- 		d_instantiate(dentry, inode);
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_mknod created object %d count = %d\n",
--		   obj->objectId, atomic_read(&inode->i_count)));
-+			("yaffs_mknod created object %d count = %d\n",
-+			obj->objectId, atomic_read(&inode->i_count)));
- 		error = 0;
- 	} else {
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_mknod failed making object\n"));
-+			("yaffs_mknod failed making object\n"));
- 		error = -ENOMEM;
- 	}
- 
-@@ -1098,25 +1302,19 @@ static int yaffs_mknod(struct inode *dir
- static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
- {
- 	int retVal;
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mkdir\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_mkdir\n"));
- 	retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
--#if 0
--	/* attempt to fix dir bug - didn't work */
--	if (!retVal) {
--		dget(dentry);
--	}
--#endif
- 	return retVal;
- }
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
- 			struct nameidata *n)
- #else
- static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
- #endif
- {
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_create\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_create\n"));
- 	return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
- }
- 
-@@ -1127,8 +1325,8 @@ static int yaffs_unlink(struct inode *di
- 	yaffs_Device *dev;
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_unlink %d:%s\n", (int)(dir->i_ino),
--	   dentry->d_name.name));
-+		("yaffs_unlink %d:%s\n", (int)(dir->i_ino),
-+		dentry->d_name.name));
- 
- 	dev = yaffs_InodeToObject(dir)->myDev;
- 
-@@ -1151,82 +1349,74 @@ static int yaffs_unlink(struct inode *di
-  * Create a link...
-  */
- static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
--		      struct dentry *dentry)
-+			struct dentry *dentry)
- {
- 	struct inode *inode = old_dentry->d_inode;
- 	yaffs_Object *obj = NULL;
- 	yaffs_Object *link = NULL;
- 	yaffs_Device *dev;
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_link\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_link\n"));
- 
- 	obj = yaffs_InodeToObject(inode);
- 	dev = obj->myDev;
- 
- 	yaffs_GrossLock(dev);
- 
--	if (!S_ISDIR(inode->i_mode))	/* Don't link directories */
--	{
--		link =
--		    yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name,
--			       obj);
--	}
-+	if (!S_ISDIR(inode->i_mode))		/* Don't link directories */
-+		link = yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name,
-+			obj);
- 
- 	if (link) {
- 		old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj);
- 		d_instantiate(dentry, old_dentry->d_inode);
- 		atomic_inc(&old_dentry->d_inode->i_count);
- 		T(YAFFS_TRACE_OS,
--		  (KERN_DEBUG "yaffs_link link count %d i_count %d\n",
--		   old_dentry->d_inode->i_nlink,
--		   atomic_read(&old_dentry->d_inode->i_count)));
--
-+			("yaffs_link link count %d i_count %d\n",
-+			old_dentry->d_inode->i_nlink,
-+			atomic_read(&old_dentry->d_inode->i_count)));
- 	}
- 
- 	yaffs_GrossUnlock(dev);
- 
--	if (link) {
--
-+	if (link)
- 		return 0;
--	}
- 
- 	return -EPERM;
- }
- 
- static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
--			 const char *symname)
-+				const char *symname)
- {
- 	yaffs_Object *obj;
- 	yaffs_Device *dev;
--	uid_t uid = current->fsuid;
--	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-+	uid_t uid = YCRED(current)->fsuid;
-+	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_symlink\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_symlink\n"));
- 
- 	dev = yaffs_InodeToObject(dir)->myDev;
- 	yaffs_GrossLock(dev);
- 	obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name,
--				 S_IFLNK | S_IRWXUGO, uid, gid, symname);
-+				S_IFLNK | S_IRWXUGO, uid, gid, symname);
- 	yaffs_GrossUnlock(dev);
- 
- 	if (obj) {
--
- 		struct inode *inode;
- 
- 		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
- 		d_instantiate(dentry, inode);
--		T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink created OK\n"));
-+		T(YAFFS_TRACE_OS, ("symlink created OK\n"));
- 		return 0;
- 	} else {
--		T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink not created\n"));
--
-+		T(YAFFS_TRACE_OS, ("symlink not created\n"));
- 	}
- 
- 	return -ENOMEM;
- }
- 
- static int yaffs_sync_object(struct file *file, struct dentry *dentry,
--			     int datasync)
-+				int datasync)
- {
- 
- 	yaffs_Object *obj;
-@@ -1236,7 +1426,7 @@ static int yaffs_sync_object(struct file
- 
- 	dev = obj->myDev;
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_object\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_sync_object\n"));
- 	yaffs_GrossLock(dev);
- 	yaffs_FlushFile(obj, 1);
- 	yaffs_GrossUnlock(dev);
-@@ -1255,41 +1445,36 @@ static int yaffs_rename(struct inode *ol
- 	int retVal = YAFFS_FAIL;
- 	yaffs_Object *target;
- 
--        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_rename\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_rename\n"));
- 	dev = yaffs_InodeToObject(old_dir)->myDev;
- 
- 	yaffs_GrossLock(dev);
- 
- 	/* Check if the target is an existing directory that is not empty. */
--	target =
--	    yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),
--				   new_dentry->d_name.name);
-+	target = yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),
-+				new_dentry->d_name.name);
- 
- 
- 
--	if (target &&
--	    target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
--	    !list_empty(&target->variant.directoryVariant.children)) {
-+	if (target && target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
-+		!ylist_empty(&target->variant.directoryVariant.children)) {
- 
--	        T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n"));
-+		T(YAFFS_TRACE_OS, ("target is non-empty dir\n"));
- 
- 		retVal = YAFFS_FAIL;
- 	} else {
--
- 		/* Now does unlinking internally using shadowing mechanism */
--	        T(YAFFS_TRACE_OS, (KERN_DEBUG "calling yaffs_RenameObject\n"));
--
--		retVal =
--		    yaffs_RenameObject(yaffs_InodeToObject(old_dir),
--				       old_dentry->d_name.name,
--				       yaffs_InodeToObject(new_dir),
--				       new_dentry->d_name.name);
-+		T(YAFFS_TRACE_OS, ("calling yaffs_RenameObject\n"));
- 
-+		retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),
-+				old_dentry->d_name.name,
-+				yaffs_InodeToObject(new_dir),
-+				new_dentry->d_name.name);
- 	}
- 	yaffs_GrossUnlock(dev);
- 
- 	if (retVal == YAFFS_OK) {
--		if(target) {
-+		if (target) {
- 			new_dentry->d_inode->i_nlink--;
- 			mark_inode_dirty(new_dentry->d_inode);
- 		}
-@@ -1298,7 +1483,6 @@ static int yaffs_rename(struct inode *ol
- 	} else {
- 		return -ENOTEMPTY;
- 	}
--
- }
- 
- static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
-@@ -1308,15 +1492,15 @@ static int yaffs_setattr(struct dentry *
- 	yaffs_Device *dev;
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_setattr of object %d\n",
--	   yaffs_InodeToObject(inode)->objectId));
--
--	if ((error = inode_change_ok(inode, attr)) == 0) {
-+		("yaffs_setattr of object %d\n",
-+		yaffs_InodeToObject(inode)->objectId));
- 
-+	error = inode_change_ok(inode, attr);
-+	if (error == 0) {
- 		dev = yaffs_InodeToObject(inode)->myDev;
- 		yaffs_GrossLock(dev);
- 		if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) ==
--		    YAFFS_OK) {
-+				YAFFS_OK) {
- 			error = 0;
- 		} else {
- 			error = -EPERM;
-@@ -1328,12 +1512,12 @@ static int yaffs_setattr(struct dentry *
- 	return error;
- }
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
- {
- 	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
- 	struct super_block *sb = dentry->d_sb;
--#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
- {
- 	yaffs_Device *dev = yaffs_SuperToDevice(sb);
-@@ -1343,32 +1527,53 @@ static int yaffs_statfs(struct super_blo
- 	yaffs_Device *dev = yaffs_SuperToDevice(sb);
- #endif
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_statfs\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_statfs\n"));
- 
- 	yaffs_GrossLock(dev);
- 
- 	buf->f_type = YAFFS_MAGIC;
- 	buf->f_bsize = sb->s_blocksize;
- 	buf->f_namelen = 255;
--	if (sb->s_blocksize > dev->nDataBytesPerChunk) {
-+
-+	if (dev->nDataBytesPerChunk & (dev->nDataBytesPerChunk - 1)) {
-+		/* Do this if chunk size is not a power of 2 */
-+
-+		uint64_t bytesInDev;
-+		uint64_t bytesFree;
-+
-+		bytesInDev = ((uint64_t)((dev->endBlock - dev->startBlock + 1))) *
-+			((uint64_t)(dev->nChunksPerBlock * dev->nDataBytesPerChunk));
-+
-+		do_div(bytesInDev, sb->s_blocksize); /* bytesInDev becomes the number of blocks */
-+		buf->f_blocks = bytesInDev;
-+
-+		bytesFree  = ((uint64_t)(yaffs_GetNumberOfFreeChunks(dev))) *
-+			((uint64_t)(dev->nDataBytesPerChunk));
-+
-+		do_div(bytesFree, sb->s_blocksize);
-+
-+		buf->f_bfree = bytesFree;
-+
-+	} else if (sb->s_blocksize > dev->nDataBytesPerChunk) {
- 
- 		buf->f_blocks =
--		    (dev->endBlock - dev->startBlock +
--		     1) * dev->nChunksPerBlock / (sb->s_blocksize /
--						  dev->nDataBytesPerChunk);
-+			(dev->endBlock - dev->startBlock + 1) *
-+			dev->nChunksPerBlock /
-+			(sb->s_blocksize / dev->nDataBytesPerChunk);
- 		buf->f_bfree =
--		    yaffs_GetNumberOfFreeChunks(dev) / (sb->s_blocksize /
--							dev->nDataBytesPerChunk);
-+			yaffs_GetNumberOfFreeChunks(dev) /
-+			(sb->s_blocksize / dev->nDataBytesPerChunk);
- 	} else {
--
- 		buf->f_blocks =
--		    (dev->endBlock - dev->startBlock +
--		     1) * dev->nChunksPerBlock * (dev->nDataBytesPerChunk /
--						  sb->s_blocksize);
-+			(dev->endBlock - dev->startBlock + 1) *
-+			dev->nChunksPerBlock *
-+			(dev->nDataBytesPerChunk / sb->s_blocksize);
-+
- 		buf->f_bfree =
--		    yaffs_GetNumberOfFreeChunks(dev) * (dev->nDataBytesPerChunk /
--							sb->s_blocksize);
-+			yaffs_GetNumberOfFreeChunks(dev) *
-+			(dev->nDataBytesPerChunk / sb->s_blocksize);
- 	}
-+
- 	buf->f_files = 0;
- 	buf->f_ffree = 0;
- 	buf->f_bavail = buf->f_bfree;
-@@ -1378,18 +1583,19 @@ static int yaffs_statfs(struct super_blo
- }
- 
- 
--/**
- static int yaffs_do_sync_fs(struct super_block *sb)
- {
- 
- 	yaffs_Device *dev = yaffs_SuperToDevice(sb);
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_do_sync_fs\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_do_sync_fs\n"));
- 
--	if(sb->s_dirt) {
-+	if (sb->s_dirt) {
- 		yaffs_GrossLock(dev);
- 
--		if(dev)
-+		if (dev) {
-+			yaffs_FlushEntireDeviceCache(dev);
- 			yaffs_CheckpointSave(dev);
-+		}
- 
- 		yaffs_GrossUnlock(dev);
- 
-@@ -1397,35 +1603,73 @@ static int yaffs_do_sync_fs(struct super
- 	}
- 	return 0;
- }
--**/
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static void yaffs_write_super(struct super_block *sb)
- #else
- static int yaffs_write_super(struct super_block *sb)
- #endif
- {
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n"));
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
--	return 0; /* yaffs_do_sync_fs(sb);*/
-+	T(YAFFS_TRACE_OS, ("yaffs_write_super\n"));
-+	if (yaffs_auto_checkpoint >= 2)
-+		yaffs_do_sync_fs(sb);
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
-+	return 0;
- #endif
- }
- 
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static int yaffs_sync_fs(struct super_block *sb, int wait)
- #else
- static int yaffs_sync_fs(struct super_block *sb)
- #endif
- {
-+	T(YAFFS_TRACE_OS, ("yaffs_sync_fs\n"));
-+
-+	if (yaffs_auto_checkpoint >= 1)
-+		yaffs_do_sync_fs(sb);
-+
-+	return 0;
-+}
-+
-+#ifdef YAFFS_USE_OWN_IGET
-+
-+static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino)
-+{
-+	struct inode *inode;
-+	yaffs_Object *obj;
-+	yaffs_Device *dev = yaffs_SuperToDevice(sb);
-+
-+	T(YAFFS_TRACE_OS,
-+		("yaffs_iget for %lu\n", ino));
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n"));
-+	inode = iget_locked(sb, ino);
-+	if (!inode)
-+		return ERR_PTR(-ENOMEM);
-+	if (!(inode->i_state & I_NEW))
-+		return inode;
-+
-+	/* NB This is called as a side effect of other functions, but
-+	 * we had to release the lock to prevent deadlocks, so
-+	 * need to lock again.
-+	 */
- 
--	return 0; /* yaffs_do_sync_fs(sb);*/
-+	yaffs_GrossLock(dev);
- 
-+	obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
-+
-+	yaffs_FillInodeFromObject(inode, obj);
-+
-+	yaffs_GrossUnlock(dev);
-+
-+	unlock_new_inode(inode);
-+	return inode;
- }
- 
-+#else
- 
- static void yaffs_read_inode(struct inode *inode)
- {
-@@ -1438,7 +1682,7 @@ static void yaffs_read_inode(struct inod
- 	yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb);
- 
- 	T(YAFFS_TRACE_OS,
--	  (KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino));
-+		("yaffs_read_inode for %d\n", (int)inode->i_ino));
- 
- 	yaffs_GrossLock(dev);
- 
-@@ -1449,18 +1693,20 @@ static void yaffs_read_inode(struct inod
- 	yaffs_GrossUnlock(dev);
- }
- 
--static LIST_HEAD(yaffs_dev_list);
-+#endif
-+
-+static YLIST_HEAD(yaffs_dev_list);
- 
--#if 0 // not used
-+#if 0 /* not used */
- static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
- {
- 	yaffs_Device    *dev = yaffs_SuperToDevice(sb);
- 
--	if( *flags & MS_RDONLY ) {
-+	if (*flags & MS_RDONLY) {
- 		struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
- 
- 		T(YAFFS_TRACE_OS,
--			(KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name ));
-+			("yaffs_remount_fs: %s: RO\n", dev->name));
- 
- 		yaffs_GrossLock(dev);
- 
-@@ -1472,10 +1718,9 @@ static int yaffs_remount_fs(struct super
- 			mtd->sync(mtd);
- 
- 		yaffs_GrossUnlock(dev);
--	}
--	else {
-+	} else {
- 		T(YAFFS_TRACE_OS,
--			(KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name ));
-+			("yaffs_remount_fs: %s: RW\n", dev->name));
- 	}
- 
- 	return 0;
-@@ -1486,7 +1731,7 @@ static void yaffs_put_super(struct super
- {
- 	yaffs_Device *dev = yaffs_SuperToDevice(sb);
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n"));
-+	T(YAFFS_TRACE_OS, ("yaffs_put_super\n"));
- 
- 	yaffs_GrossLock(dev);
- 
-@@ -1494,18 +1739,17 @@ static void yaffs_put_super(struct super
- 
- 	yaffs_CheckpointSave(dev);
- 
--	if (dev->putSuperFunc) {
-+	if (dev->putSuperFunc)
- 		dev->putSuperFunc(sb);
--	}
- 
- 	yaffs_Deinitialise(dev);
- 
- 	yaffs_GrossUnlock(dev);
- 
- 	/* we assume this is protected by lock_kernel() in mount/umount */
--	list_del(&dev->devList);
-+	ylist_del(&dev->devList);
- 
--	if(dev->spareBuffer){
-+	if (dev->spareBuffer) {
- 		YFREE(dev->spareBuffer);
- 		dev->spareBuffer = NULL;
- 	}
-@@ -1516,12 +1760,10 @@ static void yaffs_put_super(struct super
- 
- static void yaffs_MTDPutSuper(struct super_block *sb)
- {
--
- 	struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
- 
--	if (mtd->sync) {
-+	if (mtd->sync)
- 		mtd->sync(mtd);
--	}
- 
- 	put_mtd_device(mtd);
- }
-@@ -1531,9 +1773,9 @@ static void yaffs_MarkSuperBlockDirty(vo
- {
- 	struct super_block *sb = (struct super_block *)vsb;
- 
--	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_MarkSuperBlockDirty() sb = %p\n",sb));
--//	if(sb)
--//		sb->s_dirt = 1;
-+	T(YAFFS_TRACE_OS, ("yaffs_MarkSuperBlockDirty() sb = %p\n", sb));
-+	if (sb)
-+		sb->s_dirt = 1;
- }
- 
- typedef struct {
-@@ -1546,48 +1788,48 @@ typedef struct {
- #define MAX_OPT_LEN 20
- static int yaffs_parse_options(yaffs_options *options, const char *options_str)
- {
--	char cur_opt[MAX_OPT_LEN+1];
-+	char cur_opt[MAX_OPT_LEN + 1];
- 	int p;
- 	int error = 0;
- 
- 	/* Parse through the options which is a comma seperated list */
- 
--	while(options_str && *options_str && !error){
--		memset(cur_opt,0,MAX_OPT_LEN+1);
-+	while (options_str && *options_str && !error) {
-+		memset(cur_opt, 0, MAX_OPT_LEN + 1);
- 		p = 0;
- 
--		while(*options_str && *options_str != ','){
--			if(p < MAX_OPT_LEN){
-+		while (*options_str && *options_str != ',') {
-+			if (p < MAX_OPT_LEN) {
- 				cur_opt[p] = *options_str;
- 				p++;
- 			}
- 			options_str++;
- 		}
- 
--		if(!strcmp(cur_opt,"inband-tags"))
-+		if (!strcmp(cur_opt, "inband-tags"))
- 			options->inband_tags = 1;
--		else if(!strcmp(cur_opt,"no-cache"))
-+		else if (!strcmp(cur_opt, "no-cache"))
- 			options->no_cache = 1;
--		else if(!strcmp(cur_opt,"no-checkpoint-read"))
-+		else if (!strcmp(cur_opt, "no-checkpoint-read"))
- 			options->skip_checkpoint_read = 1;
--		else if(!strcmp(cur_opt,"no-checkpoint-write"))
-+		else if (!strcmp(cur_opt, "no-checkpoint-write"))
- 			options->skip_checkpoint_write = 1;
--		else if(!strcmp(cur_opt,"no-checkpoint")){
-+		else if (!strcmp(cur_opt, "no-checkpoint")) {
- 			options->skip_checkpoint_read = 1;
- 			options->skip_checkpoint_write = 1;
- 		} else {
--			printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",cur_opt);
-+			printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
-+					cur_opt);
- 			error = 1;
- 		}
--
- 	}
- 
- 	return error;
- }
- 
- static struct super_block *yaffs_internal_read_super(int yaffsVersion,
--						     struct super_block *sb,
--						     void *data, int silent)
-+						struct super_block *sb,
-+						void *data, int silent)
- {
- 	int nBlocks;
- 	struct inode *inode = NULL;
-@@ -1602,6 +1844,7 @@ static struct super_block *yaffs_interna
- 
- 	sb->s_magic = YAFFS_MAGIC;
- 	sb->s_op = &yaffs_super_ops;
-+	sb->s_flags |= MS_NOATIME;
- 
- 	if (!sb)
- 		printk(KERN_INFO "yaffs: sb is NULL\n");
-@@ -1614,14 +1857,14 @@ static struct super_block *yaffs_interna
- 		       sb->s_dev,
- 		       yaffs_devname(sb, devname_buf));
- 
--	if(!data_str)
-+	if (!data_str)
- 		data_str = "";
- 
--	printk(KERN_INFO "yaffs: passed flags \"%s\"\n",data_str);
-+	printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
- 
--	memset(&options,0,sizeof(options));
-+	memset(&options, 0, sizeof(options));
- 
--	if(yaffs_parse_options(&options,data_str)){
-+	if (yaffs_parse_options(&options, data_str)) {
- 		/* Option parsing failed */
- 		return NULL;
- 	}
-@@ -1645,9 +1888,9 @@ static struct super_block *yaffs_interna
- 			       yaffs_devname(sb, devname_buf)));
- 
- 	/* Check it's an mtd device..... */
--	if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) {
-+	if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR)
- 		return NULL;	/* This isn't an mtd device */
--	}
-+
- 	/* Get the device */
- 	mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
- 	if (!mtd) {
-@@ -1673,29 +1916,23 @@ static struct super_block *yaffs_interna
- 	T(YAFFS_TRACE_OS, (" %s %d\n", WRITE_SIZE_STR, WRITE_SIZE(mtd)));
- 	T(YAFFS_TRACE_OS, (" oobsize %d\n", mtd->oobsize));
- 	T(YAFFS_TRACE_OS, (" erasesize %d\n", mtd->erasesize));
--	T(YAFFS_TRACE_OS, (" size %d\n", mtd->size));
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
-+	T(YAFFS_TRACE_OS, (" size %u\n", mtd->size));
-+#else
-+	T(YAFFS_TRACE_OS, (" size %lld\n", mtd->size));
-+#endif
- 
- #ifdef CONFIG_YAFFS_AUTO_YAFFS2
- 
--	if (yaffsVersion == 1 &&
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
--	    mtd->writesize >= 2048) {
--#else
--	    mtd->oobblock >= 2048) {
--#endif
--	    T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n"));
--	    yaffsVersion = 2;
-+	if (yaffsVersion == 1 && WRITE_SIZE(mtd) >= 2048) {
-+		T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs2\n"));
-+		yaffsVersion = 2;
- 	}
- 
- 	/* Added NCB 26/5/2006 for completeness */
--	if (yaffsVersion == 2 &&
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
--	    mtd->writesize == 512) {
--#else
--	    mtd->oobblock == 512) {
--#endif
--	    T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n"));
--	    yaffsVersion = 1;
-+	if (yaffsVersion == 2 && !options.inband_tags && WRITE_SIZE(mtd) == 512) {
-+		T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs1\n"));
-+		yaffsVersion = 1;
- 	}
- 
- #endif
-@@ -1707,7 +1944,7 @@ static struct super_block *yaffs_interna
- 		    !mtd->block_markbad ||
- 		    !mtd->read ||
- 		    !mtd->write ||
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- 		    !mtd->read_oob || !mtd->write_oob) {
- #else
- 		    !mtd->write_ecc ||
-@@ -1719,12 +1956,9 @@ static struct super_block *yaffs_interna
- 			return NULL;
- 		}
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
--		if (mtd->writesize < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
--#else
--		if (mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
--#endif
--		    mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) {
-+		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
-+		    mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&
-+		    !options.inband_tags) {
- 			T(YAFFS_TRACE_ALWAYS,
- 			  ("yaffs: MTD device does not have the "
- 			   "right page sizes\n"));
-@@ -1735,7 +1969,7 @@ static struct super_block *yaffs_interna
- 		if (!mtd->erase ||
- 		    !mtd->read ||
- 		    !mtd->write ||
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- 		    !mtd->read_oob || !mtd->write_oob) {
- #else
- 		    !mtd->write_ecc ||
-@@ -1761,7 +1995,7 @@ static struct super_block *yaffs_interna
- 	 * Set the yaffs_Device up for mtd
- 	 */
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- 	sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
- #else
- 	sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
-@@ -1780,13 +2014,15 @@ static struct super_block *yaffs_interna
- 
- 	/* Set up the memory size parameters.... */
- 
--	nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
-+	nBlocks = YCALCBLOCKS(mtd->size, (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK));
-+
- 	dev->startBlock = 0;
- 	dev->endBlock = nBlocks - 1;
- 	dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
--	dev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
-+	dev->totalBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
- 	dev->nReservedBlocks = 5;
- 	dev->nShortOpCaches = (options.no_cache) ? 0 : 10;
-+	dev->inbandTags = options.inband_tags;
- 
- 	/* ... and the functions. */
- 	if (yaffsVersion == 2) {
-@@ -1798,20 +2034,19 @@ static struct super_block *yaffs_interna
- 		dev->queryNANDBlock = nandmtd2_QueryNANDBlock;
- 		dev->spareBuffer = YMALLOC(mtd->oobsize);
- 		dev->isYaffs2 = 1;
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
--		dev->nDataBytesPerChunk = mtd->writesize;
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+		dev->totalBytesPerChunk = mtd->writesize;
- 		dev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
- #else
--		dev->nDataBytesPerChunk = mtd->oobblock;
-+		dev->totalBytesPerChunk = mtd->oobblock;
- 		dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
- #endif
--		nBlocks = mtd->size / mtd->erasesize;
-+		nBlocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
- 
--		dev->nCheckpointReservedBlocks = CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS;
- 		dev->startBlock = 0;
- 		dev->endBlock = nBlocks - 1;
- 	} else {
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- 		/* use the MTD interface in yaffs_mtdif1.c */
- 		dev->writeChunkWithTagsToNAND =
- 			nandmtd1_WriteChunkWithTagsToNAND;
-@@ -1847,7 +2082,7 @@ static struct super_block *yaffs_interna
- 	dev->skipCheckpointWrite = options.skip_checkpoint_write;
- 
- 	/* we assume this is protected by lock_kernel() in mount/umount */
--	list_add_tail(&dev->devList, &yaffs_dev_list);
-+	ylist_add_tail(&dev->devList, &yaffs_dev_list);
- 
- 	init_MUTEX(&dev->grossLock);
- 
-@@ -1884,20 +2119,23 @@ static struct super_block *yaffs_interna
- 		return NULL;
- 	}
- 	sb->s_root = root;
-+	sb->s_dirt = !dev->isCheckpointed;
-+	T(YAFFS_TRACE_ALWAYS,
-+	  ("yaffs_read_super: isCheckpointed %d\n", dev->isCheckpointed));
- 
- 	T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n"));
- 	return sb;
- }
- 
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
- 					 int silent)
- {
- 	return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
- }
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static int yaffs_read_super(struct file_system_type *fs,
- 			    int flags, const char *dev_name,
- 			    void *data, struct vfsmount *mnt)
-@@ -1938,14 +2176,14 @@ static DECLARE_FSTYPE(yaffs_fs_type, "ya
- 
- #ifdef CONFIG_YAFFS_YAFFS2
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
- 					  int silent)
- {
- 	return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
- }
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- static int yaffs2_read_super(struct file_system_type *fs,
- 			int flags, const char *dev_name, void *data,
- 			struct vfsmount *mnt)
-@@ -1990,12 +2228,12 @@ static char *yaffs_dump_dev(char *buf, y
- {
- 	buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock);
- 	buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock);
-+	buf += sprintf(buf, "totalBytesPerChunk. %d\n", dev->totalBytesPerChunk);
- 	buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk);
- 	buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits);
- 	buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize);
- 	buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks);
- 	buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks);
--	buf += sprintf(buf, "nCheckptResBlocks.. %d\n", dev->nCheckpointReservedBlocks);
- 	buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint);
- 	buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated);
- 	buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes);
-@@ -2006,10 +2244,8 @@ static char *yaffs_dump_dev(char *buf, y
- 	buf += sprintf(buf, "nPageReads......... %d\n", dev->nPageReads);
- 	buf += sprintf(buf, "nBlockErasures..... %d\n", dev->nBlockErasures);
- 	buf += sprintf(buf, "nGCCopies.......... %d\n", dev->nGCCopies);
--	buf +=
--	    sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);
--	buf +=
--	    sprintf(buf, "passiveGCs......... %d\n",
-+	buf += sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);
-+	buf += sprintf(buf, "passiveGCs......... %d\n",
- 		    dev->passiveGarbageCollections);
- 	buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites);
- 	buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches);
-@@ -2025,6 +2261,7 @@ static char *yaffs_dump_dev(char *buf, y
- 	    sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions);
- 	buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC);
- 	buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2);
-+	buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags);
- 
- 	return buf;
- }
-@@ -2033,7 +2270,7 @@ static int yaffs_proc_read(char *page,
- 			   char **start,
- 			   off_t offset, int count, int *eof, void *data)
- {
--	struct list_head *item;
-+	struct ylist_head *item;
- 	char *buf = page;
- 	int step = offset;
- 	int n = 0;
-@@ -2057,8 +2294,8 @@ static int yaffs_proc_read(char *page,
- 	lock_kernel();
- 
- 	/* Locate and print the Nth entry.  Order N-squared but N is small. */
--	list_for_each(item, &yaffs_dev_list) {
--		yaffs_Device *dev = list_entry(item, yaffs_Device, devList);
-+	ylist_for_each(item, &yaffs_dev_list) {
-+		yaffs_Device *dev = ylist_entry(item, yaffs_Device, devList);
- 		if (n < step) {
- 			n++;
- 			continue;
-@@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file
- 	char *end;
- 	char *mask_name;
- 	const char *x;
--	char substring[MAX_MASK_NAME_LENGTH+1];
-+	char substring[MAX_MASK_NAME_LENGTH + 1];
- 	int i;
- 	int done = 0;
- 	int add, len = 0;
-@@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file
- 
- 	while (!done && (pos < count)) {
- 		done = 1;
--		while ((pos < count) && isspace(buf[pos])) {
-+		while ((pos < count) && isspace(buf[pos]))
- 			pos++;
--		}
- 
- 		switch (buf[pos]) {
- 		case '+':
-@@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file
- 		mask_name = NULL;
- 
- 		mask_bitfield = simple_strtoul(buf + pos, &end, 0);
-+
- 		if (end > buf + pos) {
- 			mask_name = "numeral";
- 			len = end - (buf + pos);
- 			pos += len;
- 			done = 0;
- 		} else {
--			for(x = buf + pos, i = 0;
--			    (*x == '_' || (*x >='a' && *x <= 'z')) &&
--			    i <MAX_MASK_NAME_LENGTH; x++, i++, pos++)
--			    substring[i] = *x;
-+			for (x = buf + pos, i = 0;
-+			    (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
-+			    i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
-+				substring[i] = *x;
- 			substring[i] = '\0';
- 
- 			for (i = 0; mask_flags[i].mask_name != NULL; i++) {
--				if(strcmp(substring,mask_flags[i].mask_name) == 0){
-+				if (strcmp(substring, mask_flags[i].mask_name) == 0) {
- 					mask_name = mask_flags[i].mask_name;
- 					mask_bitfield = mask_flags[i].mask_bitfield;
- 					done = 0;
-@@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file
- 
- 		if (mask_name != NULL) {
- 			done = 0;
--			switch(add) {
-+			switch (add) {
- 			case '-':
- 				rg &= ~mask_bitfield;
- 				break;
-@@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file
- 
- 	yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
- 
--	printk("new trace = 0x%08X\n",yaffs_traceMask);
-+	printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_traceMask);
- 
- 	if (rg & YAFFS_TRACE_ALWAYS) {
- 		for (i = 0; mask_flags[i].mask_name != NULL; i++) {
- 			char flag;
- 			flag = ((rg & mask_flags[i].mask_bitfield) == mask_flags[i].mask_bitfield) ? '+' : '-';
--			printk("%c%s\n", flag, mask_flags[i].mask_name);
-+			printk(KERN_DEBUG "%c%s\n", flag, mask_flags[i].mask_name);
- 		}
- 	}
- 
-@@ -2211,12 +2448,8 @@ struct file_system_to_install {
- };
- 
- static struct file_system_to_install fs_to_install[] = {
--//#ifdef CONFIG_YAFFS_YAFFS1
- 	{&yaffs_fs_type, 0},
--//#endif
--//#ifdef CONFIG_YAFFS_YAFFS2
- 	{&yaffs2_fs_type, 0},
--//#endif
- 	{NULL, 0}
- };
- 
-@@ -2231,15 +2464,14 @@ static int __init init_yaffs_fs(void)
- 	/* Install the proc_fs entry */
- 	my_proc_entry = create_proc_entry("yaffs",
- 					       S_IRUGO | S_IFREG,
--					       &proc_root);
-+					       YPROC_ROOT);
- 
- 	if (my_proc_entry) {
- 		my_proc_entry->write_proc = yaffs_proc_write;
- 		my_proc_entry->read_proc = yaffs_proc_read;
- 		my_proc_entry->data = NULL;
--	} else {
-+	} else
- 		return -ENOMEM;
--	}
- 
- 	/* Now add the file system entries */
- 
-@@ -2247,9 +2479,8 @@ static int __init init_yaffs_fs(void)
- 
- 	while (fsinst->fst && !error) {
- 		error = register_filesystem(fsinst->fst);
--		if (!error) {
-+		if (!error)
- 			fsinst->installed = 1;
--		}
- 		fsinst++;
- 	}
- 
-@@ -2277,7 +2508,7 @@ static void __exit exit_yaffs_fs(void)
- 	T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__
- 			       " removing. \n"));
- 
--	remove_proc_entry("yaffs", &proc_root);
-+	remove_proc_entry("yaffs", YPROC_ROOT);
- 
- 	fsinst = fs_to_install;
- 
-@@ -2288,7 +2519,6 @@ static void __exit exit_yaffs_fs(void)
- 		}
- 		fsinst++;
- 	}
--
- }
- 
- module_init(init_yaffs_fs)
---- /dev/null
-+++ b/fs/yaffs2/yaffs_getblockinfo.h
-@@ -0,0 +1,34 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2007 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+#ifndef __YAFFS_GETBLOCKINFO_H__
-+#define __YAFFS_GETBLOCKINFO_H__
-+
-+#include "yaffs_guts.h"
-+
-+/* Function to manipulate block info */
-+static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
-+{
-+	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
-+		T(YAFFS_TRACE_ERROR,
-+		  (TSTR
-+		   ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
-+		   blk));
-+		YBUG();
-+	}
-+	return &dev->blockInfo[blk - dev->internalStartBlock];
-+}
-+
-+#endif
---- a/fs/yaffs2/yaffs_guts.c
-+++ b/fs/yaffs2/yaffs_guts.c
-@@ -12,16 +12,17 @@
-  */
- 
- const char *yaffs_guts_c_version =
--    "$Id: yaffs_guts.c,v 1.49 2007-05-15 20:07:40 charles Exp $";
-+    "$Id: yaffs_guts.c,v 1.82 2009-03-09 04:24:17 charles Exp $";
- 
- #include "yportenv.h"
- 
- #include "yaffsinterface.h"
- #include "yaffs_guts.h"
- #include "yaffs_tagsvalidity.h"
-+#include "yaffs_getblockinfo.h"
- 
- #include "yaffs_tagscompat.h"
--#ifndef  CONFIG_YAFFS_USE_OWN_SORT
-+#ifndef CONFIG_YAFFS_USE_OWN_SORT
- #include "yaffs_qsort.h"
- #endif
- #include "yaffs_nand.h"
-@@ -32,116 +33,116 @@ const char *yaffs_guts_c_version =
- #include "yaffs_packedtags2.h"
- 
- 
--#ifdef CONFIG_YAFFS_WINCE
--void yfsd_LockYAFFS(BOOL fsLockOnly);
--void yfsd_UnlockYAFFS(BOOL fsLockOnly);
--#endif
--
- #define YAFFS_PASSIVE_GC_CHUNKS 2
- 
- #include "yaffs_ecc.h"
- 
- 
- /* Robustification (if it ever comes about...) */
--static void yaffs_RetireBlock(yaffs_Device * dev, int blockInNAND);
--static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk);
--static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
--				     const __u8 * data,
--				     const yaffs_ExtendedTags * tags);
--static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
--				    const yaffs_ExtendedTags * tags);
-+static void yaffs_RetireBlock(yaffs_Device *dev, int blockInNAND);
-+static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND,
-+		int erasedOk);
-+static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
-+				const __u8 *data,
-+				const yaffs_ExtendedTags *tags);
-+static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
-+				const yaffs_ExtendedTags *tags);
- 
- /* Other local prototypes */
--static int yaffs_UnlinkObject( yaffs_Object *obj);
-+static int yaffs_UnlinkObject(yaffs_Object *obj);
- static int yaffs_ObjectHasCachedWriteData(yaffs_Object *obj);
- 
- static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList);
- 
--static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device * dev,
--					     const __u8 * buffer,
--					     yaffs_ExtendedTags * tags,
--					     int useReserve);
--static int yaffs_PutChunkIntoFile(yaffs_Object * in, int chunkInInode,
--				  int chunkInNAND, int inScan);
--
--static yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number,
--					   yaffs_ObjectType type);
--static void yaffs_AddObjectToDirectory(yaffs_Object * directory,
--				       yaffs_Object * obj);
--static int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name,
--				    int force, int isShrink, int shadows);
--static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj);
-+static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device *dev,
-+					const __u8 *buffer,
-+					yaffs_ExtendedTags *tags,
-+					int useReserve);
-+static int yaffs_PutChunkIntoFile(yaffs_Object *in, int chunkInInode,
-+				int chunkInNAND, int inScan);
-+
-+static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number,
-+					yaffs_ObjectType type);
-+static void yaffs_AddObjectToDirectory(yaffs_Object *directory,
-+				yaffs_Object *obj);
-+static int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name,
-+				int force, int isShrink, int shadows);
-+static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
- static int yaffs_CheckStructures(void);
--static int yaffs_DeleteWorker(yaffs_Object * in, yaffs_Tnode * tn, __u32 level,
--			      int chunkOffset, int *limit);
--static int yaffs_DoGenericObjectDeletion(yaffs_Object * in);
--
--static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blockNo);
--
--static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo);
--static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
--				    int lineNo);
-+static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level,
-+			int chunkOffset, int *limit);
-+static int yaffs_DoGenericObjectDeletion(yaffs_Object *in);
-+
-+static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev, int blockNo);
- 
--static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
--				  int chunkInNAND);
- 
--static int yaffs_UnlinkWorker(yaffs_Object * obj);
--static void yaffs_DestroyObject(yaffs_Object * obj);
-+static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
-+				int chunkInNAND);
- 
--static int yaffs_TagsMatch(const yaffs_ExtendedTags * tags, int objectId,
--			   int chunkInObject);
-+static int yaffs_UnlinkWorker(yaffs_Object *obj);
- 
--loff_t yaffs_GetFileSize(yaffs_Object * obj);
-+static int yaffs_TagsMatch(const yaffs_ExtendedTags *tags, int objectId,
-+			int chunkInObject);
- 
--static int yaffs_AllocateChunk(yaffs_Device * dev, int useReserve, yaffs_BlockInfo **blockUsedPtr);
-+static int yaffs_AllocateChunk(yaffs_Device *dev, int useReserve,
-+				yaffs_BlockInfo **blockUsedPtr);
- 
--static void yaffs_VerifyFreeChunks(yaffs_Device * dev);
-+static void yaffs_VerifyFreeChunks(yaffs_Device *dev);
- 
- static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in);
- 
-+static void yaffs_VerifyDirectory(yaffs_Object *directory);
- #ifdef YAFFS_PARANOID
--static int yaffs_CheckFileSanity(yaffs_Object * in);
-+static int yaffs_CheckFileSanity(yaffs_Object *in);
- #else
- #define yaffs_CheckFileSanity(in)
- #endif
- 
--static void yaffs_InvalidateWholeChunkCache(yaffs_Object * in);
--static void yaffs_InvalidateChunkCache(yaffs_Object * object, int chunkId);
-+static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in);
-+static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId);
- 
- static void yaffs_InvalidateCheckpoint(yaffs_Device *dev);
- 
--static int yaffs_FindChunkInFile(yaffs_Object * in, int chunkInInode,
--				 yaffs_ExtendedTags * tags);
-+static int yaffs_FindChunkInFile(yaffs_Object *in, int chunkInInode,
-+				yaffs_ExtendedTags *tags);
- 
--static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos);
--static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device * dev,
--					  yaffs_FileStructure * fStruct,
--					  __u32 chunkId);
-+static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn,
-+		unsigned pos);
-+static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device *dev,
-+					yaffs_FileStructure *fStruct,
-+					__u32 chunkId);
- 
- 
- /* Function to calculate chunk and offset */
- 
--static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, __u32 *chunk, __u32 *offset)
-+static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, int *chunkOut,
-+		__u32 *offsetOut)
- {
--	if(dev->chunkShift){
--		/* Easy-peasy power of 2 case */
--		*chunk  = (__u32)(addr >> dev->chunkShift);
--		*offset = (__u32)(addr & dev->chunkMask);
--	}
--	else if(dev->crumbsPerChunk)
--	{
--		/* Case where we're using "crumbs" */
--		*offset = (__u32)(addr & dev->crumbMask);
--		addr >>= dev->crumbShift;
--		*chunk = ((__u32)addr)/dev->crumbsPerChunk;
--		*offset += ((addr - (*chunk * dev->crumbsPerChunk)) << dev->crumbShift);
-+	int chunk;
-+	__u32 offset;
-+
-+	chunk  = (__u32)(addr >> dev->chunkShift);
-+
-+	if (dev->chunkDiv == 1) {
-+		/* easy power of 2 case */
-+		offset = (__u32)(addr & dev->chunkMask);
-+	} else {
-+		/* Non power-of-2 case */
-+
-+		loff_t chunkBase;
-+
-+		chunk /= dev->chunkDiv;
-+
-+		chunkBase = ((loff_t)chunk) * dev->nDataBytesPerChunk;
-+		offset = (__u32)(addr - chunkBase);
- 	}
--	else
--		YBUG();
-+
-+	*chunkOut = chunk;
-+	*offsetOut = offset;
- }
- 
--/* Function to return the number of shifts for a power of 2 greater than or equal
-- * to the given number
-+/* Function to return the number of shifts for a power of 2 greater than or
-+ * equal to the given number
-  * Note we don't try to cater for all possible numbers and this does not have to
-  * be hellishly efficient.
-  */
-@@ -153,13 +154,14 @@ static __u32 ShiftsGE(__u32 x)
- 
- 	nShifts = extraBits = 0;
- 
--	while(x>1){
--		if(x & 1) extraBits++;
--		x>>=1;
-+	while (x > 1) {
-+		if (x & 1)
-+			extraBits++;
-+		x >>= 1;
- 		nShifts++;
- 	}
- 
--	if(extraBits)
-+	if (extraBits)
- 		nShifts++;
- 
- 	return nShifts;
-@@ -168,16 +170,17 @@ static __u32 ShiftsGE(__u32 x)
- /* Function to return the number of shifts to get a 1 in bit 0
-  */
- 
--static __u32 ShiftDiv(__u32 x)
-+static __u32 Shifts(__u32 x)
- {
- 	int nShifts;
- 
- 	nShifts =  0;
- 
--	if(!x) return 0;
-+	if (!x)
-+		return 0;
- 
--	while( !(x&1)){
--		x>>=1;
-+	while (!(x&1)) {
-+		x >>= 1;
- 		nShifts++;
- 	}
- 
-@@ -195,21 +198,25 @@ static int yaffs_InitialiseTempBuffers(y
- 	int i;
- 	__u8 *buf = (__u8 *)1;
- 
--	memset(dev->tempBuffer,0,sizeof(dev->tempBuffer));
-+	memset(dev->tempBuffer, 0, sizeof(dev->tempBuffer));
- 
- 	for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) {
- 		dev->tempBuffer[i].line = 0;	/* not in use */
- 		dev->tempBuffer[i].buffer = buf =
--		    YMALLOC_DMA(dev->nDataBytesPerChunk);
-+		    YMALLOC_DMA(dev->totalBytesPerChunk);
- 	}
- 
- 	return buf ? YAFFS_OK : YAFFS_FAIL;
--
- }
- 
--static __u8 *yaffs_GetTempBuffer(yaffs_Device * dev, int lineNo)
-+__u8 *yaffs_GetTempBuffer(yaffs_Device *dev, int lineNo)
- {
- 	int i, j;
-+
-+	dev->tempInUse++;
-+	if (dev->tempInUse > dev->maxTemp)
-+		dev->maxTemp = dev->tempInUse;
-+
- 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
- 		if (dev->tempBuffer[i].line == 0) {
- 			dev->tempBuffer[i].line = lineNo;
-@@ -227,9 +234,9 @@ static __u8 *yaffs_GetTempBuffer(yaffs_D
- 	T(YAFFS_TRACE_BUFFERS,
- 	  (TSTR("Out of temp buffers at line %d, other held by lines:"),
- 	   lineNo));
--	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
-+	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
- 		T(YAFFS_TRACE_BUFFERS, (TSTR(" %d "), dev->tempBuffer[i].line));
--	}
-+
- 	T(YAFFS_TRACE_BUFFERS, (TSTR(" " TENDSTR)));
- 
- 	/*
-@@ -242,10 +249,13 @@ static __u8 *yaffs_GetTempBuffer(yaffs_D
- 
- }
- 
--static void yaffs_ReleaseTempBuffer(yaffs_Device * dev, __u8 * buffer,
-+void yaffs_ReleaseTempBuffer(yaffs_Device *dev, __u8 *buffer,
- 				    int lineNo)
- {
- 	int i;
-+
-+	dev->tempInUse--;
-+
- 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
- 		if (dev->tempBuffer[i].buffer == buffer) {
- 			dev->tempBuffer[i].line = 0;
-@@ -267,27 +277,26 @@ static void yaffs_ReleaseTempBuffer(yaff
- /*
-  * Determine if we have a managed buffer.
-  */
--int yaffs_IsManagedTempBuffer(yaffs_Device * dev, const __u8 * buffer)
-+int yaffs_IsManagedTempBuffer(yaffs_Device *dev, const __u8 *buffer)
- {
- 	int i;
-+
- 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
- 		if (dev->tempBuffer[i].buffer == buffer)
- 			return 1;
-+	}
- 
-+	for (i = 0; i < dev->nShortOpCaches; i++) {
-+		if (dev->srCache[i].data == buffer)
-+			return 1;
- 	}
- 
--    for (i = 0; i < dev->nShortOpCaches; i++) {
--        if( dev->srCache[i].data == buffer )
--            return 1;
--
--    }
--
--    if (buffer == dev->checkpointBuffer)
--      return 1;
--
--    T(YAFFS_TRACE_ALWAYS,
--	  (TSTR("yaffs: unmaged buffer detected.\n" TENDSTR)));
--    return 0;
-+	if (buffer == dev->checkpointBuffer)
-+		return 1;
-+
-+	T(YAFFS_TRACE_ALWAYS,
-+		(TSTR("yaffs: unmaged buffer detected.\n" TENDSTR)));
-+	return 0;
- }
- 
- 
-@@ -296,62 +305,63 @@ int yaffs_IsManagedTempBuffer(yaffs_Devi
-  * Chunk bitmap manipulations
-  */
- 
--static Y_INLINE __u8 *yaffs_BlockBits(yaffs_Device * dev, int blk)
-+static Y_INLINE __u8 *yaffs_BlockBits(yaffs_Device *dev, int blk)
- {
- 	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
- 		T(YAFFS_TRACE_ERROR,
--		  (TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),
--		   blk));
-+			(TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),
-+			blk));
- 		YBUG();
- 	}
- 	return dev->chunkBits +
--	    (dev->chunkBitmapStride * (blk - dev->internalStartBlock));
-+		(dev->chunkBitmapStride * (blk - dev->internalStartBlock));
- }
- 
- static Y_INLINE void yaffs_VerifyChunkBitId(yaffs_Device *dev, int blk, int chunk)
- {
--	if(blk < dev->internalStartBlock || blk > dev->internalEndBlock ||
--	   chunk < 0 || chunk >= dev->nChunksPerBlock) {
--	   T(YAFFS_TRACE_ERROR,
--	    (TSTR("**>> yaffs: Chunk Id (%d:%d) invalid"TENDSTR),blk,chunk));
--	    YBUG();
-+	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock ||
-+			chunk < 0 || chunk >= dev->nChunksPerBlock) {
-+		T(YAFFS_TRACE_ERROR,
-+		(TSTR("**>> yaffs: Chunk Id (%d:%d) invalid"TENDSTR),
-+			blk, chunk));
-+		YBUG();
- 	}
- }
- 
--static Y_INLINE void yaffs_ClearChunkBits(yaffs_Device * dev, int blk)
-+static Y_INLINE void yaffs_ClearChunkBits(yaffs_Device *dev, int blk)
- {
- 	__u8 *blkBits = yaffs_BlockBits(dev, blk);
- 
- 	memset(blkBits, 0, dev->chunkBitmapStride);
- }
- 
--static Y_INLINE void yaffs_ClearChunkBit(yaffs_Device * dev, int blk, int chunk)
-+static Y_INLINE void yaffs_ClearChunkBit(yaffs_Device *dev, int blk, int chunk)
- {
- 	__u8 *blkBits = yaffs_BlockBits(dev, blk);
- 
--	yaffs_VerifyChunkBitId(dev,blk,chunk);
-+	yaffs_VerifyChunkBitId(dev, blk, chunk);
- 
- 	blkBits[chunk / 8] &= ~(1 << (chunk & 7));
- }
- 
--static Y_INLINE void yaffs_SetChunkBit(yaffs_Device * dev, int blk, int chunk)
-+static Y_INLINE void yaffs_SetChunkBit(yaffs_Device *dev, int blk, int chunk)
- {
- 	__u8 *blkBits = yaffs_BlockBits(dev, blk);
- 
--	yaffs_VerifyChunkBitId(dev,blk,chunk);
-+	yaffs_VerifyChunkBitId(dev, blk, chunk);
- 
- 	blkBits[chunk / 8] |= (1 << (chunk & 7));
- }
- 
--static Y_INLINE int yaffs_CheckChunkBit(yaffs_Device * dev, int blk, int chunk)
-+static Y_INLINE int yaffs_CheckChunkBit(yaffs_Device *dev, int blk, int chunk)
- {
- 	__u8 *blkBits = yaffs_BlockBits(dev, blk);
--	yaffs_VerifyChunkBitId(dev,blk,chunk);
-+	yaffs_VerifyChunkBitId(dev, blk, chunk);
- 
- 	return (blkBits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0;
- }
- 
--static Y_INLINE int yaffs_StillSomeChunkBits(yaffs_Device * dev, int blk)
-+static Y_INLINE int yaffs_StillSomeChunkBits(yaffs_Device *dev, int blk)
- {
- 	__u8 *blkBits = yaffs_BlockBits(dev, blk);
- 	int i;
-@@ -363,17 +373,17 @@ static Y_INLINE int yaffs_StillSomeChunk
- 	return 0;
- }
- 
--static int yaffs_CountChunkBits(yaffs_Device * dev, int blk)
-+static int yaffs_CountChunkBits(yaffs_Device *dev, int blk)
- {
- 	__u8 *blkBits = yaffs_BlockBits(dev, blk);
- 	int i;
- 	int n = 0;
- 	for (i = 0; i < dev->chunkBitmapStride; i++) {
- 		__u8 x = *blkBits;
--		while(x){
--			if(x & 1)
-+		while (x) {
-+			if (x & 1)
- 				n++;
--			x >>=1;
-+			x >>= 1;
- 		}
- 
- 		blkBits++;
-@@ -400,7 +410,7 @@ static int yaffs_SkipNANDVerification(ya
- 	return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY_NAND));
- }
- 
--static const char * blockStateName[] = {
-+static const char *blockStateName[] = {
- "Unknown",
- "Needs scanning",
- "Scanning",
-@@ -413,64 +423,65 @@ static const char * blockStateName[] = {
- "Dead"
- };
- 
--static void yaffs_VerifyBlock(yaffs_Device *dev,yaffs_BlockInfo *bi,int n)
-+static void yaffs_VerifyBlock(yaffs_Device *dev, yaffs_BlockInfo *bi, int n)
- {
- 	int actuallyUsed;
- 	int inUse;
- 
--	if(yaffs_SkipVerification(dev))
-+	if (yaffs_SkipVerification(dev))
- 		return;
- 
- 	/* Report illegal runtime states */
--	if(bi->blockState <0 || bi->blockState >= YAFFS_NUMBER_OF_BLOCK_STATES)
--		T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has undefined state %d"TENDSTR),n,bi->blockState));
-+	if (bi->blockState >= YAFFS_NUMBER_OF_BLOCK_STATES)
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has undefined state %d"TENDSTR), n, bi->blockState));
- 
--	switch(bi->blockState){
--	 case YAFFS_BLOCK_STATE_UNKNOWN:
--	 case YAFFS_BLOCK_STATE_SCANNING:
--	 case YAFFS_BLOCK_STATE_NEEDS_SCANNING:
--		T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has bad run-state %s"TENDSTR),
--		n,blockStateName[bi->blockState]));
-+	switch (bi->blockState) {
-+	case YAFFS_BLOCK_STATE_UNKNOWN:
-+	case YAFFS_BLOCK_STATE_SCANNING:
-+	case YAFFS_BLOCK_STATE_NEEDS_SCANNING:
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has bad run-state %s"TENDSTR),
-+		n, blockStateName[bi->blockState]));
- 	}
- 
- 	/* Check pages in use and soft deletions are legal */
- 
- 	actuallyUsed = bi->pagesInUse - bi->softDeletions;
- 
--	if(bi->pagesInUse < 0 || bi->pagesInUse > dev->nChunksPerBlock ||
-+	if (bi->pagesInUse < 0 || bi->pagesInUse > dev->nChunksPerBlock ||
- 	   bi->softDeletions < 0 || bi->softDeletions > dev->nChunksPerBlock ||
- 	   actuallyUsed < 0 || actuallyUsed > dev->nChunksPerBlock)
--		T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has illegal values pagesInUsed %d softDeletions %d"TENDSTR),
--		n,bi->pagesInUse,bi->softDeletions));
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has illegal values pagesInUsed %d softDeletions %d"TENDSTR),
-+		n, bi->pagesInUse, bi->softDeletions));
- 
- 
- 	/* Check chunk bitmap legal */
--	inUse = yaffs_CountChunkBits(dev,n);
--	if(inUse != bi->pagesInUse)
--		T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has inconsistent values pagesInUse %d counted chunk bits %d"TENDSTR),
--			n,bi->pagesInUse,inUse));
-+	inUse = yaffs_CountChunkBits(dev, n);
-+	if (inUse != bi->pagesInUse)
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has inconsistent values pagesInUse %d counted chunk bits %d"TENDSTR),
-+			n, bi->pagesInUse, inUse));
- 
- 	/* Check that the sequence number is valid.
- 	 * Ten million is legal, but is very unlikely
- 	 */
--	if(dev->isYaffs2 &&
-+	if (dev->isYaffs2 &&
- 	   (bi->blockState == YAFFS_BLOCK_STATE_ALLOCATING || bi->blockState == YAFFS_BLOCK_STATE_FULL) &&
--	   (bi->sequenceNumber < YAFFS_LOWEST_SEQUENCE_NUMBER || bi->sequenceNumber > 10000000 ))
--		T(YAFFS_TRACE_VERIFY,(TSTR("Block %d has suspect sequence number of %d"TENDSTR),
--		n,bi->sequenceNumber));
--
-+	   (bi->sequenceNumber < YAFFS_LOWEST_SEQUENCE_NUMBER || bi->sequenceNumber > 10000000))
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has suspect sequence number of %d"TENDSTR),
-+		n, bi->sequenceNumber));
- }
- 
--static void yaffs_VerifyCollectedBlock(yaffs_Device *dev,yaffs_BlockInfo *bi,int n)
-+static void yaffs_VerifyCollectedBlock(yaffs_Device *dev, yaffs_BlockInfo *bi,
-+		int n)
- {
--	yaffs_VerifyBlock(dev,bi,n);
-+	yaffs_VerifyBlock(dev, bi, n);
- 
- 	/* After collection the block should be in the erased state */
--	/* TODO: This will need to change if we do partial gc */
-+	/* This will need to change if we do partial gc */
- 
--	if(bi->blockState != YAFFS_BLOCK_STATE_EMPTY){
--		T(YAFFS_TRACE_ERROR,(TSTR("Block %d is in state %d after gc, should be erased"TENDSTR),
--			n,bi->blockState));
-+	if (bi->blockState != YAFFS_BLOCK_STATE_COLLECTING &&
-+			bi->blockState != YAFFS_BLOCK_STATE_EMPTY) {
-+		T(YAFFS_TRACE_ERROR, (TSTR("Block %d is in state %d after gc, should be erased"TENDSTR),
-+			n, bi->blockState));
- 	}
- }
- 
-@@ -480,52 +491,49 @@ static void yaffs_VerifyBlocks(yaffs_Dev
- 	int nBlocksPerState[YAFFS_NUMBER_OF_BLOCK_STATES];
- 	int nIllegalBlockStates = 0;
- 
--
--	if(yaffs_SkipVerification(dev))
-+	if (yaffs_SkipVerification(dev))
- 		return;
- 
--	memset(nBlocksPerState,0,sizeof(nBlocksPerState));
--
-+	memset(nBlocksPerState, 0, sizeof(nBlocksPerState));
- 
--	for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++){
--		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
--		yaffs_VerifyBlock(dev,bi,i);
-+	for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
-+		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
-+		yaffs_VerifyBlock(dev, bi, i);
- 
--		if(bi->blockState >=0 && bi->blockState < YAFFS_NUMBER_OF_BLOCK_STATES)
-+		if (bi->blockState < YAFFS_NUMBER_OF_BLOCK_STATES)
- 			nBlocksPerState[bi->blockState]++;
- 		else
- 			nIllegalBlockStates++;
--
- 	}
- 
--	T(YAFFS_TRACE_VERIFY,(TSTR(""TENDSTR)));
--	T(YAFFS_TRACE_VERIFY,(TSTR("Block summary"TENDSTR)));
-+	T(YAFFS_TRACE_VERIFY, (TSTR(""TENDSTR)));
-+	T(YAFFS_TRACE_VERIFY, (TSTR("Block summary"TENDSTR)));
- 
--	T(YAFFS_TRACE_VERIFY,(TSTR("%d blocks have illegal states"TENDSTR),nIllegalBlockStates));
--	if(nBlocksPerState[YAFFS_BLOCK_STATE_ALLOCATING] > 1)
--		T(YAFFS_TRACE_VERIFY,(TSTR("Too many allocating blocks"TENDSTR)));
-+	T(YAFFS_TRACE_VERIFY, (TSTR("%d blocks have illegal states"TENDSTR), nIllegalBlockStates));
-+	if (nBlocksPerState[YAFFS_BLOCK_STATE_ALLOCATING] > 1)
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Too many allocating blocks"TENDSTR)));
- 
--	for(i = 0; i < YAFFS_NUMBER_OF_BLOCK_STATES; i++)
-+	for (i = 0; i < YAFFS_NUMBER_OF_BLOCK_STATES; i++)
- 		T(YAFFS_TRACE_VERIFY,
- 		  (TSTR("%s %d blocks"TENDSTR),
--		  blockStateName[i],nBlocksPerState[i]));
-+		  blockStateName[i], nBlocksPerState[i]));
- 
--	if(dev->blocksInCheckpoint != nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT])
-+	if (dev->blocksInCheckpoint != nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT])
- 		T(YAFFS_TRACE_VERIFY,
- 		 (TSTR("Checkpoint block count wrong dev %d count %d"TENDSTR),
- 		 dev->blocksInCheckpoint, nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT]));
- 
--	if(dev->nErasedBlocks != nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY])
-+	if (dev->nErasedBlocks != nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY])
- 		T(YAFFS_TRACE_VERIFY,
- 		 (TSTR("Erased block count wrong dev %d count %d"TENDSTR),
- 		 dev->nErasedBlocks, nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY]));
- 
--	if(nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING] > 1)
-+	if (nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING] > 1)
- 		T(YAFFS_TRACE_VERIFY,
- 		 (TSTR("Too many collecting blocks %d (max is 1)"TENDSTR),
- 		 nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING]));
- 
--	T(YAFFS_TRACE_VERIFY,(TSTR(""TENDSTR)));
-+	T(YAFFS_TRACE_VERIFY, (TSTR(""TENDSTR)));
- 
- }
- 
-@@ -535,26 +543,26 @@ static void yaffs_VerifyBlocks(yaffs_Dev
-  */
- static void yaffs_VerifyObjectHeader(yaffs_Object *obj, yaffs_ObjectHeader *oh, yaffs_ExtendedTags *tags, int parentCheck)
- {
--	if(yaffs_SkipVerification(obj->myDev))
-+	if (obj && yaffs_SkipVerification(obj->myDev))
- 		return;
- 
--	if(!(tags && obj && oh)){
--	 	T(YAFFS_TRACE_VERIFY,
--		 		(TSTR("Verifying object header tags %x obj %x oh %x"TENDSTR),
--		 		(__u32)tags,(__u32)obj,(__u32)oh));
-+	if (!(tags && obj && oh)) {
-+		T(YAFFS_TRACE_VERIFY,
-+				(TSTR("Verifying object header tags %x obj %x oh %x"TENDSTR),
-+				(__u32)tags, (__u32)obj, (__u32)oh));
- 		return;
- 	}
- 
--	if(oh->type <= YAFFS_OBJECT_TYPE_UNKNOWN ||
--	   oh->type > YAFFS_OBJECT_TYPE_MAX)
--	 	T(YAFFS_TRACE_VERIFY,
--		 (TSTR("Obj %d header type is illegal value 0x%x"TENDSTR),
--		 tags->objectId, oh->type));
--
--	if(tags->objectId != obj->objectId)
--	 	T(YAFFS_TRACE_VERIFY,
--		 (TSTR("Obj %d header mismatch objectId %d"TENDSTR),
--		 tags->objectId, obj->objectId));
-+	if (oh->type <= YAFFS_OBJECT_TYPE_UNKNOWN ||
-+			oh->type > YAFFS_OBJECT_TYPE_MAX)
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header type is illegal value 0x%x"TENDSTR),
-+			tags->objectId, oh->type));
-+
-+	if (tags->objectId != obj->objectId)
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header mismatch objectId %d"TENDSTR),
-+			tags->objectId, obj->objectId));
- 
- 
- 	/*
-@@ -563,46 +571,43 @@ static void yaffs_VerifyObjectHeader(yaf
- 	 * Tests do not apply to the root object.
- 	 */
- 
--	if(parentCheck && tags->objectId > 1 && !obj->parent)
--	 	T(YAFFS_TRACE_VERIFY,
--		 (TSTR("Obj %d header mismatch parentId %d obj->parent is NULL"TENDSTR),
--	 	 tags->objectId, oh->parentObjectId));
--
--
--	if(parentCheck && obj->parent &&
--	   oh->parentObjectId != obj->parent->objectId &&
--	   (oh->parentObjectId != YAFFS_OBJECTID_UNLINKED ||
--	    obj->parent->objectId != YAFFS_OBJECTID_DELETED))
--	 	T(YAFFS_TRACE_VERIFY,
--		 (TSTR("Obj %d header mismatch parentId %d parentObjectId %d"TENDSTR),
--	 	 tags->objectId, oh->parentObjectId, obj->parent->objectId));
-+	if (parentCheck && tags->objectId > 1 && !obj->parent)
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header mismatch parentId %d obj->parent is NULL"TENDSTR),
-+			tags->objectId, oh->parentObjectId));
- 
-+	if (parentCheck && obj->parent &&
-+			oh->parentObjectId != obj->parent->objectId &&
-+			(oh->parentObjectId != YAFFS_OBJECTID_UNLINKED ||
-+			obj->parent->objectId != YAFFS_OBJECTID_DELETED))
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header mismatch parentId %d parentObjectId %d"TENDSTR),
-+			tags->objectId, oh->parentObjectId, obj->parent->objectId));
- 
--	if(tags->objectId > 1 && oh->name[0] == 0) /* Null name */
-+	if (tags->objectId > 1 && oh->name[0] == 0) /* Null name */
- 		T(YAFFS_TRACE_VERIFY,
--		(TSTR("Obj %d header name is NULL"TENDSTR),
--		 obj->objectId));
-+			(TSTR("Obj %d header name is NULL"TENDSTR),
-+			obj->objectId));
- 
--	if(tags->objectId > 1 && ((__u8)(oh->name[0])) == 0xff) /* Trashed name */
-+	if (tags->objectId > 1 && ((__u8)(oh->name[0])) == 0xff) /* Trashed name */
- 		T(YAFFS_TRACE_VERIFY,
--		(TSTR("Obj %d header name is 0xFF"TENDSTR),
--		 obj->objectId));
-+			(TSTR("Obj %d header name is 0xFF"TENDSTR),
-+			obj->objectId));
- }
- 
- 
- 
--static int yaffs_VerifyTnodeWorker(yaffs_Object * obj, yaffs_Tnode * tn,
--				  	__u32 level, int chunkOffset)
-+static int yaffs_VerifyTnodeWorker(yaffs_Object *obj, yaffs_Tnode *tn,
-+					__u32 level, int chunkOffset)
- {
- 	int i;
- 	yaffs_Device *dev = obj->myDev;
- 	int ok = 1;
--	int nTnodeBytes = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
- 
- 	if (tn) {
- 		if (level > 0) {
- 
--			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++){
-+			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
- 				if (tn->internal[i]) {
- 					ok = yaffs_VerifyTnodeWorker(obj,
- 							tn->internal[i],
-@@ -611,20 +616,19 @@ static int yaffs_VerifyTnodeWorker(yaffs
- 				}
- 			}
- 		} else if (level == 0) {
--			int i;
- 			yaffs_ExtendedTags tags;
- 			__u32 objectId = obj->objectId;
- 
- 			chunkOffset <<=  YAFFS_TNODES_LEVEL0_BITS;
- 
--			for(i = 0; i < YAFFS_NTNODES_LEVEL0; i++){
--				__u32 theChunk = yaffs_GetChunkGroupBase(dev,tn,i);
-+			for (i = 0; i < YAFFS_NTNODES_LEVEL0; i++) {
-+				__u32 theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
- 
--				if(theChunk > 0){
-+				if (theChunk > 0) {
- 					/* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),tags.objectId,tags.chunkId,theChunk)); */
--					yaffs_ReadChunkWithTagsFromNAND(dev,theChunk,NULL, &tags);
--					if(tags.objectId != objectId || tags.chunkId != chunkOffset){
--						T(~0,(TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
-+					yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL, &tags);
-+					if (tags.objectId != objectId || tags.chunkId != chunkOffset) {
-+						T(~0, (TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
- 							objectId, chunkOffset, theChunk,
- 							tags.objectId, tags.chunkId));
- 					}
-@@ -646,13 +650,15 @@ static void yaffs_VerifyFile(yaffs_Objec
- 	__u32 lastChunk;
- 	__u32 x;
- 	__u32 i;
--	int ok;
- 	yaffs_Device *dev;
- 	yaffs_ExtendedTags tags;
- 	yaffs_Tnode *tn;
- 	__u32 objectId;
- 
--	if(obj && yaffs_SkipVerification(obj->myDev))
-+	if (!obj)
-+		return;
-+
-+	if (yaffs_SkipVerification(obj->myDev))
- 		return;
- 
- 	dev = obj->myDev;
-@@ -662,17 +668,17 @@ static void yaffs_VerifyFile(yaffs_Objec
- 	lastChunk =  obj->variant.fileVariant.fileSize / dev->nDataBytesPerChunk + 1;
- 	x = lastChunk >> YAFFS_TNODES_LEVEL0_BITS;
- 	requiredTallness = 0;
--	while (x> 0) {
-+	while (x > 0) {
- 		x >>= YAFFS_TNODES_INTERNAL_BITS;
- 		requiredTallness++;
- 	}
- 
- 	actualTallness = obj->variant.fileVariant.topLevel;
- 
--	if(requiredTallness > actualTallness )
-+	if (requiredTallness > actualTallness)
- 		T(YAFFS_TRACE_VERIFY,
- 		(TSTR("Obj %d had tnode tallness %d, needs to be %d"TENDSTR),
--		 obj->objectId,actualTallness, requiredTallness));
-+		 obj->objectId, actualTallness, requiredTallness));
- 
- 
- 	/* Check that the chunks in the tnode tree are all correct.
-@@ -680,39 +686,31 @@ static void yaffs_VerifyFile(yaffs_Objec
- 	 * checking the tags for every chunk match.
- 	 */
- 
--	if(yaffs_SkipNANDVerification(dev))
-+	if (yaffs_SkipNANDVerification(dev))
- 		return;
- 
--	for(i = 1; i <= lastChunk; i++){
--		tn = yaffs_FindLevel0Tnode(dev, &obj->variant.fileVariant,i);
-+	for (i = 1; i <= lastChunk; i++) {
-+		tn = yaffs_FindLevel0Tnode(dev, &obj->variant.fileVariant, i);
- 
- 		if (tn) {
--			__u32 theChunk = yaffs_GetChunkGroupBase(dev,tn,i);
--			if(theChunk > 0){
-+			__u32 theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
-+			if (theChunk > 0) {
- 				/* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),objectId,i,theChunk)); */
--				yaffs_ReadChunkWithTagsFromNAND(dev,theChunk,NULL, &tags);
--				if(tags.objectId != objectId || tags.chunkId != i){
--					T(~0,(TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
-+				yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL, &tags);
-+				if (tags.objectId != objectId || tags.chunkId != i) {
-+					T(~0, (TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
- 						objectId, i, theChunk,
- 						tags.objectId, tags.chunkId));
- 				}
- 			}
- 		}
--
- 	}
--
- }
- 
--static void yaffs_VerifyDirectory(yaffs_Object *obj)
--{
--	if(obj && yaffs_SkipVerification(obj->myDev))
--		return;
--
--}
- 
- static void yaffs_VerifyHardLink(yaffs_Object *obj)
- {
--	if(obj && yaffs_SkipVerification(obj->myDev))
-+	if (obj && yaffs_SkipVerification(obj->myDev))
- 		return;
- 
- 	/* Verify sane equivalent object */
-@@ -720,7 +718,7 @@ static void yaffs_VerifyHardLink(yaffs_O
- 
- static void yaffs_VerifySymlink(yaffs_Object *obj)
- {
--	if(obj && yaffs_SkipVerification(obj->myDev))
-+	if (obj && yaffs_SkipVerification(obj->myDev))
- 		return;
- 
- 	/* Verify symlink string */
-@@ -728,7 +726,7 @@ static void yaffs_VerifySymlink(yaffs_Ob
- 
- static void yaffs_VerifySpecial(yaffs_Object *obj)
- {
--	if(obj && yaffs_SkipVerification(obj->myDev))
-+	if (obj && yaffs_SkipVerification(obj->myDev))
- 		return;
- }
- 
-@@ -740,14 +738,19 @@ static void yaffs_VerifyObject(yaffs_Obj
- 	__u32 chunkMax;
- 
- 	__u32 chunkIdOk;
--	__u32 chunkIsLive;
-+	__u32 chunkInRange;
-+	__u32 chunkShouldNotBeDeleted;
-+	__u32 chunkValid;
-+
-+	if (!obj)
-+		return;
- 
--	if(!obj)
-+	if (obj->beingCreated)
- 		return;
- 
- 	dev = obj->myDev;
- 
--	if(yaffs_SkipVerification(dev))
-+	if (yaffs_SkipVerification(dev))
- 		return;
- 
- 	/* Check sane object header chunk */
-@@ -755,50 +758,54 @@ static void yaffs_VerifyObject(yaffs_Obj
- 	chunkMin = dev->internalStartBlock * dev->nChunksPerBlock;
- 	chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1;
- 
--	chunkIdOk = (obj->chunkId >= chunkMin && obj->chunkId <= chunkMax);
--	chunkIsLive = chunkIdOk &&
-+	chunkInRange = (((unsigned)(obj->hdrChunk)) >= chunkMin && ((unsigned)(obj->hdrChunk)) <= chunkMax);
-+	chunkIdOk = chunkInRange || obj->hdrChunk == 0;
-+	chunkValid = chunkInRange &&
- 			yaffs_CheckChunkBit(dev,
--					    obj->chunkId / dev->nChunksPerBlock,
--					    obj->chunkId % dev->nChunksPerBlock);
--	if(!obj->fake &&
--	    (!chunkIdOk || !chunkIsLive)) {
--	   T(YAFFS_TRACE_VERIFY,
--	   (TSTR("Obj %d has chunkId %d %s %s"TENDSTR),
--	   obj->objectId,obj->chunkId,
--	   chunkIdOk ? "" : ",out of range",
--	   chunkIsLive || !chunkIdOk ? "" : ",marked as deleted"));
-+					obj->hdrChunk / dev->nChunksPerBlock,
-+					obj->hdrChunk % dev->nChunksPerBlock);
-+	chunkShouldNotBeDeleted = chunkInRange && !chunkValid;
-+
-+	if (!obj->fake &&
-+			(!chunkIdOk || chunkShouldNotBeDeleted)) {
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d has chunkId %d %s %s"TENDSTR),
-+			obj->objectId, obj->hdrChunk,
-+			chunkIdOk ? "" : ",out of range",
-+			chunkShouldNotBeDeleted ? ",marked as deleted" : ""));
- 	}
- 
--	if(chunkIdOk && chunkIsLive &&!yaffs_SkipNANDVerification(dev)) {
-+	if (chunkValid && !yaffs_SkipNANDVerification(dev)) {
- 		yaffs_ExtendedTags tags;
- 		yaffs_ObjectHeader *oh;
--		__u8 *buffer = yaffs_GetTempBuffer(dev,__LINE__);
-+		__u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
- 
- 		oh = (yaffs_ObjectHeader *)buffer;
- 
--		yaffs_ReadChunkWithTagsFromNAND(dev, obj->chunkId,buffer, &tags);
-+		yaffs_ReadChunkWithTagsFromNAND(dev, obj->hdrChunk, buffer,
-+				&tags);
- 
--		yaffs_VerifyObjectHeader(obj,oh,&tags,1);
-+		yaffs_VerifyObjectHeader(obj, oh, &tags, 1);
- 
--		yaffs_ReleaseTempBuffer(dev,buffer,__LINE__);
-+		yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
- 	}
- 
- 	/* Verify it has a parent */
--	if(obj && !obj->fake &&
--	   (!obj->parent || obj->parent->myDev != dev)){
--	   T(YAFFS_TRACE_VERIFY,
--	   (TSTR("Obj %d has parent pointer %p which does not look like an object"TENDSTR),
--	   obj->objectId,obj->parent));
-+	if (obj && !obj->fake &&
-+			(!obj->parent || obj->parent->myDev != dev)) {
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d has parent pointer %p which does not look like an object"TENDSTR),
-+			obj->objectId, obj->parent));
- 	}
- 
- 	/* Verify parent is a directory */
--	if(obj->parent && obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY){
--	   T(YAFFS_TRACE_VERIFY,
--	   (TSTR("Obj %d's parent is not a directory (type %d)"TENDSTR),
--	   obj->objectId,obj->parent->variantType));
-+	if (obj->parent && obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d's parent is not a directory (type %d)"TENDSTR),
-+			obj->objectId, obj->parent->variantType));
- 	}
- 
--	switch(obj->variantType){
-+	switch (obj->variantType) {
- 	case YAFFS_OBJECT_TYPE_FILE:
- 		yaffs_VerifyFile(obj);
- 		break;
-@@ -818,33 +825,30 @@ static void yaffs_VerifyObject(yaffs_Obj
- 	default:
- 		T(YAFFS_TRACE_VERIFY,
- 		(TSTR("Obj %d has illegaltype %d"TENDSTR),
--		obj->objectId,obj->variantType));
-+		obj->objectId, obj->variantType));
- 		break;
- 	}
--
--
- }
- 
- static void yaffs_VerifyObjects(yaffs_Device *dev)
- {
- 	yaffs_Object *obj;
- 	int i;
--	struct list_head *lh;
-+	struct ylist_head *lh;
- 
--	if(yaffs_SkipVerification(dev))
-+	if (yaffs_SkipVerification(dev))
- 		return;
- 
- 	/* Iterate through the objects in each hash entry */
- 
--	 for(i = 0; i <  YAFFS_NOBJECT_BUCKETS; i++){
--	 	list_for_each(lh, &dev->objectBucket[i].list) {
-+	for (i = 0; i <  YAFFS_NOBJECT_BUCKETS; i++) {
-+		ylist_for_each(lh, &dev->objectBucket[i].list) {
- 			if (lh) {
--				obj = list_entry(lh, yaffs_Object, hashLink);
-+				obj = ylist_entry(lh, yaffs_Object, hashLink);
- 				yaffs_VerifyObject(obj);
- 			}
- 		}
--	 }
--
-+	}
- }
- 
- 
-@@ -855,19 +859,20 @@ static void yaffs_VerifyObjects(yaffs_De
- static Y_INLINE int yaffs_HashFunction(int n)
- {
- 	n = abs(n);
--	return (n % YAFFS_NOBJECT_BUCKETS);
-+	return n % YAFFS_NOBJECT_BUCKETS;
- }
- 
- /*
-- * Access functions to useful fake objects
-+ * Access functions to useful fake objects.
-+ * Note that root might have a presence in NAND if permissions are set.
-  */
- 
--yaffs_Object *yaffs_Root(yaffs_Device * dev)
-+yaffs_Object *yaffs_Root(yaffs_Device *dev)
- {
- 	return dev->rootDir;
- }
- 
--yaffs_Object *yaffs_LostNFound(yaffs_Device * dev)
-+yaffs_Object *yaffs_LostNFound(yaffs_Device *dev)
- {
- 	return dev->lostNFoundDir;
- }
-@@ -877,7 +882,7 @@ yaffs_Object *yaffs_LostNFound(yaffs_Dev
-  *  Erased NAND checking functions
-  */
- 
--int yaffs_CheckFF(__u8 * buffer, int nBytes)
-+int yaffs_CheckFF(__u8 *buffer, int nBytes)
- {
- 	/* Horrible, slow implementation */
- 	while (nBytes--) {
-@@ -889,9 +894,8 @@ int yaffs_CheckFF(__u8 * buffer, int nBy
- }
- 
- static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
--				  int chunkInNAND)
-+				int chunkInNAND)
- {
--
- 	int retval = YAFFS_OK;
- 	__u8 *data = yaffs_GetTempBuffer(dev, __LINE__);
- 	yaffs_ExtendedTags tags;
-@@ -899,10 +903,9 @@ static int yaffs_CheckChunkErased(struct
- 
- 	result = yaffs_ReadChunkWithTagsFromNAND(dev, chunkInNAND, data, &tags);
- 
--	if(tags.eccResult > YAFFS_ECC_RESULT_NO_ERROR)
-+	if (tags.eccResult > YAFFS_ECC_RESULT_NO_ERROR)
- 		retval = YAFFS_FAIL;
- 
--
- 	if (!yaffs_CheckFF(data, dev->nDataBytesPerChunk) || tags.chunkUsed) {
- 		T(YAFFS_TRACE_NANDACCESS,
- 		  (TSTR("Chunk %d not erased" TENDSTR), chunkInNAND));
-@@ -915,11 +918,10 @@ static int yaffs_CheckChunkErased(struct
- 
- }
- 
--
- static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
--					     const __u8 * data,
--					     yaffs_ExtendedTags * tags,
--					     int useReserve)
-+					const __u8 *data,
-+					yaffs_ExtendedTags *tags,
-+					int useReserve)
- {
- 	int attempts = 0;
- 	int writeOk = 0;
-@@ -972,7 +974,7 @@ static int yaffs_WriteNewChunkWithTagsTo
- 			erasedOk = yaffs_CheckChunkErased(dev, chunk);
- 			if (erasedOk != YAFFS_OK) {
- 				T(YAFFS_TRACE_ERROR,
--				(TSTR ("**>> yaffs chunk %d was not erased"
-+				(TSTR("**>> yaffs chunk %d was not erased"
- 				TENDSTR), chunk));
- 
- 				/* try another chunk */
-@@ -992,7 +994,11 @@ static int yaffs_WriteNewChunkWithTagsTo
- 		/* Copy the data into the robustification buffer */
- 		yaffs_HandleWriteChunkOk(dev, chunk, data, tags);
- 
--	} while (writeOk != YAFFS_OK && attempts < yaffs_wr_attempts);
-+	} while (writeOk != YAFFS_OK &&
-+		(yaffs_wr_attempts <= 0 || attempts <= yaffs_wr_attempts));
-+
-+	if (!writeOk)
-+		chunk = -1;
- 
- 	if (attempts > 1) {
- 		T(YAFFS_TRACE_ERROR,
-@@ -1009,13 +1015,35 @@ static int yaffs_WriteNewChunkWithTagsTo
-  * Block retiring for handling a broken block.
-  */
- 
--static void yaffs_RetireBlock(yaffs_Device * dev, int blockInNAND)
-+static void yaffs_RetireBlock(yaffs_Device *dev, int blockInNAND)
- {
- 	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);
- 
- 	yaffs_InvalidateCheckpoint(dev);
- 
--	yaffs_MarkBlockBad(dev, blockInNAND);
-+	if (yaffs_MarkBlockBad(dev, blockInNAND) != YAFFS_OK) {
-+		if (yaffs_EraseBlockInNAND(dev, blockInNAND) != YAFFS_OK) {
-+			T(YAFFS_TRACE_ALWAYS, (TSTR(
-+				"yaffs: Failed to mark bad and erase block %d"
-+				TENDSTR), blockInNAND));
-+		} else {
-+			yaffs_ExtendedTags tags;
-+			int chunkId = blockInNAND * dev->nChunksPerBlock;
-+
-+			__u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
-+
-+			memset(buffer, 0xff, dev->nDataBytesPerChunk);
-+			yaffs_InitialiseTags(&tags);
-+			tags.sequenceNumber = YAFFS_SEQUENCE_BAD_BLOCK;
-+			if (dev->writeChunkWithTagsToNAND(dev, chunkId -
-+				dev->chunkOffset, buffer, &tags) != YAFFS_OK)
-+				T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Failed to "
-+					TCONT("write bad block marker to block %d")
-+					TENDSTR), blockInNAND));
-+
-+			yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
-+		}
-+	}
- 
- 	bi->blockState = YAFFS_BLOCK_STATE_DEAD;
- 	bi->gcPrioritise = 0;
-@@ -1029,49 +1057,45 @@ static void yaffs_RetireBlock(yaffs_Devi
-  *
-  */
- 
--static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
--				     const __u8 * data,
--				     const yaffs_ExtendedTags * tags)
-+static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
-+				const __u8 *data,
-+				const yaffs_ExtendedTags *tags)
- {
- }
- 
--static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
--				    const yaffs_ExtendedTags * tags)
-+static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
-+				const yaffs_ExtendedTags *tags)
- {
- }
- 
- void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi)
- {
--	if(!bi->gcPrioritise){
-+	if (!bi->gcPrioritise) {
- 		bi->gcPrioritise = 1;
- 		dev->hasPendingPrioritisedGCs = 1;
--		bi->chunkErrorStrikes ++;
-+		bi->chunkErrorStrikes++;
- 
--		if(bi->chunkErrorStrikes > 3){
-+		if (bi->chunkErrorStrikes > 3) {
- 			bi->needsRetiring = 1; /* Too many stikes, so retire this */
- 			T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Block struck out" TENDSTR)));
- 
- 		}
--
- 	}
- }
- 
--static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND, int erasedOk)
-+static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND,
-+		int erasedOk)
- {
--
- 	int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
- 	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);
- 
--	yaffs_HandleChunkError(dev,bi);
-+	yaffs_HandleChunkError(dev, bi);
- 
--
--	if(erasedOk ) {
-+	if (erasedOk) {
- 		/* Was an actual write failure, so mark the block for retirement  */
- 		bi->needsRetiring = 1;
- 		T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
- 		  (TSTR("**>> Block %d needs retiring" TENDSTR), blockInNAND));
--
--
- 	}
- 
- 	/* Delete the chunk */
-@@ -1081,12 +1105,12 @@ static void yaffs_HandleWriteChunkError(
- 
- /*---------------- Name handling functions ------------*/
- 
--static __u16 yaffs_CalcNameSum(const YCHAR * name)
-+static __u16 yaffs_CalcNameSum(const YCHAR *name)
- {
- 	__u16 sum = 0;
- 	__u16 i = 1;
- 
--	YUCHAR *bname = (YUCHAR *) name;
-+	const YUCHAR *bname = (const YUCHAR *) name;
- 	if (bname) {
- 		while ((*bname) && (i < (YAFFS_MAX_NAME_LENGTH/2))) {
- 
-@@ -1102,14 +1126,14 @@ static __u16 yaffs_CalcNameSum(const YCH
- 	return sum;
- }
- 
--static void yaffs_SetObjectName(yaffs_Object * obj, const YCHAR * name)
-+static void yaffs_SetObjectName(yaffs_Object *obj, const YCHAR *name)
- {
- #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
--	if (name && yaffs_strlen(name) <= YAFFS_SHORT_NAME_LENGTH) {
-+	memset(obj->shortName, 0, sizeof(YCHAR) * (YAFFS_SHORT_NAME_LENGTH+1));
-+	if (name && yaffs_strlen(name) <= YAFFS_SHORT_NAME_LENGTH)
- 		yaffs_strcpy(obj->shortName, name);
--	} else {
-+	else
- 		obj->shortName[0] = _Y('\0');
--	}
- #endif
- 	obj->sum = yaffs_CalcNameSum(name);
- }
-@@ -1126,7 +1150,7 @@ static void yaffs_SetObjectName(yaffs_Ob
-  * Don't use this function directly
-  */
- 
--static int yaffs_CreateTnodes(yaffs_Device * dev, int nTnodes)
-+static int yaffs_CreateTnodes(yaffs_Device *dev, int nTnodes)
- {
- 	int i;
- 	int tnodeSize;
-@@ -1143,6 +1167,9 @@ static int yaffs_CreateTnodes(yaffs_Devi
- 	 * Must be a multiple of 32-bits  */
- 	tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
- 
-+	if (tnodeSize < sizeof(yaffs_Tnode))
-+		tnodeSize = sizeof(yaffs_Tnode);
-+
- 	/* make these things */
- 
- 	newTnodes = YMALLOC(nTnodes * tnodeSize);
-@@ -1150,7 +1177,7 @@ static int yaffs_CreateTnodes(yaffs_Devi
- 
- 	if (!newTnodes) {
- 		T(YAFFS_TRACE_ERROR,
--		  (TSTR("yaffs: Could not allocate Tnodes" TENDSTR)));
-+			(TSTR("yaffs: Could not allocate Tnodes" TENDSTR)));
- 		return YAFFS_FAIL;
- 	}
- 
-@@ -1170,7 +1197,7 @@ static int yaffs_CreateTnodes(yaffs_Devi
- 	dev->freeTnodes = newTnodes;
- #else
- 	/* New hookup for wide tnodes */
--	for(i = 0; i < nTnodes -1; i++) {
-+	for (i = 0; i < nTnodes - 1; i++) {
- 		curr = (yaffs_Tnode *) &mem[i * tnodeSize];
- 		next = (yaffs_Tnode *) &mem[(i+1) * tnodeSize];
- 		curr->internal[0] = next;
-@@ -1197,7 +1224,6 @@ static int yaffs_CreateTnodes(yaffs_Devi
- 		  (TSTR
- 		   ("yaffs: Could not add tnodes to management list" TENDSTR)));
- 		   return YAFFS_FAIL;
--
- 	} else {
- 		tnl->tnodes = newTnodes;
- 		tnl->next = dev->allocatedTnodeList;
-@@ -1211,14 +1237,13 @@ static int yaffs_CreateTnodes(yaffs_Devi
- 
- /* GetTnode gets us a clean tnode. Tries to make allocate more if we run out */
- 
--static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device * dev)
-+static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device *dev)
- {
- 	yaffs_Tnode *tn = NULL;
- 
- 	/* If there are none left make more */
--	if (!dev->freeTnodes) {
-+	if (!dev->freeTnodes)
- 		yaffs_CreateTnodes(dev, YAFFS_ALLOCATION_NTNODES);
--	}
- 
- 	if (dev->freeTnodes) {
- 		tn = dev->freeTnodes;
-@@ -1233,21 +1258,27 @@ static yaffs_Tnode *yaffs_GetTnodeRaw(ya
- 		dev->nFreeTnodes--;
- 	}
- 
-+	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
-+
- 	return tn;
- }
- 
--static yaffs_Tnode *yaffs_GetTnode(yaffs_Device * dev)
-+static yaffs_Tnode *yaffs_GetTnode(yaffs_Device *dev)
- {
- 	yaffs_Tnode *tn = yaffs_GetTnodeRaw(dev);
-+	int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
- 
--	if(tn)
--		memset(tn, 0, (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
-+	if (tnodeSize < sizeof(yaffs_Tnode))
-+		tnodeSize = sizeof(yaffs_Tnode);
-+
-+	if (tn)
-+		memset(tn, 0, tnodeSize);
- 
- 	return tn;
- }
- 
- /* FreeTnode frees up a tnode and puts it back on the free list */
--static void yaffs_FreeTnode(yaffs_Device * dev, yaffs_Tnode * tn)
-+static void yaffs_FreeTnode(yaffs_Device *dev, yaffs_Tnode *tn)
- {
- 	if (tn) {
- #ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
-@@ -1262,9 +1293,10 @@ static void yaffs_FreeTnode(yaffs_Device
- 		dev->freeTnodes = tn;
- 		dev->nFreeTnodes++;
- 	}
-+	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
- }
- 
--static void yaffs_DeinitialiseTnodes(yaffs_Device * dev)
-+static void yaffs_DeinitialiseTnodes(yaffs_Device *dev)
- {
- 	/* Free the list of allocated tnodes */
- 	yaffs_TnodeList *tmp;
-@@ -1282,71 +1314,72 @@ static void yaffs_DeinitialiseTnodes(yaf
- 	dev->nFreeTnodes = 0;
- }
- 
--static void yaffs_InitialiseTnodes(yaffs_Device * dev)
-+static void yaffs_InitialiseTnodes(yaffs_Device *dev)
- {
- 	dev->allocatedTnodeList = NULL;
- 	dev->freeTnodes = NULL;
- 	dev->nFreeTnodes = 0;
- 	dev->nTnodesCreated = 0;
--
- }
- 
- 
--void yaffs_PutLevel0Tnode(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos, unsigned val)
-+void yaffs_PutLevel0Tnode(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos,
-+		unsigned val)
- {
--  __u32 *map = (__u32 *)tn;
--  __u32 bitInMap;
--  __u32 bitInWord;
--  __u32 wordInMap;
--  __u32 mask;
-+	__u32 *map = (__u32 *)tn;
-+	__u32 bitInMap;
-+	__u32 bitInWord;
-+	__u32 wordInMap;
-+	__u32 mask;
- 
--  pos &= YAFFS_TNODES_LEVEL0_MASK;
--  val >>= dev->chunkGroupBits;
-+	pos &= YAFFS_TNODES_LEVEL0_MASK;
-+	val >>= dev->chunkGroupBits;
- 
--  bitInMap = pos * dev->tnodeWidth;
--  wordInMap = bitInMap /32;
--  bitInWord = bitInMap & (32 -1);
-+	bitInMap = pos * dev->tnodeWidth;
-+	wordInMap = bitInMap / 32;
-+	bitInWord = bitInMap & (32 - 1);
- 
--  mask = dev->tnodeMask << bitInWord;
-+	mask = dev->tnodeMask << bitInWord;
- 
--  map[wordInMap] &= ~mask;
--  map[wordInMap] |= (mask & (val << bitInWord));
-+	map[wordInMap] &= ~mask;
-+	map[wordInMap] |= (mask & (val << bitInWord));
- 
--  if(dev->tnodeWidth > (32-bitInWord)) {
--    bitInWord = (32 - bitInWord);
--    wordInMap++;;
--    mask = dev->tnodeMask >> (/*dev->tnodeWidth -*/ bitInWord);
--    map[wordInMap] &= ~mask;
--    map[wordInMap] |= (mask & (val >> bitInWord));
--  }
-+	if (dev->tnodeWidth > (32 - bitInWord)) {
-+		bitInWord = (32 - bitInWord);
-+		wordInMap++;;
-+		mask = dev->tnodeMask >> (/*dev->tnodeWidth -*/ bitInWord);
-+		map[wordInMap] &= ~mask;
-+		map[wordInMap] |= (mask & (val >> bitInWord));
-+	}
- }
- 
--static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos)
-+static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn,
-+		unsigned pos)
- {
--  __u32 *map = (__u32 *)tn;
--  __u32 bitInMap;
--  __u32 bitInWord;
--  __u32 wordInMap;
--  __u32 val;
-+	__u32 *map = (__u32 *)tn;
-+	__u32 bitInMap;
-+	__u32 bitInWord;
-+	__u32 wordInMap;
-+	__u32 val;
- 
--  pos &= YAFFS_TNODES_LEVEL0_MASK;
-+	pos &= YAFFS_TNODES_LEVEL0_MASK;
- 
--  bitInMap = pos * dev->tnodeWidth;
--  wordInMap = bitInMap /32;
--  bitInWord = bitInMap & (32 -1);
-+	bitInMap = pos * dev->tnodeWidth;
-+	wordInMap = bitInMap / 32;
-+	bitInWord = bitInMap & (32 - 1);
- 
--  val = map[wordInMap] >> bitInWord;
-+	val = map[wordInMap] >> bitInWord;
- 
--  if(dev->tnodeWidth > (32-bitInWord)) {
--    bitInWord = (32 - bitInWord);
--    wordInMap++;;
--    val |= (map[wordInMap] << bitInWord);
--  }
-+	if	(dev->tnodeWidth > (32 - bitInWord)) {
-+		bitInWord = (32 - bitInWord);
-+		wordInMap++;;
-+		val |= (map[wordInMap] << bitInWord);
-+	}
- 
--  val &= dev->tnodeMask;
--  val <<= dev->chunkGroupBits;
-+	val &= dev->tnodeMask;
-+	val <<= dev->chunkGroupBits;
- 
--  return val;
-+	return val;
- }
- 
- /* ------------------- End of individual tnode manipulation -----------------*/
-@@ -1357,24 +1390,21 @@ static __u32 yaffs_GetChunkGroupBase(yaf
-  */
- 
- /* FindLevel0Tnode finds the level 0 tnode, if one exists. */
--static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device * dev,
--					  yaffs_FileStructure * fStruct,
--					  __u32 chunkId)
-+static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device *dev,
-+					yaffs_FileStructure *fStruct,
-+					__u32 chunkId)
- {
--
- 	yaffs_Tnode *tn = fStruct->top;
- 	__u32 i;
- 	int requiredTallness;
- 	int level = fStruct->topLevel;
- 
- 	/* Check sane level and chunk Id */
--	if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL) {
-+	if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL)
- 		return NULL;
--	}
- 
--	if (chunkId > YAFFS_MAX_CHUNK_ID) {
-+	if (chunkId > YAFFS_MAX_CHUNK_ID)
- 		return NULL;
--	}
- 
- 	/* First check we're tall enough (ie enough topLevel) */
- 
-@@ -1385,22 +1415,17 @@ static yaffs_Tnode *yaffs_FindLevel0Tnod
- 		requiredTallness++;
- 	}
- 
--	if (requiredTallness > fStruct->topLevel) {
--		/* Not tall enough, so we can't find it, return NULL. */
--		return NULL;
--	}
-+	if (requiredTallness > fStruct->topLevel)
-+		return NULL; /* Not tall enough, so we can't find it */
- 
- 	/* Traverse down to level 0 */
- 	while (level > 0 && tn) {
--		tn = tn->
--		    internal[(chunkId >>
--			       ( YAFFS_TNODES_LEVEL0_BITS +
--			         (level - 1) *
--			         YAFFS_TNODES_INTERNAL_BITS)
--			      ) &
--			     YAFFS_TNODES_INTERNAL_MASK];
-+		tn = tn->internal[(chunkId >>
-+			(YAFFS_TNODES_LEVEL0_BITS +
-+				(level - 1) *
-+				YAFFS_TNODES_INTERNAL_BITS)) &
-+			YAFFS_TNODES_INTERNAL_MASK];
- 		level--;
--
- 	}
- 
- 	return tn;
-@@ -1417,12 +1442,11 @@ static yaffs_Tnode *yaffs_FindLevel0Tnod
-  *  be plugged into the ttree.
-  */
- 
--static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device * dev,
--					       yaffs_FileStructure * fStruct,
--					       __u32 chunkId,
--					       yaffs_Tnode *passedTn)
-+static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device *dev,
-+					yaffs_FileStructure *fStruct,
-+					__u32 chunkId,
-+					yaffs_Tnode *passedTn)
- {
--
- 	int requiredTallness;
- 	int i;
- 	int l;
-@@ -1432,13 +1456,11 @@ static yaffs_Tnode *yaffs_AddOrFindLevel
- 
- 
- 	/* Check sane level and page Id */
--	if (fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL) {
-+	if (fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL)
- 		return NULL;
--	}
- 
--	if (chunkId > YAFFS_MAX_CHUNK_ID) {
-+	if (chunkId > YAFFS_MAX_CHUNK_ID)
- 		return NULL;
--	}
- 
- 	/* First check we're tall enough (ie enough topLevel) */
- 
-@@ -1451,7 +1473,7 @@ static yaffs_Tnode *yaffs_AddOrFindLevel
- 
- 
- 	if (requiredTallness > fStruct->topLevel) {
--		/* Not tall enough,gotta make the tree taller */
-+		/* Not tall enough, gotta make the tree taller */
- 		for (i = fStruct->topLevel; i < requiredTallness; i++) {
- 
- 			tn = yaffs_GetTnode(dev);
-@@ -1473,27 +1495,27 @@ static yaffs_Tnode *yaffs_AddOrFindLevel
- 	l = fStruct->topLevel;
- 	tn = fStruct->top;
- 
--	if(l > 0) {
-+	if (l > 0) {
- 		while (l > 0 && tn) {
- 			x = (chunkId >>
--			     ( YAFFS_TNODES_LEVEL0_BITS +
-+			     (YAFFS_TNODES_LEVEL0_BITS +
- 			      (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) &
- 			    YAFFS_TNODES_INTERNAL_MASK;
- 
- 
--			if((l>1) && !tn->internal[x]){
-+			if ((l > 1) && !tn->internal[x]) {
- 				/* Add missing non-level-zero tnode */
- 				tn->internal[x] = yaffs_GetTnode(dev);
- 
--			} else if(l == 1) {
-+			} else if (l == 1) {
- 				/* Looking from level 1 at level 0 */
--			 	if (passedTn) {
-+				if (passedTn) {
- 					/* If we already have one, then release it.*/
--					if(tn->internal[x])
--						yaffs_FreeTnode(dev,tn->internal[x]);
-+					if (tn->internal[x])
-+						yaffs_FreeTnode(dev, tn->internal[x]);
- 					tn->internal[x] = passedTn;
- 
--				} else if(!tn->internal[x]) {
-+				} else if (!tn->internal[x]) {
- 					/* Don't have one, none passed in */
- 					tn->internal[x] = yaffs_GetTnode(dev);
- 				}
-@@ -1504,31 +1526,29 @@ static yaffs_Tnode *yaffs_AddOrFindLevel
- 		}
- 	} else {
- 		/* top is level 0 */
--		if(passedTn) {
--			memcpy(tn,passedTn,(dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
--			yaffs_FreeTnode(dev,passedTn);
-+		if (passedTn) {
-+			memcpy(tn, passedTn, (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
-+			yaffs_FreeTnode(dev, passedTn);
- 		}
- 	}
- 
- 	return tn;
- }
- 
--static int yaffs_FindChunkInGroup(yaffs_Device * dev, int theChunk,
--				  yaffs_ExtendedTags * tags, int objectId,
--				  int chunkInInode)
-+static int yaffs_FindChunkInGroup(yaffs_Device *dev, int theChunk,
-+				yaffs_ExtendedTags *tags, int objectId,
-+				int chunkInInode)
- {
- 	int j;
- 
- 	for (j = 0; theChunk && j < dev->chunkGroupSize; j++) {
--		if (yaffs_CheckChunkBit
--		    (dev, theChunk / dev->nChunksPerBlock,
--		     theChunk % dev->nChunksPerBlock)) {
-+		if (yaffs_CheckChunkBit(dev, theChunk / dev->nChunksPerBlock,
-+				theChunk % dev->nChunksPerBlock)) {
- 			yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL,
- 							tags);
- 			if (yaffs_TagsMatch(tags, objectId, chunkInInode)) {
- 				/* found it; */
- 				return theChunk;
--
- 			}
- 		}
- 		theChunk++;
-@@ -1543,7 +1563,7 @@ static int yaffs_FindChunkInGroup(yaffs_
-  * Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.
-  */
- 
--static int yaffs_DeleteWorker(yaffs_Object * in, yaffs_Tnode * tn, __u32 level,
-+static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level,
- 			      int chunkOffset, int *limit)
- {
- 	int i;
-@@ -1557,7 +1577,6 @@ static int yaffs_DeleteWorker(yaffs_Obje
- 
- 	if (tn) {
- 		if (level > 0) {
--
- 			for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0;
- 			     i--) {
- 				if (tn->internal[i]) {
-@@ -1565,17 +1584,17 @@ static int yaffs_DeleteWorker(yaffs_Obje
- 						allDone = 0;
- 					} else {
- 						allDone =
--						    yaffs_DeleteWorker(in,
--								       tn->
--								       internal
--								       [i],
--								       level -
--								       1,
--								       (chunkOffset
-+							yaffs_DeleteWorker(in,
-+								tn->
-+								internal
-+								[i],
-+								level -
-+								1,
-+								(chunkOffset
- 									<<
- 									YAFFS_TNODES_INTERNAL_BITS)
--								       + i,
--								       limit);
-+								+ i,
-+								limit);
- 					}
- 					if (allDone) {
- 						yaffs_FreeTnode(dev,
-@@ -1584,27 +1603,25 @@ static int yaffs_DeleteWorker(yaffs_Obje
- 						tn->internal[i] = NULL;
- 					}
- 				}
--
- 			}
- 			return (allDone) ? 1 : 0;
- 		} else if (level == 0) {
- 			int hitLimit = 0;
- 
- 			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0 && !hitLimit;
--			     i--) {
--			        theChunk = yaffs_GetChunkGroupBase(dev,tn,i);
-+					i--) {
-+				theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
- 				if (theChunk) {
- 
--					chunkInInode =
--					    (chunkOffset <<
--					     YAFFS_TNODES_LEVEL0_BITS) + i;
-+					chunkInInode = (chunkOffset <<
-+						YAFFS_TNODES_LEVEL0_BITS) + i;
- 
- 					foundChunk =
--					    yaffs_FindChunkInGroup(dev,
--								   theChunk,
--								   &tags,
--								   in->objectId,
--								   chunkInInode);
-+						yaffs_FindChunkInGroup(dev,
-+								theChunk,
-+								&tags,
-+								in->objectId,
-+								chunkInInode);
- 
- 					if (foundChunk > 0) {
- 						yaffs_DeleteChunk(dev,
-@@ -1613,14 +1630,13 @@ static int yaffs_DeleteWorker(yaffs_Obje
- 						in->nDataChunks--;
- 						if (limit) {
- 							*limit = *limit - 1;
--							if (*limit <= 0) {
-+							if (*limit <= 0)
- 								hitLimit = 1;
--							}
- 						}
- 
- 					}
- 
--					yaffs_PutLevel0Tnode(dev,tn,i,0);
-+					yaffs_PutLevel0Tnode(dev, tn, i, 0);
- 				}
- 
- 			}
-@@ -1634,9 +1650,8 @@ static int yaffs_DeleteWorker(yaffs_Obje
- 
- }
- 
--static void yaffs_SoftDeleteChunk(yaffs_Device * dev, int chunk)
-+static void yaffs_SoftDeleteChunk(yaffs_Device *dev, int chunk)
- {
--
- 	yaffs_BlockInfo *theBlock;
- 
- 	T(YAFFS_TRACE_DELETION, (TSTR("soft delete chunk %d" TENDSTR), chunk));
-@@ -1654,7 +1669,7 @@ static void yaffs_SoftDeleteChunk(yaffs_
-  * Thus, essentially this is the same as DeleteWorker except that the chunks are soft deleted.
-  */
- 
--static int yaffs_SoftDeleteWorker(yaffs_Object * in, yaffs_Tnode * tn,
-+static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn,
- 				  __u32 level, int chunkOffset)
- {
- 	int i;
-@@ -1691,14 +1706,14 @@ static int yaffs_SoftDeleteWorker(yaffs_
- 		} else if (level == 0) {
- 
- 			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) {
--				theChunk = yaffs_GetChunkGroupBase(dev,tn,i);
-+				theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
- 				if (theChunk) {
- 					/* Note this does not find the real chunk, only the chunk group.
- 					 * We make an assumption that a chunk group is not larger than
- 					 * a block.
- 					 */
- 					yaffs_SoftDeleteChunk(dev, theChunk);
--					yaffs_PutLevel0Tnode(dev,tn,i,0);
-+					yaffs_PutLevel0Tnode(dev, tn, i, 0);
- 				}
- 
- 			}
-@@ -1712,7 +1727,7 @@ static int yaffs_SoftDeleteWorker(yaffs_
- 
- }
- 
--static void yaffs_SoftDeleteFile(yaffs_Object * obj)
-+static void yaffs_SoftDeleteFile(yaffs_Object *obj)
- {
- 	if (obj->deleted &&
- 	    obj->variantType == YAFFS_OBJECT_TYPE_FILE && !obj->softDeleted) {
-@@ -1746,8 +1761,8 @@ static void yaffs_SoftDeleteFile(yaffs_O
-  * by a special case.
-  */
- 
--static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device * dev, yaffs_Tnode * tn,
--				      __u32 level, int del0)
-+static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device *dev, yaffs_Tnode *tn,
-+				__u32 level, int del0)
- {
- 	int i;
- 	int hasData;
-@@ -1763,9 +1778,8 @@ static yaffs_Tnode *yaffs_PruneWorker(ya
- 						      (i == 0) ? del0 : 1);
- 			}
- 
--			if (tn->internal[i]) {
-+			if (tn->internal[i])
- 				hasData++;
--			}
- 		}
- 
- 		if (hasData == 0 && del0) {
-@@ -1781,8 +1795,8 @@ static yaffs_Tnode *yaffs_PruneWorker(ya
- 
- }
- 
--static int yaffs_PruneFileStructure(yaffs_Device * dev,
--				    yaffs_FileStructure * fStruct)
-+static int yaffs_PruneFileStructure(yaffs_Device *dev,
-+				yaffs_FileStructure *fStruct)
- {
- 	int i;
- 	int hasData;
-@@ -1805,9 +1819,8 @@ static int yaffs_PruneFileStructure(yaff
- 
- 			hasData = 0;
- 			for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {
--				if (tn->internal[i]) {
-+				if (tn->internal[i])
- 					hasData++;
--				}
- 			}
- 
- 			if (!hasData) {
-@@ -1828,7 +1841,7 @@ static int yaffs_PruneFileStructure(yaff
- /* yaffs_CreateFreeObjects creates a bunch more objects and
-  * adds them to the object free list.
-  */
--static int yaffs_CreateFreeObjects(yaffs_Device * dev, int nObjects)
-+static int yaffs_CreateFreeObjects(yaffs_Device *dev, int nObjects)
- {
- 	int i;
- 	yaffs_Object *newObjects;
-@@ -1842,9 +1855,9 @@ static int yaffs_CreateFreeObjects(yaffs
- 	list = YMALLOC(sizeof(yaffs_ObjectList));
- 
- 	if (!newObjects || !list) {
--		if(newObjects)
-+		if (newObjects)
- 			YFREE(newObjects);
--		if(list)
-+		if (list)
- 			YFREE(list);
- 		T(YAFFS_TRACE_ALLOCATE,
- 		  (TSTR("yaffs: Could not allocate more objects" TENDSTR)));
-@@ -1854,7 +1867,7 @@ static int yaffs_CreateFreeObjects(yaffs
- 	/* Hook them into the free list */
- 	for (i = 0; i < nObjects - 1; i++) {
- 		newObjects[i].siblings.next =
--		    (struct list_head *)(&newObjects[i + 1]);
-+				(struct ylist_head *)(&newObjects[i + 1]);
- 	}
- 
- 	newObjects[nObjects - 1].siblings.next = (void *)dev->freeObjects;
-@@ -1873,85 +1886,109 @@ static int yaffs_CreateFreeObjects(yaffs
- 
- 
- /* AllocateEmptyObject gets us a clean Object. Tries to make allocate more if we run out */
--static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device * dev)
-+static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device *dev)
- {
- 	yaffs_Object *tn = NULL;
- 
-+#ifdef VALGRIND_TEST
-+	tn = YMALLOC(sizeof(yaffs_Object));
-+#else
- 	/* If there are none left make more */
--	if (!dev->freeObjects) {
-+	if (!dev->freeObjects)
- 		yaffs_CreateFreeObjects(dev, YAFFS_ALLOCATION_NOBJECTS);
--	}
- 
- 	if (dev->freeObjects) {
- 		tn = dev->freeObjects;
- 		dev->freeObjects =
--		    (yaffs_Object *) (dev->freeObjects->siblings.next);
-+			(yaffs_Object *) (dev->freeObjects->siblings.next);
- 		dev->nFreeObjects--;
--
-+	}
-+#endif
-+	if (tn) {
- 		/* Now sweeten it up... */
- 
- 		memset(tn, 0, sizeof(yaffs_Object));
-+		tn->beingCreated = 1;
-+
- 		tn->myDev = dev;
--		tn->chunkId = -1;
-+		tn->hdrChunk = 0;
- 		tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN;
--		INIT_LIST_HEAD(&(tn->hardLinks));
--		INIT_LIST_HEAD(&(tn->hashLink));
--		INIT_LIST_HEAD(&tn->siblings);
-+		YINIT_LIST_HEAD(&(tn->hardLinks));
-+		YINIT_LIST_HEAD(&(tn->hashLink));
-+		YINIT_LIST_HEAD(&tn->siblings);
-+
-+
-+		/* Now make the directory sane */
-+		if (dev->rootDir) {
-+			tn->parent = dev->rootDir;
-+			ylist_add(&(tn->siblings), &dev->rootDir->variant.directoryVariant.children);
-+		}
- 
- 		/* Add it to the lost and found directory.
- 		 * NB Can't put root or lostNFound in lostNFound so
- 		 * check if lostNFound exists first
- 		 */
--		if (dev->lostNFoundDir) {
-+		if (dev->lostNFoundDir)
- 			yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn);
--		}
-+
-+		tn->beingCreated = 0;
- 	}
- 
-+	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
-+
- 	return tn;
- }
- 
--static yaffs_Object *yaffs_CreateFakeDirectory(yaffs_Device * dev, int number,
-+static yaffs_Object *yaffs_CreateFakeDirectory(yaffs_Device *dev, int number,
- 					       __u32 mode)
- {
- 
- 	yaffs_Object *obj =
- 	    yaffs_CreateNewObject(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);
- 	if (obj) {
--		obj->fake = 1;		/* it is fake so it has no NAND presence... */
-+		obj->fake = 1;		/* it is fake so it might have no NAND presence... */
- 		obj->renameAllowed = 0;	/* ... and we're not allowed to rename it... */
- 		obj->unlinkAllowed = 0;	/* ... or unlink it */
- 		obj->deleted = 0;
- 		obj->unlinked = 0;
- 		obj->yst_mode = mode;
- 		obj->myDev = dev;
--		obj->chunkId = 0;	/* Not a valid chunk. */
-+		obj->hdrChunk = 0;	/* Not a valid chunk. */
- 	}
- 
- 	return obj;
- 
- }
- 
--static void yaffs_UnhashObject(yaffs_Object * tn)
-+static void yaffs_UnhashObject(yaffs_Object *tn)
- {
- 	int bucket;
- 	yaffs_Device *dev = tn->myDev;
- 
- 	/* If it is still linked into the bucket list, free from the list */
--	if (!list_empty(&tn->hashLink)) {
--		list_del_init(&tn->hashLink);
-+	if (!ylist_empty(&tn->hashLink)) {
-+		ylist_del_init(&tn->hashLink);
- 		bucket = yaffs_HashFunction(tn->objectId);
- 		dev->objectBucket[bucket].count--;
- 	}
--
- }
- 
- /*  FreeObject frees up a Object and puts it back on the free list */
--static void yaffs_FreeObject(yaffs_Object * tn)
-+static void yaffs_FreeObject(yaffs_Object *tn)
- {
--
- 	yaffs_Device *dev = tn->myDev;
- 
--#ifdef  __KERNEL__
-+#ifdef __KERNEL__
-+	T(YAFFS_TRACE_OS, (TSTR("FreeObject %p inode %p"TENDSTR), tn, tn->myInode));
-+#endif
-+
-+	if (tn->parent)
-+		YBUG();
-+	if (!ylist_empty(&tn->siblings))
-+		YBUG();
-+
-+
-+#ifdef __KERNEL__
- 	if (tn->myInode) {
- 		/* We're still hooked up to a cached inode.
- 		 * Don't delete now, but mark for later deletion
-@@ -1963,24 +2000,28 @@ static void yaffs_FreeObject(yaffs_Objec
- 
- 	yaffs_UnhashObject(tn);
- 
-+#ifdef VALGRIND_TEST
-+	YFREE(tn);
-+#else
- 	/* Link into the free list. */
--	tn->siblings.next = (struct list_head *)(dev->freeObjects);
-+	tn->siblings.next = (struct ylist_head *)(dev->freeObjects);
- 	dev->freeObjects = tn;
- 	dev->nFreeObjects++;
-+#endif
-+	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
- }
- 
- #ifdef __KERNEL__
- 
--void yaffs_HandleDeferedFree(yaffs_Object * obj)
-+void yaffs_HandleDeferedFree(yaffs_Object *obj)
- {
--	if (obj->deferedFree) {
-+	if (obj->deferedFree)
- 		yaffs_FreeObject(obj);
--	}
- }
- 
- #endif
- 
--static void yaffs_DeinitialiseObjects(yaffs_Device * dev)
-+static void yaffs_DeinitialiseObjects(yaffs_Device *dev)
- {
- 	/* Free the list of allocated Objects */
- 
-@@ -1998,7 +2039,7 @@ static void yaffs_DeinitialiseObjects(ya
- 	dev->nFreeObjects = 0;
- }
- 
--static void yaffs_InitialiseObjects(yaffs_Device * dev)
-+static void yaffs_InitialiseObjects(yaffs_Device *dev)
- {
- 	int i;
- 
-@@ -2007,15 +2048,14 @@ static void yaffs_InitialiseObjects(yaff
- 	dev->nFreeObjects = 0;
- 
- 	for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
--		INIT_LIST_HEAD(&dev->objectBucket[i].list);
-+		YINIT_LIST_HEAD(&dev->objectBucket[i].list);
- 		dev->objectBucket[i].count = 0;
- 	}
--
- }
- 
--static int yaffs_FindNiceObjectBucket(yaffs_Device * dev)
-+static int yaffs_FindNiceObjectBucket(yaffs_Device *dev)
- {
--	static int x = 0;
-+	static int x;
- 	int i;
- 	int l = 999;
- 	int lowest = 999999;
-@@ -2049,7 +2089,7 @@ static int yaffs_FindNiceObjectBucket(ya
- 	return l;
- }
- 
--static int yaffs_CreateNewObjectNumber(yaffs_Device * dev)
-+static int yaffs_CreateNewObjectNumber(yaffs_Device *dev)
- {
- 	int bucket = yaffs_FindNiceObjectBucket(dev);
- 
-@@ -2058,7 +2098,7 @@ static int yaffs_CreateNewObjectNumber(y
- 	 */
- 
- 	int found = 0;
--	struct list_head *i;
-+	struct ylist_head *i;
- 
- 	__u32 n = (__u32) bucket;
- 
-@@ -2068,41 +2108,38 @@ static int yaffs_CreateNewObjectNumber(y
- 		found = 1;
- 		n += YAFFS_NOBJECT_BUCKETS;
- 		if (1 || dev->objectBucket[bucket].count > 0) {
--			list_for_each(i, &dev->objectBucket[bucket].list) {
-+			ylist_for_each(i, &dev->objectBucket[bucket].list) {
- 				/* If there is already one in the list */
--				if (i
--				    && list_entry(i, yaffs_Object,
--						  hashLink)->objectId == n) {
-+				if (i && ylist_entry(i, yaffs_Object,
-+						hashLink)->objectId == n) {
- 					found = 0;
- 				}
- 			}
- 		}
- 	}
- 
--
- 	return n;
- }
- 
--static void yaffs_HashObject(yaffs_Object * in)
-+static void yaffs_HashObject(yaffs_Object *in)
- {
- 	int bucket = yaffs_HashFunction(in->objectId);
- 	yaffs_Device *dev = in->myDev;
- 
--	list_add(&in->hashLink, &dev->objectBucket[bucket].list);
-+	ylist_add(&in->hashLink, &dev->objectBucket[bucket].list);
- 	dev->objectBucket[bucket].count++;
--
- }
- 
--yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number)
-+yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev, __u32 number)
- {
- 	int bucket = yaffs_HashFunction(number);
--	struct list_head *i;
-+	struct ylist_head *i;
- 	yaffs_Object *in;
- 
--	list_for_each(i, &dev->objectBucket[bucket].list) {
-+	ylist_for_each(i, &dev->objectBucket[bucket].list) {
- 		/* Look if it is in the list */
- 		if (i) {
--			in = list_entry(i, yaffs_Object, hashLink);
-+			in = ylist_entry(i, yaffs_Object, hashLink);
- 			if (in->objectId == number) {
- #ifdef __KERNEL__
- 				/* Don't tell the VFS about this one if it is defered free */
-@@ -2118,31 +2155,27 @@ yaffs_Object *yaffs_FindObjectByNumber(y
- 	return NULL;
- }
- 
--yaffs_Object *yaffs_CreateNewObject(yaffs_Device * dev, int number,
-+yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number,
- 				    yaffs_ObjectType type)
- {
--
- 	yaffs_Object *theObject;
--	yaffs_Tnode *tn;
-+	yaffs_Tnode *tn = NULL;
- 
--	if (number < 0) {
-+	if (number < 0)
- 		number = yaffs_CreateNewObjectNumber(dev);
--	}
- 
- 	theObject = yaffs_AllocateEmptyObject(dev);
--	if(!theObject)
-+	if (!theObject)
- 		return NULL;
- 
--	if(type == YAFFS_OBJECT_TYPE_FILE){
-+	if (type == YAFFS_OBJECT_TYPE_FILE) {
- 		tn = yaffs_GetTnode(dev);
--		if(!tn){
-+		if (!tn) {
- 			yaffs_FreeObject(theObject);
- 			return NULL;
- 		}
- 	}
- 
--
--
- 	if (theObject) {
- 		theObject->fake = 0;
- 		theObject->renameAllowed = 1;
-@@ -2171,8 +2204,8 @@ yaffs_Object *yaffs_CreateNewObject(yaff
- 			theObject->variant.fileVariant.top = tn;
- 			break;
- 		case YAFFS_OBJECT_TYPE_DIRECTORY:
--			INIT_LIST_HEAD(&theObject->variant.directoryVariant.
--				       children);
-+			YINIT_LIST_HEAD(&theObject->variant.directoryVariant.
-+					children);
- 			break;
- 		case YAFFS_OBJECT_TYPE_SYMLINK:
- 		case YAFFS_OBJECT_TYPE_HARDLINK:
-@@ -2188,32 +2221,30 @@ yaffs_Object *yaffs_CreateNewObject(yaff
- 	return theObject;
- }
- 
--static yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device * dev,
-+static yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device *dev,
- 						      int number,
- 						      yaffs_ObjectType type)
- {
- 	yaffs_Object *theObject = NULL;
- 
--	if (number > 0) {
-+	if (number > 0)
- 		theObject = yaffs_FindObjectByNumber(dev, number);
--	}
- 
--	if (!theObject) {
-+	if (!theObject)
- 		theObject = yaffs_CreateNewObject(dev, number, type);
--	}
- 
- 	return theObject;
- 
- }
- 
- 
--static YCHAR *yaffs_CloneString(const YCHAR * str)
-+static YCHAR *yaffs_CloneString(const YCHAR *str)
- {
- 	YCHAR *newStr = NULL;
- 
- 	if (str && *str) {
- 		newStr = YMALLOC((yaffs_strlen(str) + 1) * sizeof(YCHAR));
--		if(newStr)
-+		if (newStr)
- 			yaffs_strcpy(newStr, str);
- 	}
- 
-@@ -2229,29 +2260,31 @@ static YCHAR *yaffs_CloneString(const YC
-  */
- 
- static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type,
--				       yaffs_Object * parent,
--				       const YCHAR * name,
-+				       yaffs_Object *parent,
-+				       const YCHAR *name,
- 				       __u32 mode,
- 				       __u32 uid,
- 				       __u32 gid,
--				       yaffs_Object * equivalentObject,
--				       const YCHAR * aliasString, __u32 rdev)
-+				       yaffs_Object *equivalentObject,
-+				       const YCHAR *aliasString, __u32 rdev)
- {
- 	yaffs_Object *in;
--	YCHAR *str;
-+	YCHAR *str = NULL;
- 
- 	yaffs_Device *dev = parent->myDev;
- 
- 	/* Check if the entry exists. If it does then fail the call since we don't want a dup.*/
--	if (yaffs_FindObjectByName(parent, name)) {
-+	if (yaffs_FindObjectByName(parent, name))
- 		return NULL;
--	}
- 
- 	in = yaffs_CreateNewObject(dev, -1, type);
- 
--	if(type == YAFFS_OBJECT_TYPE_SYMLINK){
-+	if (!in)
-+		return YAFFS_FAIL;
-+
-+	if (type == YAFFS_OBJECT_TYPE_SYMLINK) {
- 		str = yaffs_CloneString(aliasString);
--		if(!str){
-+		if (!str) {
- 			yaffs_FreeObject(in);
- 			return NULL;
- 		}
-@@ -2260,7 +2293,7 @@ static yaffs_Object *yaffs_MknodObject(y
- 
- 
- 	if (in) {
--		in->chunkId = -1;
-+		in->hdrChunk = 0;
- 		in->valid = 1;
- 		in->variantType = type;
- 
-@@ -2293,10 +2326,10 @@ static yaffs_Object *yaffs_MknodObject(y
- 			break;
- 		case YAFFS_OBJECT_TYPE_HARDLINK:
- 			in->variant.hardLinkVariant.equivalentObject =
--			    equivalentObject;
-+				equivalentObject;
- 			in->variant.hardLinkVariant.equivalentObjectId =
--			    equivalentObject->objectId;
--			list_add(&in->hardLinks, &equivalentObject->hardLinks);
-+				equivalentObject->objectId;
-+			ylist_add(&in->hardLinks, &equivalentObject->hardLinks);
- 			break;
- 		case YAFFS_OBJECT_TYPE_FILE:
- 		case YAFFS_OBJECT_TYPE_DIRECTORY:
-@@ -2308,7 +2341,7 @@ static yaffs_Object *yaffs_MknodObject(y
- 
- 		if (yaffs_UpdateObjectHeader(in, name, 0, 0, 0) < 0) {
- 			/* Could not create the object header, fail the creation */
--			yaffs_DestroyObject(in);
-+			yaffs_DeleteObject(in);
- 			in = NULL;
- 		}
- 
-@@ -2317,38 +2350,38 @@ static yaffs_Object *yaffs_MknodObject(y
- 	return in;
- }
- 
--yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name,
--			      __u32 mode, __u32 uid, __u32 gid)
-+yaffs_Object *yaffs_MknodFile(yaffs_Object *parent, const YCHAR *name,
-+			__u32 mode, __u32 uid, __u32 gid)
- {
- 	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_FILE, parent, name, mode,
--				 uid, gid, NULL, NULL, 0);
-+				uid, gid, NULL, NULL, 0);
- }
- 
--yaffs_Object *yaffs_MknodDirectory(yaffs_Object * parent, const YCHAR * name,
--				   __u32 mode, __u32 uid, __u32 gid)
-+yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent, const YCHAR *name,
-+				__u32 mode, __u32 uid, __u32 gid)
- {
- 	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name,
- 				 mode, uid, gid, NULL, NULL, 0);
- }
- 
--yaffs_Object *yaffs_MknodSpecial(yaffs_Object * parent, const YCHAR * name,
--				 __u32 mode, __u32 uid, __u32 gid, __u32 rdev)
-+yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent, const YCHAR *name,
-+				__u32 mode, __u32 uid, __u32 gid, __u32 rdev)
- {
- 	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode,
- 				 uid, gid, NULL, NULL, rdev);
- }
- 
--yaffs_Object *yaffs_MknodSymLink(yaffs_Object * parent, const YCHAR * name,
--				 __u32 mode, __u32 uid, __u32 gid,
--				 const YCHAR * alias)
-+yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const YCHAR *name,
-+				__u32 mode, __u32 uid, __u32 gid,
-+				const YCHAR *alias)
- {
- 	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode,
--				 uid, gid, NULL, alias, 0);
-+				uid, gid, NULL, alias, 0);
- }
- 
- /* yaffs_Link returns the object id of the equivalent object.*/
--yaffs_Object *yaffs_Link(yaffs_Object * parent, const YCHAR * name,
--			 yaffs_Object * equivalentObject)
-+yaffs_Object *yaffs_Link(yaffs_Object *parent, const YCHAR *name,
-+			yaffs_Object *equivalentObject)
- {
- 	/* Get the real object in case we were fed a hard link as an equivalent object */
- 	equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
-@@ -2363,33 +2396,31 @@ yaffs_Object *yaffs_Link(yaffs_Object *
- 
- }
- 
--static int yaffs_ChangeObjectName(yaffs_Object * obj, yaffs_Object * newDir,
--				  const YCHAR * newName, int force, int shadows)
-+static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir,
-+				const YCHAR *newName, int force, int shadows)
- {
- 	int unlinkOp;
- 	int deleteOp;
- 
- 	yaffs_Object *existingTarget;
- 
--	if (newDir == NULL) {
-+	if (newDir == NULL)
- 		newDir = obj->parent;	/* use the old directory */
--	}
- 
- 	if (newDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
--		   ("tragendy: yaffs_ChangeObjectName: newDir is not a directory"
-+		   ("tragedy: yaffs_ChangeObjectName: newDir is not a directory"
- 		    TENDSTR)));
- 		YBUG();
- 	}
- 
- 	/* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
--	if (obj->myDev->isYaffs2) {
-+	if (obj->myDev->isYaffs2)
- 		unlinkOp = (newDir == obj->myDev->unlinkedDir);
--	} else {
-+	else
- 		unlinkOp = (newDir == obj->myDev->unlinkedDir
- 			    && obj->variantType == YAFFS_OBJECT_TYPE_FILE);
--	}
- 
- 	deleteOp = (newDir == obj->myDev->deletedDir);
- 
-@@ -2415,40 +2446,40 @@ static int yaffs_ChangeObjectName(yaffs_
- 			obj->unlinked = 1;
- 
- 		/* If it is a deletion then we mark it as a shrink for gc purposes. */
--		if (yaffs_UpdateObjectHeader(obj, newName, 0, deleteOp, shadows)>= 0)
-+		if (yaffs_UpdateObjectHeader(obj, newName, 0, deleteOp, shadows) >= 0)
- 			return YAFFS_OK;
- 	}
- 
- 	return YAFFS_FAIL;
- }
- 
--int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
--		       yaffs_Object * newDir, const YCHAR * newName)
-+int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
-+		yaffs_Object *newDir, const YCHAR *newName)
- {
--	yaffs_Object *obj;
--	yaffs_Object *existingTarget;
-+	yaffs_Object *obj = NULL;
-+	yaffs_Object *existingTarget = NULL;
- 	int force = 0;
- 
-+
-+	if (!oldDir || oldDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
-+		YBUG();
-+	if (!newDir || newDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
-+		YBUG();
-+
- #ifdef CONFIG_YAFFS_CASE_INSENSITIVE
- 	/* Special case for case insemsitive systems (eg. WinCE).
- 	 * While look-up is case insensitive, the name isn't.
- 	 * Therefore we might want to change x.txt to X.txt
- 	*/
--	if (oldDir == newDir && yaffs_strcmp(oldName, newName) == 0) {
-+	if (oldDir == newDir && yaffs_strcmp(oldName, newName) == 0)
- 		force = 1;
--	}
- #endif
- 
-+	else if (yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH)
-+		/* ENAMETOOLONG */
-+		return YAFFS_FAIL;
-+
- 	obj = yaffs_FindObjectByName(oldDir, oldName);
--	/* Check new name to long. */
--	if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK &&
--	    yaffs_strlen(newName) > YAFFS_MAX_ALIAS_LENGTH)
--	  /* ENAMETOOLONG */
--	  return YAFFS_FAIL;
--	else if (obj->variantType != YAFFS_OBJECT_TYPE_SYMLINK &&
--		 yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH)
--	  /* ENAMETOOLONG */
--	  return YAFFS_FAIL;
- 
- 	if (obj && obj->renameAllowed) {
- 
-@@ -2456,8 +2487,8 @@ int yaffs_RenameObject(yaffs_Object * ol
- 
- 		existingTarget = yaffs_FindObjectByName(newDir, newName);
- 		if (existingTarget &&
--		    existingTarget->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
--		    !list_empty(&existingTarget->variant.directoryVariant.children)) {
-+			existingTarget->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
-+			!ylist_empty(&existingTarget->variant.directoryVariant.children)) {
- 			/* There is a target that is a non-empty directory, so we fail */
- 			return YAFFS_FAIL;	/* EEXIST or ENOTEMPTY */
- 		} else if (existingTarget && existingTarget != obj) {
-@@ -2465,7 +2496,7 @@ int yaffs_RenameObject(yaffs_Object * ol
- 			 * but only if it isn't the same object
- 			 */
- 			yaffs_ChangeObjectName(obj, newDir, newName, force,
--					       existingTarget->objectId);
-+						existingTarget->objectId);
- 			yaffs_UnlinkObject(existingTarget);
- 		}
- 
-@@ -2476,7 +2507,7 @@ int yaffs_RenameObject(yaffs_Object * ol
- 
- /*------------------------- Block Management and Page Allocation ----------------*/
- 
--static int yaffs_InitialiseBlocks(yaffs_Device * dev)
-+static int yaffs_InitialiseBlocks(yaffs_Device *dev)
- {
- 	int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
- 
-@@ -2487,23 +2518,20 @@ static int yaffs_InitialiseBlocks(yaffs_
- 
- 	/* If the first allocation strategy fails, thry the alternate one */
- 	dev->blockInfo = YMALLOC(nBlocks * sizeof(yaffs_BlockInfo));
--	if(!dev->blockInfo){
-+	if (!dev->blockInfo) {
- 		dev->blockInfo = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockInfo));
- 		dev->blockInfoAlt = 1;
--	}
--	else
-+	} else
- 		dev->blockInfoAlt = 0;
- 
--	if(dev->blockInfo){
--
-+	if (dev->blockInfo) {
- 		/* Set up dynamic blockinfo stuff. */
- 		dev->chunkBitmapStride = (dev->nChunksPerBlock + 7) / 8; /* round up bytes */
- 		dev->chunkBits = YMALLOC(dev->chunkBitmapStride * nBlocks);
--		if(!dev->chunkBits){
-+		if (!dev->chunkBits) {
- 			dev->chunkBits = YMALLOC_ALT(dev->chunkBitmapStride * nBlocks);
- 			dev->chunkBitsAlt = 1;
--		}
--		else
-+		} else
- 			dev->chunkBitsAlt = 0;
- 	}
- 
-@@ -2514,30 +2542,29 @@ static int yaffs_InitialiseBlocks(yaffs_
- 	}
- 
- 	return YAFFS_FAIL;
--
- }
- 
--static void yaffs_DeinitialiseBlocks(yaffs_Device * dev)
-+static void yaffs_DeinitialiseBlocks(yaffs_Device *dev)
- {
--	if(dev->blockInfoAlt && dev->blockInfo)
-+	if (dev->blockInfoAlt && dev->blockInfo)
- 		YFREE_ALT(dev->blockInfo);
--	else if(dev->blockInfo)
-+	else if (dev->blockInfo)
- 		YFREE(dev->blockInfo);
- 
- 	dev->blockInfoAlt = 0;
- 
- 	dev->blockInfo = NULL;
- 
--	if(dev->chunkBitsAlt && dev->chunkBits)
-+	if (dev->chunkBitsAlt && dev->chunkBits)
- 		YFREE_ALT(dev->chunkBits);
--	else if(dev->chunkBits)
-+	else if (dev->chunkBits)
- 		YFREE(dev->chunkBits);
- 	dev->chunkBitsAlt = 0;
- 	dev->chunkBits = NULL;
- }
- 
--static int yaffs_BlockNotDisqualifiedFromGC(yaffs_Device * dev,
--					    yaffs_BlockInfo * bi)
-+static int yaffs_BlockNotDisqualifiedFromGC(yaffs_Device *dev,
-+					yaffs_BlockInfo *bi)
- {
- 	int i;
- 	__u32 seq;
-@@ -2556,7 +2583,7 @@ static int yaffs_BlockNotDisqualifiedFro
- 		seq = dev->sequenceNumber;
- 
- 		for (i = dev->internalStartBlock; i <= dev->internalEndBlock;
--		     i++) {
-+				i++) {
- 			b = yaffs_GetBlockInfo(dev, i);
- 			if (b->blockState == YAFFS_BLOCK_STATE_FULL &&
- 			    (b->pagesInUse - b->softDeletions) <
-@@ -2571,38 +2598,36 @@ static int yaffs_BlockNotDisqualifiedFro
- 	 * discarded pages.
- 	 */
- 	return (bi->sequenceNumber <= dev->oldestDirtySequence);
--
- }
- 
- /* FindDiretiestBlock is used to select the dirtiest block (or close enough)
-  * for garbage collection.
-  */
- 
--static int yaffs_FindBlockForGarbageCollection(yaffs_Device * dev,
--					       int aggressive)
-+static int yaffs_FindBlockForGarbageCollection(yaffs_Device *dev,
-+					int aggressive)
- {
--
- 	int b = dev->currentDirtyChecker;
- 
- 	int i;
- 	int iterations;
- 	int dirtiest = -1;
- 	int pagesInUse = 0;
--	int prioritised=0;
-+	int prioritised = 0;
- 	yaffs_BlockInfo *bi;
- 	int pendingPrioritisedExist = 0;
- 
- 	/* First let's see if we need to grab a prioritised block */
--	if(dev->hasPendingPrioritisedGCs){
--		for(i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++){
-+	if (dev->hasPendingPrioritisedGCs) {
-+		for (i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++) {
- 
- 			bi = yaffs_GetBlockInfo(dev, i);
--			//yaffs_VerifyBlock(dev,bi,i);
-+			/* yaffs_VerifyBlock(dev,bi,i); */
- 
--			if(bi->gcPrioritise) {
-+			if (bi->gcPrioritise) {
- 				pendingPrioritisedExist = 1;
--				if(bi->blockState == YAFFS_BLOCK_STATE_FULL &&
--				   yaffs_BlockNotDisqualifiedFromGC(dev, bi)){
-+				if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
-+				   yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
- 					pagesInUse = (bi->pagesInUse - bi->softDeletions);
- 					dirtiest = i;
- 					prioritised = 1;
-@@ -2611,7 +2636,7 @@ static int yaffs_FindBlockForGarbageColl
- 			}
- 		}
- 
--		if(!pendingPrioritisedExist) /* None found, so we can clear this */
-+		if (!pendingPrioritisedExist) /* None found, so we can clear this */
- 			dev->hasPendingPrioritisedGCs = 0;
- 	}
- 
-@@ -2623,31 +2648,28 @@ static int yaffs_FindBlockForGarbageColl
- 
- 	dev->nonAggressiveSkip--;
- 
--	if (!aggressive && (dev->nonAggressiveSkip > 0)) {
-+	if (!aggressive && (dev->nonAggressiveSkip > 0))
- 		return -1;
--	}
- 
--	if(!prioritised)
-+	if (!prioritised)
- 		pagesInUse =
--	    		(aggressive) ? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
-+			(aggressive) ? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
- 
--	if (aggressive) {
-+	if (aggressive)
- 		iterations =
- 		    dev->internalEndBlock - dev->internalStartBlock + 1;
--	} else {
-+	else {
- 		iterations =
- 		    dev->internalEndBlock - dev->internalStartBlock + 1;
- 		iterations = iterations / 16;
--		if (iterations > 200) {
-+		if (iterations > 200)
- 			iterations = 200;
--		}
- 	}
- 
- 	for (i = 0; i <= iterations && pagesInUse > 0 && !prioritised; i++) {
- 		b++;
--		if (b < dev->internalStartBlock || b > dev->internalEndBlock) {
-+		if (b < dev->internalStartBlock || b > dev->internalEndBlock)
- 			b = dev->internalStartBlock;
--		}
- 
- 		if (b < dev->internalStartBlock || b > dev->internalEndBlock) {
- 			T(YAFFS_TRACE_ERROR,
-@@ -2657,17 +2679,9 @@ static int yaffs_FindBlockForGarbageColl
- 
- 		bi = yaffs_GetBlockInfo(dev, b);
- 
--#if 0
--		if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) {
--			dirtiest = b;
--			pagesInUse = 0;
--		}
--		else
--#endif
--
- 		if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
--		       (bi->pagesInUse - bi->softDeletions) < pagesInUse &&
--		        yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
-+			(bi->pagesInUse - bi->softDeletions) < pagesInUse &&
-+				yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
- 			dirtiest = b;
- 			pagesInUse = (bi->pagesInUse - bi->softDeletions);
- 		}
-@@ -2678,19 +2692,18 @@ static int yaffs_FindBlockForGarbageColl
- 	if (dirtiest > 0) {
- 		T(YAFFS_TRACE_GC,
- 		  (TSTR("GC Selected block %d with %d free, prioritised:%d" TENDSTR), dirtiest,
--		   dev->nChunksPerBlock - pagesInUse,prioritised));
-+		   dev->nChunksPerBlock - pagesInUse, prioritised));
- 	}
- 
- 	dev->oldestDirtySequence = 0;
- 
--	if (dirtiest > 0) {
-+	if (dirtiest > 0)
- 		dev->nonAggressiveSkip = 4;
--	}
- 
- 	return dirtiest;
- }
- 
--static void yaffs_BlockBecameDirty(yaffs_Device * dev, int blockNo)
-+static void yaffs_BlockBecameDirty(yaffs_Device *dev, int blockNo)
- {
- 	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockNo);
- 
-@@ -2752,7 +2765,7 @@ static void yaffs_BlockBecameDirty(yaffs
- 	}
- }
- 
--static int yaffs_FindBlockForAllocation(yaffs_Device * dev)
-+static int yaffs_FindBlockForAllocation(yaffs_Device *dev)
- {
- 	int i;
- 
-@@ -2763,7 +2776,7 @@ static int yaffs_FindBlockForAllocation(
- 		 * Can't get space to gc
- 		 */
- 		T(YAFFS_TRACE_ERROR,
--		  (TSTR("yaffs tragedy: no more eraased blocks" TENDSTR)));
-+		  (TSTR("yaffs tragedy: no more erased blocks" TENDSTR)));
- 
- 		return -1;
- 	}
-@@ -2794,31 +2807,74 @@ static int yaffs_FindBlockForAllocation(
- 
- 	T(YAFFS_TRACE_ALWAYS,
- 	  (TSTR
--	   ("yaffs tragedy: no more eraased blocks, but there should have been %d"
-+	   ("yaffs tragedy: no more erased blocks, but there should have been %d"
- 	    TENDSTR), dev->nErasedBlocks));
- 
- 	return -1;
- }
- 
- 
--// Check if there's space to allocate...
--// Thinks.... do we need top make this ths same as yaffs_GetFreeChunks()?
--static int yaffs_CheckSpaceForAllocation(yaffs_Device * dev)
-+
-+static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
-+{
-+	if (!dev->nCheckpointBlocksRequired &&
-+	   dev->isYaffs2) {
-+		/* Not a valid value so recalculate */
-+		int nBytes = 0;
-+		int nBlocks;
-+		int devBlocks = (dev->endBlock - dev->startBlock + 1);
-+		int tnodeSize;
-+
-+		tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
-+
-+		if (tnodeSize < sizeof(yaffs_Tnode))
-+			tnodeSize = sizeof(yaffs_Tnode);
-+
-+		nBytes += sizeof(yaffs_CheckpointValidity);
-+		nBytes += sizeof(yaffs_CheckpointDevice);
-+		nBytes += devBlocks * sizeof(yaffs_BlockInfo);
-+		nBytes += devBlocks * dev->chunkBitmapStride;
-+		nBytes += (sizeof(yaffs_CheckpointObject) + sizeof(__u32)) * (dev->nObjectsCreated - dev->nFreeObjects);
-+		nBytes += (tnodeSize + sizeof(__u32)) * (dev->nTnodesCreated - dev->nFreeTnodes);
-+		nBytes += sizeof(yaffs_CheckpointValidity);
-+		nBytes += sizeof(__u32); /* checksum*/
-+
-+		/* Round up and add 2 blocks to allow for some bad blocks, so add 3 */
-+
-+		nBlocks = (nBytes/(dev->nDataBytesPerChunk * dev->nChunksPerBlock)) + 3;
-+
-+		dev->nCheckpointBlocksRequired = nBlocks;
-+	}
-+
-+	return dev->nCheckpointBlocksRequired;
-+}
-+
-+/*
-+ * Check if there's space to allocate...
-+ * Thinks.... do we need top make this ths same as yaffs_GetFreeChunks()?
-+ */
-+static int yaffs_CheckSpaceForAllocation(yaffs_Device *dev)
- {
- 	int reservedChunks;
- 	int reservedBlocks = dev->nReservedBlocks;
- 	int checkpointBlocks;
- 
--	checkpointBlocks =  dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
--	if(checkpointBlocks < 0)
-+	if (dev->isYaffs2) {
-+		checkpointBlocks =  yaffs_CalcCheckpointBlocksRequired(dev) -
-+				    dev->blocksInCheckpoint;
-+		if (checkpointBlocks < 0)
-+			checkpointBlocks = 0;
-+	} else {
- 		checkpointBlocks = 0;
-+	}
- 
- 	reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->nChunksPerBlock);
- 
- 	return (dev->nFreeChunks > reservedChunks);
- }
- 
--static int yaffs_AllocateChunk(yaffs_Device * dev, int useReserve, yaffs_BlockInfo **blockUsedPtr)
-+static int yaffs_AllocateChunk(yaffs_Device *dev, int useReserve,
-+		yaffs_BlockInfo **blockUsedPtr)
- {
- 	int retVal;
- 	yaffs_BlockInfo *bi;
-@@ -2835,7 +2891,7 @@ static int yaffs_AllocateChunk(yaffs_Dev
- 	}
- 
- 	if (dev->nErasedBlocks < dev->nReservedBlocks
--	    && dev->allocationPage == 0) {
-+			&& dev->allocationPage == 0) {
- 		T(YAFFS_TRACE_ALLOCATE, (TSTR("Allocating reserve" TENDSTR)));
- 	}
- 
-@@ -2844,10 +2900,10 @@ static int yaffs_AllocateChunk(yaffs_Dev
- 		bi = yaffs_GetBlockInfo(dev, dev->allocationBlock);
- 
- 		retVal = (dev->allocationBlock * dev->nChunksPerBlock) +
--		    dev->allocationPage;
-+			dev->allocationPage;
- 		bi->pagesInUse++;
- 		yaffs_SetChunkBit(dev, dev->allocationBlock,
--				  dev->allocationPage);
-+				dev->allocationPage);
- 
- 		dev->allocationPage++;
- 
-@@ -2859,43 +2915,43 @@ static int yaffs_AllocateChunk(yaffs_Dev
- 			dev->allocationBlock = -1;
- 		}
- 
--		if(blockUsedPtr)
-+		if (blockUsedPtr)
- 			*blockUsedPtr = bi;
- 
- 		return retVal;
- 	}
- 
- 	T(YAFFS_TRACE_ERROR,
--	  (TSTR("!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!" TENDSTR)));
-+			(TSTR("!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!" TENDSTR)));
- 
- 	return -1;
- }
- 
--static int yaffs_GetErasedChunks(yaffs_Device * dev)
-+static int yaffs_GetErasedChunks(yaffs_Device *dev)
- {
- 	int n;
- 
- 	n = dev->nErasedBlocks * dev->nChunksPerBlock;
- 
--	if (dev->allocationBlock > 0) {
-+	if (dev->allocationBlock > 0)
- 		n += (dev->nChunksPerBlock - dev->allocationPage);
--	}
- 
- 	return n;
- 
- }
- 
--static int yaffs_GarbageCollectBlock(yaffs_Device * dev, int block)
-+static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block,
-+		int wholeBlock)
- {
- 	int oldChunk;
- 	int newChunk;
--	int chunkInBlock;
- 	int markNAND;
- 	int retVal = YAFFS_OK;
- 	int cleanups = 0;
- 	int i;
- 	int isCheckpointBlock;
- 	int matchingChunk;
-+	int maxCopies;
- 
- 	int chunksBefore = yaffs_GetErasedChunks(dev);
- 	int chunksAfter;
-@@ -2911,8 +2967,11 @@ static int yaffs_GarbageCollectBlock(yaf
- 	bi->blockState = YAFFS_BLOCK_STATE_COLLECTING;
- 
- 	T(YAFFS_TRACE_TRACING,
--	  (TSTR("Collecting block %d, in use %d, shrink %d, " TENDSTR), block,
--	   bi->pagesInUse, bi->hasShrinkHeader));
-+			(TSTR("Collecting block %d, in use %d, shrink %d, wholeBlock %d" TENDSTR),
-+			 block,
-+			 bi->pagesInUse,
-+			 bi->hasShrinkHeader,
-+			 wholeBlock));
- 
- 	/*yaffs_VerifyFreeChunks(dev); */
- 
-@@ -2926,26 +2985,33 @@ static int yaffs_GarbageCollectBlock(yaf
- 	dev->isDoingGC = 1;
- 
- 	if (isCheckpointBlock ||
--	    !yaffs_StillSomeChunkBits(dev, block)) {
-+			!yaffs_StillSomeChunkBits(dev, block)) {
- 		T(YAFFS_TRACE_TRACING,
--		  (TSTR
--		   ("Collecting block %d that has no chunks in use" TENDSTR),
--		   block));
-+				(TSTR
-+				 ("Collecting block %d that has no chunks in use" TENDSTR),
-+				 block));
- 		yaffs_BlockBecameDirty(dev, block);
- 	} else {
- 
- 		__u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
- 
--		yaffs_VerifyBlock(dev,bi,block);
-+		yaffs_VerifyBlock(dev, bi, block);
- 
--		for (chunkInBlock = 0, oldChunk = block * dev->nChunksPerBlock;
--		     chunkInBlock < dev->nChunksPerBlock
--		     && yaffs_StillSomeChunkBits(dev, block);
--		     chunkInBlock++, oldChunk++) {
--			if (yaffs_CheckChunkBit(dev, block, chunkInBlock)) {
-+		maxCopies = (wholeBlock) ? dev->nChunksPerBlock : 10;
-+		oldChunk = block * dev->nChunksPerBlock + dev->gcChunk;
-+
-+		for (/* init already done */;
-+		     retVal == YAFFS_OK &&
-+		     dev->gcChunk < dev->nChunksPerBlock &&
-+		     (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) &&
-+		     maxCopies > 0;
-+		     dev->gcChunk++, oldChunk++) {
-+			if (yaffs_CheckChunkBit(dev, block, dev->gcChunk)) {
- 
- 				/* This page is in use and might need to be copied off */
- 
-+				maxCopies--;
-+
- 				markNAND = 1;
- 
- 				yaffs_InitialiseTags(&tags);
-@@ -2959,22 +3025,22 @@ static int yaffs_GarbageCollectBlock(yaf
- 
- 				T(YAFFS_TRACE_GC_DETAIL,
- 				  (TSTR
--				   ("Collecting page %d, %d %d %d " TENDSTR),
--				   chunkInBlock, tags.objectId, tags.chunkId,
-+				   ("Collecting chunk in block %d, %d %d %d " TENDSTR),
-+				   dev->gcChunk, tags.objectId, tags.chunkId,
- 				   tags.byteCount));
- 
--				if(object && !yaffs_SkipVerification(dev)){
--					if(tags.chunkId == 0)
--						matchingChunk = object->chunkId;
--					else if(object->softDeleted)
-+				if (object && !yaffs_SkipVerification(dev)) {
-+					if (tags.chunkId == 0)
-+						matchingChunk = object->hdrChunk;
-+					else if (object->softDeleted)
- 						matchingChunk = oldChunk; /* Defeat the test */
- 					else
--						matchingChunk = yaffs_FindChunkInFile(object,tags.chunkId,NULL);
-+						matchingChunk = yaffs_FindChunkInFile(object, tags.chunkId, NULL);
- 
--					if(oldChunk != matchingChunk)
-+					if (oldChunk != matchingChunk)
- 						T(YAFFS_TRACE_ERROR,
- 						  (TSTR("gc: page in gc mismatch: %d %d %d %d"TENDSTR),
--						  oldChunk,matchingChunk,tags.objectId, tags.chunkId));
-+						  oldChunk, matchingChunk, tags.objectId, tags.chunkId));
- 
- 				}
- 
-@@ -2986,9 +3052,11 @@ static int yaffs_GarbageCollectBlock(yaf
- 					    tags.objectId, tags.chunkId, tags.byteCount));
- 				}
- 
--				if (object && object->deleted
--				    && tags.chunkId != 0) {
--					/* Data chunk in a deleted file, throw it away
-+				if (object &&
-+				    object->deleted &&
-+				    object->softDeleted &&
-+				    tags.chunkId != 0) {
-+					/* Data chunk in a soft deleted file, throw it away
- 					 * It's a soft deleted data chunk,
- 					 * No need to copy this, just forget about it and
- 					 * fix up the object.
-@@ -3003,13 +3071,12 @@ static int yaffs_GarbageCollectBlock(yaf
- 						cleanups++;
- 					}
- 					markNAND = 0;
--				} else if (0
--					   /* Todo object && object->deleted && object->nDataChunks == 0 */
--					   ) {
-+				} else if (0) {
-+					/* Todo object && object->deleted && object->nDataChunks == 0 */
- 					/* Deleted object header with no data chunks.
- 					 * Can be discarded and the file deleted.
- 					 */
--					object->chunkId = 0;
-+					object->hdrChunk = 0;
- 					yaffs_FreeTnode(object->myDev,
- 							object->variant.
- 							fileVariant.top);
-@@ -3031,17 +3098,14 @@ static int yaffs_GarbageCollectBlock(yaf
- 						 * We need to nuke the shrinkheader flags first
- 						 * We no longer want the shrinkHeader flag since its work is done
- 						 * and if it is left in place it will mess up scanning.
--						 * Also, clear out any shadowing stuff
- 						 */
- 
- 						yaffs_ObjectHeader *oh;
- 						oh = (yaffs_ObjectHeader *)buffer;
- 						oh->isShrink = 0;
--						oh->shadowsObject = -1;
--						tags.extraShadows = 0;
- 						tags.extraIsShrinkHeader = 0;
- 
--						yaffs_VerifyObjectHeader(object,oh,&tags,1);
-+						yaffs_VerifyObjectHeader(object, oh, &tags, 1);
- 					}
- 
- 					newChunk =
-@@ -3055,7 +3119,7 @@ static int yaffs_GarbageCollectBlock(yaf
- 
- 						if (tags.chunkId == 0) {
- 							/* It's a header */
--							object->chunkId =  newChunk;
-+							object->hdrChunk =  newChunk;
- 							object->serial =   tags.serialNumber;
- 						} else {
- 							/* It's a data chunk */
-@@ -3067,7 +3131,8 @@ static int yaffs_GarbageCollectBlock(yaf
- 					}
- 				}
- 
--				yaffs_DeleteChunk(dev, oldChunk, markNAND, __LINE__);
-+				if (retVal == YAFFS_OK)
-+					yaffs_DeleteChunk(dev, oldChunk, markNAND, __LINE__);
- 
- 			}
- 		}
-@@ -3098,18 +3163,25 @@ static int yaffs_GarbageCollectBlock(yaf
- 
- 	}
- 
--	yaffs_VerifyCollectedBlock(dev,bi,block);
-+	yaffs_VerifyCollectedBlock(dev, bi, block);
- 
--	if (chunksBefore >= (chunksAfter = yaffs_GetErasedChunks(dev))) {
-+	chunksAfter = yaffs_GetErasedChunks(dev);
-+	if (chunksBefore >= chunksAfter) {
- 		T(YAFFS_TRACE_GC,
- 		  (TSTR
- 		   ("gc did not increase free chunks before %d after %d"
- 		    TENDSTR), chunksBefore, chunksAfter));
- 	}
- 
-+	/* If the gc completed then clear the current gcBlock so that we find another. */
-+	if (bi->blockState != YAFFS_BLOCK_STATE_COLLECTING) {
-+		dev->gcBlock = -1;
-+		dev->gcChunk = 0;
-+	}
-+
- 	dev->isDoingGC = 0;
- 
--	return YAFFS_OK;
-+	return retVal;
- }
- 
- /* New garbage collector
-@@ -3121,7 +3193,7 @@ static int yaffs_GarbageCollectBlock(yaf
-  * The idea is to help clear out space in a more spread-out manner.
-  * Dunno if it really does anything useful.
-  */
--static int yaffs_CheckGarbageCollection(yaffs_Device * dev)
-+static int yaffs_CheckGarbageCollection(yaffs_Device *dev)
- {
- 	int block;
- 	int aggressive;
-@@ -3142,8 +3214,8 @@ static int yaffs_CheckGarbageCollection(
- 	do {
- 		maxTries++;
- 
--		checkpointBlockAdjust = (dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint);
--		if(checkpointBlockAdjust < 0)
-+		checkpointBlockAdjust = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
-+		if (checkpointBlockAdjust < 0)
- 			checkpointBlockAdjust = 0;
- 
- 		if (dev->nErasedBlocks < (dev->nReservedBlocks + checkpointBlockAdjust + 2)) {
-@@ -3154,20 +3226,24 @@ static int yaffs_CheckGarbageCollection(
- 			aggressive = 0;
- 		}
- 
--		block = yaffs_FindBlockForGarbageCollection(dev, aggressive);
-+		if (dev->gcBlock <= 0) {
-+			dev->gcBlock = yaffs_FindBlockForGarbageCollection(dev, aggressive);
-+			dev->gcChunk = 0;
-+		}
-+
-+		block = dev->gcBlock;
- 
- 		if (block > 0) {
- 			dev->garbageCollections++;
--			if (!aggressive) {
-+			if (!aggressive)
- 				dev->passiveGarbageCollections++;
--			}
- 
- 			T(YAFFS_TRACE_GC,
- 			  (TSTR
- 			   ("yaffs: GC erasedBlocks %d aggressive %d" TENDSTR),
- 			   dev->nErasedBlocks, aggressive));
- 
--			gcOk = yaffs_GarbageCollectBlock(dev, block);
-+			gcOk = yaffs_GarbageCollectBlock(dev, block, aggressive);
- 		}
- 
- 		if (dev->nErasedBlocks < (dev->nReservedBlocks) && block > 0) {
-@@ -3176,15 +3252,16 @@ static int yaffs_CheckGarbageCollection(
- 			   ("yaffs: GC !!!no reclaim!!! erasedBlocks %d after try %d block %d"
- 			    TENDSTR), dev->nErasedBlocks, maxTries, block));
- 		}
--	} while ((dev->nErasedBlocks < dev->nReservedBlocks) && (block > 0)
--		 && (maxTries < 2));
-+	} while ((dev->nErasedBlocks < dev->nReservedBlocks) &&
-+		 (block > 0) &&
-+		 (maxTries < 2));
- 
- 	return aggressive ? gcOk : YAFFS_OK;
- }
- 
- /*-------------------------  TAGS --------------------------------*/
- 
--static int yaffs_TagsMatch(const yaffs_ExtendedTags * tags, int objectId,
-+static int yaffs_TagsMatch(const yaffs_ExtendedTags *tags, int objectId,
- 			   int chunkInObject)
- {
- 	return (tags->chunkId == chunkInObject &&
-@@ -3195,8 +3272,8 @@ static int yaffs_TagsMatch(const yaffs_E
- 
- /*-------------------- Data file manipulation -----------------*/
- 
--static int yaffs_FindChunkInFile(yaffs_Object * in, int chunkInInode,
--				 yaffs_ExtendedTags * tags)
-+static int yaffs_FindChunkInFile(yaffs_Object *in, int chunkInInode,
-+				 yaffs_ExtendedTags *tags)
- {
- 	/*Get the Tnode, then get the level 0 offset chunk offset */
- 	yaffs_Tnode *tn;
-@@ -3214,7 +3291,7 @@ static int yaffs_FindChunkInFile(yaffs_O
- 	tn = yaffs_FindLevel0Tnode(dev, &in->variant.fileVariant, chunkInInode);
- 
- 	if (tn) {
--		theChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode);
-+		theChunk = yaffs_GetChunkGroupBase(dev, tn, chunkInInode);
- 
- 		retVal =
- 		    yaffs_FindChunkInGroup(dev, theChunk, tags, in->objectId,
-@@ -3223,8 +3300,8 @@ static int yaffs_FindChunkInFile(yaffs_O
- 	return retVal;
- }
- 
--static int yaffs_FindAndDeleteChunkInFile(yaffs_Object * in, int chunkInInode,
--					  yaffs_ExtendedTags * tags)
-+static int yaffs_FindAndDeleteChunkInFile(yaffs_Object *in, int chunkInInode,
-+					  yaffs_ExtendedTags *tags)
- {
- 	/* Get the Tnode, then get the level 0 offset chunk offset */
- 	yaffs_Tnode *tn;
-@@ -3243,29 +3320,23 @@ static int yaffs_FindAndDeleteChunkInFil
- 
- 	if (tn) {
- 
--		theChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode);
-+		theChunk = yaffs_GetChunkGroupBase(dev, tn, chunkInInode);
- 
- 		retVal =
- 		    yaffs_FindChunkInGroup(dev, theChunk, tags, in->objectId,
- 					   chunkInInode);
- 
- 		/* Delete the entry in the filestructure (if found) */
--		if (retVal != -1) {
--			yaffs_PutLevel0Tnode(dev,tn,chunkInInode,0);
--		}
--	} else {
--		/*T(("No level 0 found for %d\n", chunkInInode)); */
-+		if (retVal != -1)
-+			yaffs_PutLevel0Tnode(dev, tn, chunkInInode, 0);
- 	}
- 
--	if (retVal == -1) {
--		/* T(("Could not find %d to delete\n",chunkInInode)); */
--	}
- 	return retVal;
- }
- 
- #ifdef YAFFS_PARANOID
- 
--static int yaffs_CheckFileSanity(yaffs_Object * in)
-+static int yaffs_CheckFileSanity(yaffs_Object *in)
- {
- 	int chunk;
- 	int nChunks;
-@@ -3278,10 +3349,8 @@ static int yaffs_CheckFileSanity(yaffs_O
- 	int theChunk;
- 	int chunkDeleted;
- 
--	if (in->variantType != YAFFS_OBJECT_TYPE_FILE) {
--		/* T(("Object not a file\n")); */
-+	if (in->variantType != YAFFS_OBJECT_TYPE_FILE)
- 		return YAFFS_FAIL;
--	}
- 
- 	objId = in->objectId;
- 	fSize = in->variant.fileVariant.fileSize;
-@@ -3294,7 +3363,7 @@ static int yaffs_CheckFileSanity(yaffs_O
- 
- 		if (tn) {
- 
--			theChunk = yaffs_GetChunkGroupBase(dev,tn,chunk);
-+			theChunk = yaffs_GetChunkGroupBase(dev, tn, chunk);
- 
- 			if (yaffs_CheckChunkBits
- 			    (dev, theChunk / dev->nChunksPerBlock,
-@@ -3323,7 +3392,7 @@ static int yaffs_CheckFileSanity(yaffs_O
- 
- #endif
- 
--static int yaffs_PutChunkIntoFile(yaffs_Object * in, int chunkInInode,
-+static int yaffs_PutChunkIntoFile(yaffs_Object *in, int chunkInInode,
- 				  int chunkInNAND, int inScan)
- {
- 	/* NB inScan is zero unless scanning.
-@@ -3358,11 +3427,10 @@ static int yaffs_PutChunkIntoFile(yaffs_
- 					&in->variant.fileVariant,
- 					chunkInInode,
- 					NULL);
--	if (!tn) {
-+	if (!tn)
- 		return YAFFS_FAIL;
--	}
- 
--	existingChunk = yaffs_GetChunkGroupBase(dev,tn,chunkInInode);
-+	existingChunk = yaffs_GetChunkGroupBase(dev, tn, chunkInInode);
- 
- 	if (inScan != 0) {
- 		/* If we're scanning then we need to test for duplicates
-@@ -3374,7 +3442,7 @@ static int yaffs_PutChunkIntoFile(yaffs_
- 		 * Update: For backward scanning we don't need to re-read tags so this is quite cheap.
- 		 */
- 
--		if (existingChunk != 0) {
-+		if (existingChunk > 0) {
- 			/* NB Right now existing chunk will not be real chunkId if the device >= 32MB
- 			 *    thus we have to do a FindChunkInFile to get the real chunk id.
- 			 *
-@@ -3411,8 +3479,10 @@ static int yaffs_PutChunkIntoFile(yaffs_
- 			 * not be loaded during a scan
- 			 */
- 
--			newSerial = newTags.serialNumber;
--			existingSerial = existingTags.serialNumber;
-+			if (inScan > 0) {
-+				newSerial = newTags.serialNumber;
-+				existingSerial = existingTags.serialNumber;
-+			}
- 
- 			if ((inScan > 0) &&
- 			    (in->myDev->isYaffs2 ||
-@@ -3437,24 +3507,23 @@ static int yaffs_PutChunkIntoFile(yaffs_
- 
- 	}
- 
--	if (existingChunk == 0) {
-+	if (existingChunk == 0)
- 		in->nDataChunks++;
--	}
- 
--	yaffs_PutLevel0Tnode(dev,tn,chunkInInode,chunkInNAND);
-+	yaffs_PutLevel0Tnode(dev, tn, chunkInInode, chunkInNAND);
- 
- 	return YAFFS_OK;
- }
- 
--static int yaffs_ReadChunkDataFromObject(yaffs_Object * in, int chunkInInode,
--					 __u8 * buffer)
-+static int yaffs_ReadChunkDataFromObject(yaffs_Object *in, int chunkInInode,
-+					__u8 *buffer)
- {
- 	int chunkInNAND = yaffs_FindChunkInFile(in, chunkInInode, NULL);
- 
--	if (chunkInNAND >= 0) {
-+	if (chunkInNAND >= 0)
- 		return yaffs_ReadChunkWithTagsFromNAND(in->myDev, chunkInNAND,
--						       buffer,NULL);
--	} else {
-+						buffer, NULL);
-+	else {
- 		T(YAFFS_TRACE_NANDACCESS,
- 		  (TSTR("Chunk %d not found zero instead" TENDSTR),
- 		   chunkInNAND));
-@@ -3465,7 +3534,7 @@ static int yaffs_ReadChunkDataFromObject
- 
- }
- 
--void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn)
-+void yaffs_DeleteChunk(yaffs_Device *dev, int chunkId, int markNAND, int lyn)
- {
- 	int block;
- 	int page;
-@@ -3475,16 +3544,15 @@ void yaffs_DeleteChunk(yaffs_Device * de
- 	if (chunkId <= 0)
- 		return;
- 
--
- 	dev->nDeletions++;
- 	block = chunkId / dev->nChunksPerBlock;
- 	page = chunkId % dev->nChunksPerBlock;
- 
- 
--	if(!yaffs_CheckChunkBit(dev,block,page))
-+	if (!yaffs_CheckChunkBit(dev, block, page))
- 		T(YAFFS_TRACE_VERIFY,
--		 	(TSTR("Deleting invalid chunk %d"TENDSTR),
--		 	 chunkId));
-+			(TSTR("Deleting invalid chunk %d"TENDSTR),
-+			 chunkId));
- 
- 	bi = yaffs_GetBlockInfo(dev, block);
- 
-@@ -3524,14 +3592,12 @@ void yaffs_DeleteChunk(yaffs_Device * de
- 			yaffs_BlockBecameDirty(dev, block);
- 		}
- 
--	} else {
--		/* T(("Bad news deleting chunk %d\n",chunkId)); */
- 	}
- 
- }
- 
--static int yaffs_WriteChunkDataToObject(yaffs_Object * in, int chunkInInode,
--					const __u8 * buffer, int nBytes,
-+static int yaffs_WriteChunkDataToObject(yaffs_Object *in, int chunkInInode,
-+					const __u8 *buffer, int nBytes,
- 					int useReserve)
- {
- 	/* Find old chunk Need to do this to get serial number
-@@ -3561,6 +3627,12 @@ static int yaffs_WriteChunkDataToObject(
- 	    (prevChunkId >= 0) ? prevTags.serialNumber + 1 : 1;
- 	newTags.byteCount = nBytes;
- 
-+	if (nBytes < 1 || nBytes > dev->totalBytesPerChunk) {
-+		T(YAFFS_TRACE_ERROR,
-+		(TSTR("Writing %d bytes to chunk!!!!!!!!!" TENDSTR), nBytes));
-+		YBUG();
-+	}
-+
- 	newChunkId =
- 	    yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags,
- 					      useReserve);
-@@ -3568,11 +3640,9 @@ static int yaffs_WriteChunkDataToObject(
- 	if (newChunkId >= 0) {
- 		yaffs_PutChunkIntoFile(in, chunkInInode, newChunkId, 0);
- 
--		if (prevChunkId >= 0) {
-+		if (prevChunkId >= 0)
- 			yaffs_DeleteChunk(dev, prevChunkId, 1, __LINE__);
- 
--		}
--
- 		yaffs_CheckFileSanity(in);
- 	}
- 	return newChunkId;
-@@ -3582,7 +3652,7 @@ static int yaffs_WriteChunkDataToObject(
- /* UpdateObjectHeader updates the header on NAND for an object.
-  * If name is not NULL, then that new name is used.
-  */
--int yaffs_UpdateObjectHeader(yaffs_Object * in, const YCHAR * name, int force,
-+int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force,
- 			     int isShrink, int shadows)
- {
- 
-@@ -3603,9 +3673,12 @@ int yaffs_UpdateObjectHeader(yaffs_Objec
- 
- 	yaffs_ObjectHeader *oh = NULL;
- 
--	yaffs_strcpy(oldName,"silly old name");
-+	yaffs_strcpy(oldName, _Y("silly old name"));
- 
--	if (!in->fake || force) {
-+
-+	if (!in->fake ||
-+		in == dev->rootDir || /* The rootDir should also be saved */
-+		force) {
- 
- 		yaffs_CheckGarbageCollection(dev);
- 		yaffs_CheckObjectDetailsLoaded(in);
-@@ -3613,13 +3686,13 @@ int yaffs_UpdateObjectHeader(yaffs_Objec
- 		buffer = yaffs_GetTempBuffer(in->myDev, __LINE__);
- 		oh = (yaffs_ObjectHeader *) buffer;
- 
--		prevChunkId = in->chunkId;
-+		prevChunkId = in->hdrChunk;
- 
--		if (prevChunkId >= 0) {
-+		if (prevChunkId > 0) {
- 			result = yaffs_ReadChunkWithTagsFromNAND(dev, prevChunkId,
- 							buffer, &oldTags);
- 
--			yaffs_VerifyObjectHeader(in,oh,&oldTags,0);
-+			yaffs_VerifyObjectHeader(in, oh, &oldTags, 0);
- 
- 			memcpy(oldName, oh->name, sizeof(oh->name));
- 		}
-@@ -3628,7 +3701,7 @@ int yaffs_UpdateObjectHeader(yaffs_Objec
- 
- 		oh->type = in->variantType;
- 		oh->yst_mode = in->yst_mode;
--		oh->shadowsObject = shadows;
-+		oh->shadowsObject = oh->inbandShadowsObject = shadows;
- 
- #ifdef CONFIG_YAFFS_WINCE
- 		oh->win_atime[0] = in->win_atime[0];
-@@ -3645,20 +3718,18 @@ int yaffs_UpdateObjectHeader(yaffs_Objec
- 		oh->yst_ctime = in->yst_ctime;
- 		oh->yst_rdev = in->yst_rdev;
- #endif
--		if (in->parent) {
-+		if (in->parent)
- 			oh->parentObjectId = in->parent->objectId;
--		} else {
-+		else
- 			oh->parentObjectId = 0;
--		}
- 
- 		if (name && *name) {
- 			memset(oh->name, 0, sizeof(oh->name));
- 			yaffs_strncpy(oh->name, name, YAFFS_MAX_NAME_LENGTH);
--		} else if (prevChunkId>=0) {
-+		} else if (prevChunkId >= 0)
- 			memcpy(oh->name, oldName, sizeof(oh->name));
--		} else {
-+		else
- 			memset(oh->name, 0, sizeof(oh->name));
--		}
- 
- 		oh->isShrink = isShrink;
- 
-@@ -3708,7 +3779,7 @@ int yaffs_UpdateObjectHeader(yaffs_Objec
- 		newTags.extraShadows = (oh->shadowsObject > 0) ? 1 : 0;
- 		newTags.extraObjectType = in->variantType;
- 
--		yaffs_VerifyObjectHeader(in,oh,&newTags,1);
-+		yaffs_VerifyObjectHeader(in, oh, &newTags, 1);
- 
- 		/* Create new chunk in NAND */
- 		newChunkId =
-@@ -3717,20 +3788,20 @@ int yaffs_UpdateObjectHeader(yaffs_Objec
- 
- 		if (newChunkId >= 0) {
- 
--			in->chunkId = newChunkId;
-+			in->hdrChunk = newChunkId;
- 
- 			if (prevChunkId >= 0) {
- 				yaffs_DeleteChunk(dev, prevChunkId, 1,
- 						  __LINE__);
- 			}
- 
--			if(!yaffs_ObjectHasCachedWriteData(in))
-+			if (!yaffs_ObjectHasCachedWriteData(in))
- 				in->dirty = 0;
- 
- 			/* If this was a shrink, then mark the block that the chunk lives on */
- 			if (isShrink) {
- 				bi = yaffs_GetBlockInfo(in->myDev,
--							newChunkId /in->myDev->	nChunksPerBlock);
-+					newChunkId / in->myDev->nChunksPerBlock);
- 				bi->hasShrinkHeader = 1;
- 			}
- 
-@@ -3766,7 +3837,7 @@ static int yaffs_ObjectHasCachedWriteDat
- 	yaffs_ChunkCache *cache;
- 	int nCaches = obj->myDev->nShortOpCaches;
- 
--	for(i = 0; i < nCaches; i++){
-+	for (i = 0; i < nCaches; i++) {
- 		cache = &dev->srCache[i];
- 		if (cache->object == obj &&
- 		    cache->dirty)
-@@ -3777,7 +3848,7 @@ static int yaffs_ObjectHasCachedWriteDat
- }
- 
- 
--static void yaffs_FlushFilesChunkCache(yaffs_Object * obj)
-+static void yaffs_FlushFilesChunkCache(yaffs_Object *obj)
- {
- 	yaffs_Device *dev = obj->myDev;
- 	int lowest = -99;	/* Stop compiler whining. */
-@@ -3844,16 +3915,16 @@ void yaffs_FlushEntireDeviceCache(yaffs_
- 	 */
- 	do {
- 		obj = NULL;
--		for( i = 0; i < nCaches && !obj; i++) {
-+		for (i = 0; i < nCaches && !obj; i++) {
- 			if (dev->srCache[i].object &&
- 			    dev->srCache[i].dirty)
- 				obj = dev->srCache[i].object;
- 
- 		}
--		if(obj)
-+		if (obj)
- 			yaffs_FlushFilesChunkCache(obj);
- 
--	} while(obj);
-+	} while (obj);
- 
- }
- 
-@@ -3863,41 +3934,21 @@ void yaffs_FlushEntireDeviceCache(yaffs_
-  * Then look for the least recently used non-dirty one.
-  * Then look for the least recently used dirty one...., flush and look again.
-  */
--static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device * dev)
-+static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device *dev)
- {
- 	int i;
--	int usage;
--	int theOne;
- 
- 	if (dev->nShortOpCaches > 0) {
- 		for (i = 0; i < dev->nShortOpCaches; i++) {
- 			if (!dev->srCache[i].object)
- 				return &dev->srCache[i];
- 		}
-+	}
- 
--		return NULL;
-+	return NULL;
-+}
- 
--		theOne = -1;
--		usage = 0;	/* just to stop the compiler grizzling */
--
--		for (i = 0; i < dev->nShortOpCaches; i++) {
--			if (!dev->srCache[i].dirty &&
--			    ((dev->srCache[i].lastUse < usage && theOne >= 0) ||
--			     theOne < 0)) {
--				usage = dev->srCache[i].lastUse;
--				theOne = i;
--			}
--		}
--
--
--		return theOne >= 0 ? &dev->srCache[theOne] : NULL;
--	} else {
--		return NULL;
--	}
--
--}
--
--static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device * dev)
-+static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev)
- {
- 	yaffs_ChunkCache *cache;
- 	yaffs_Object *theObj;
-@@ -3927,8 +3978,7 @@ static yaffs_ChunkCache *yaffs_GrabChunk
- 			for (i = 0; i < dev->nShortOpCaches; i++) {
- 				if (dev->srCache[i].object &&
- 				    !dev->srCache[i].locked &&
--				    (dev->srCache[i].lastUse < usage || !cache))
--				{
-+				    (dev->srCache[i].lastUse < usage || !cache)) {
- 					usage = dev->srCache[i].lastUse;
- 					theObj = dev->srCache[i].object;
- 					cache = &dev->srCache[i];
-@@ -3950,7 +4000,7 @@ static yaffs_ChunkCache *yaffs_GrabChunk
- }
- 
- /* Find a cached chunk */
--static yaffs_ChunkCache *yaffs_FindChunkCache(const yaffs_Object * obj,
-+static yaffs_ChunkCache *yaffs_FindChunkCache(const yaffs_Object *obj,
- 					      int chunkId)
- {
- 	yaffs_Device *dev = obj->myDev;
-@@ -3969,7 +4019,7 @@ static yaffs_ChunkCache *yaffs_FindChunk
- }
- 
- /* Mark the chunk for the least recently used algorithym */
--static void yaffs_UseChunkCache(yaffs_Device * dev, yaffs_ChunkCache * cache,
-+static void yaffs_UseChunkCache(yaffs_Device *dev, yaffs_ChunkCache *cache,
- 				int isAWrite)
- {
- 
-@@ -3977,9 +4027,9 @@ static void yaffs_UseChunkCache(yaffs_De
- 		if (dev->srLastUse < 0 || dev->srLastUse > 100000000) {
- 			/* Reset the cache usages */
- 			int i;
--			for (i = 1; i < dev->nShortOpCaches; i++) {
-+			for (i = 1; i < dev->nShortOpCaches; i++)
- 				dev->srCache[i].lastUse = 0;
--			}
-+
- 			dev->srLastUse = 0;
- 		}
- 
-@@ -3987,9 +4037,8 @@ static void yaffs_UseChunkCache(yaffs_De
- 
- 		cache->lastUse = dev->srLastUse;
- 
--		if (isAWrite) {
-+		if (isAWrite)
- 			cache->dirty = 1;
--		}
- 	}
- }
- 
-@@ -3997,21 +4046,20 @@ static void yaffs_UseChunkCache(yaffs_De
-  * Do this when a whole page gets written,
-  * ie the short cache for this page is no longer valid.
-  */
--static void yaffs_InvalidateChunkCache(yaffs_Object * object, int chunkId)
-+static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId)
- {
- 	if (object->myDev->nShortOpCaches > 0) {
- 		yaffs_ChunkCache *cache = yaffs_FindChunkCache(object, chunkId);
- 
--		if (cache) {
-+		if (cache)
- 			cache->object = NULL;
--		}
- 	}
- }
- 
- /* Invalidate all the cache pages associated with this object
-  * Do this whenever ther file is deleted or resized.
-  */
--static void yaffs_InvalidateWholeChunkCache(yaffs_Object * in)
-+static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in)
- {
- 	int i;
- 	yaffs_Device *dev = in->myDev;
-@@ -4019,9 +4067,8 @@ static void yaffs_InvalidateWholeChunkCa
- 	if (dev->nShortOpCaches > 0) {
- 		/* Invalidate it. */
- 		for (i = 0; i < dev->nShortOpCaches; i++) {
--			if (dev->srCache[i].object == in) {
-+			if (dev->srCache[i].object == in)
- 				dev->srCache[i].object = NULL;
--			}
- 		}
- 	}
- }
-@@ -4029,18 +4076,18 @@ static void yaffs_InvalidateWholeChunkCa
- /*--------------------- Checkpointing --------------------*/
- 
- 
--static int yaffs_WriteCheckpointValidityMarker(yaffs_Device *dev,int head)
-+static int yaffs_WriteCheckpointValidityMarker(yaffs_Device *dev, int head)
- {
- 	yaffs_CheckpointValidity cp;
- 
--	memset(&cp,0,sizeof(cp));
-+	memset(&cp, 0, sizeof(cp));
- 
- 	cp.structType = sizeof(cp);
- 	cp.magic = YAFFS_MAGIC;
- 	cp.version = YAFFS_CHECKPOINT_VERSION;
- 	cp.head = (head) ? 1 : 0;
- 
--	return (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp))?
-+	return (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp)) ?
- 		1 : 0;
- }
- 
-@@ -4049,9 +4096,9 @@ static int yaffs_ReadCheckpointValidityM
- 	yaffs_CheckpointValidity cp;
- 	int ok;
- 
--	ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp));
-+	ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp));
- 
--	if(ok)
-+	if (ok)
- 		ok = (cp.structType == sizeof(cp)) &&
- 		     (cp.magic == YAFFS_MAGIC) &&
- 		     (cp.version == YAFFS_CHECKPOINT_VERSION) &&
-@@ -4100,21 +4147,21 @@ static int yaffs_WriteCheckpointDevice(y
- 	int ok;
- 
- 	/* Write device runtime values*/
--	yaffs_DeviceToCheckpointDevice(&cp,dev);
-+	yaffs_DeviceToCheckpointDevice(&cp, dev);
- 	cp.structType = sizeof(cp);
- 
--	ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp));
-+	ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
- 
- 	/* Write block info */
--	if(ok) {
-+	if (ok) {
- 		nBytes = nBlocks * sizeof(yaffs_BlockInfo);
--		ok = (yaffs_CheckpointWrite(dev,dev->blockInfo,nBytes) == nBytes);
-+		ok = (yaffs_CheckpointWrite(dev, dev->blockInfo, nBytes) == nBytes);
- 	}
- 
- 	/* Write chunk bits */
--	if(ok) {
-+	if (ok) {
- 		nBytes = nBlocks * dev->chunkBitmapStride;
--		ok = (yaffs_CheckpointWrite(dev,dev->chunkBits,nBytes) == nBytes);
-+		ok = (yaffs_CheckpointWrite(dev, dev->chunkBits, nBytes) == nBytes);
- 	}
- 	return	 ok ? 1 : 0;
- 
-@@ -4128,25 +4175,25 @@ static int yaffs_ReadCheckpointDevice(ya
- 
- 	int ok;
- 
--	ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp));
--	if(!ok)
-+	ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp));
-+	if (!ok)
- 		return 0;
- 
--	if(cp.structType != sizeof(cp))
-+	if (cp.structType != sizeof(cp))
- 		return 0;
- 
- 
--	yaffs_CheckpointDeviceToDevice(dev,&cp);
-+	yaffs_CheckpointDeviceToDevice(dev, &cp);
- 
- 	nBytes = nBlocks * sizeof(yaffs_BlockInfo);
- 
--	ok = (yaffs_CheckpointRead(dev,dev->blockInfo,nBytes) == nBytes);
-+	ok = (yaffs_CheckpointRead(dev, dev->blockInfo, nBytes) == nBytes);
- 
--	if(!ok)
-+	if (!ok)
- 		return 0;
- 	nBytes = nBlocks * dev->chunkBitmapStride;
- 
--	ok = (yaffs_CheckpointRead(dev,dev->chunkBits,nBytes) == nBytes);
-+	ok = (yaffs_CheckpointRead(dev, dev->chunkBits, nBytes) == nBytes);
- 
- 	return ok ? 1 : 0;
- }
-@@ -4157,7 +4204,7 @@ static void yaffs_ObjectToCheckpointObje
- 
- 	cp->objectId = obj->objectId;
- 	cp->parentId = (obj->parent) ? obj->parent->objectId : 0;
--	cp->chunkId = obj->chunkId;
-+	cp->hdrChunk = obj->hdrChunk;
- 	cp->variantType = obj->variantType;
- 	cp->deleted = obj->deleted;
- 	cp->softDeleted = obj->softDeleted;
-@@ -4168,20 +4215,28 @@ static void yaffs_ObjectToCheckpointObje
- 	cp->serial = obj->serial;
- 	cp->nDataChunks = obj->nDataChunks;
- 
--	if(obj->variantType == YAFFS_OBJECT_TYPE_FILE)
-+	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE)
- 		cp->fileSizeOrEquivalentObjectId = obj->variant.fileVariant.fileSize;
--	else if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK)
-+	else if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK)
- 		cp->fileSizeOrEquivalentObjectId = obj->variant.hardLinkVariant.equivalentObjectId;
- }
- 
--static void yaffs_CheckpointObjectToObject( yaffs_Object *obj,yaffs_CheckpointObject *cp)
-+static int yaffs_CheckpointObjectToObject(yaffs_Object *obj, yaffs_CheckpointObject *cp)
- {
- 
- 	yaffs_Object *parent;
- 
-+	if (obj->variantType != cp->variantType) {
-+		T(YAFFS_TRACE_ERROR, (TSTR("Checkpoint read object %d type %d "
-+			TCONT("chunk %d does not match existing object type %d")
-+			TENDSTR), cp->objectId, cp->variantType, cp->hdrChunk,
-+			obj->variantType));
-+		return 0;
-+	}
-+
- 	obj->objectId = cp->objectId;
- 
--	if(cp->parentId)
-+	if (cp->parentId)
- 		parent = yaffs_FindOrCreateObjectByNumber(
- 					obj->myDev,
- 					cp->parentId,
-@@ -4189,10 +4244,19 @@ static void yaffs_CheckpointObjectToObje
- 	else
- 		parent = NULL;
- 
--	if(parent)
-+	if (parent) {
-+		if (parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+			T(YAFFS_TRACE_ALWAYS, (TSTR("Checkpoint read object %d parent %d type %d"
-+				TCONT(" chunk %d Parent type, %d, not directory")
-+				TENDSTR),
-+				cp->objectId, cp->parentId, cp->variantType,
-+				cp->hdrChunk, parent->variantType));
-+			return 0;
-+		}
- 		yaffs_AddObjectToDirectory(parent, obj);
-+	}
- 
--	obj->chunkId = cp->chunkId;
-+	obj->hdrChunk = cp->hdrChunk;
- 	obj->variantType = cp->variantType;
- 	obj->deleted = cp->deleted;
- 	obj->softDeleted = cp->softDeleted;
-@@ -4203,29 +4267,34 @@ static void yaffs_CheckpointObjectToObje
- 	obj->serial = cp->serial;
- 	obj->nDataChunks = cp->nDataChunks;
- 
--	if(obj->variantType == YAFFS_OBJECT_TYPE_FILE)
-+	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE)
- 		obj->variant.fileVariant.fileSize = cp->fileSizeOrEquivalentObjectId;
--	else if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK)
-+	else if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK)
- 		obj->variant.hardLinkVariant.equivalentObjectId = cp->fileSizeOrEquivalentObjectId;
- 
--	if(obj->objectId >= YAFFS_NOBJECT_BUCKETS)
-+	if (obj->hdrChunk > 0)
- 		obj->lazyLoaded = 1;
-+	return 1;
- }
- 
- 
- 
--static int yaffs_CheckpointTnodeWorker(yaffs_Object * in, yaffs_Tnode * tn,
--				  	__u32 level, int chunkOffset)
-+static int yaffs_CheckpointTnodeWorker(yaffs_Object *in, yaffs_Tnode *tn,
-+					__u32 level, int chunkOffset)
- {
- 	int i;
- 	yaffs_Device *dev = in->myDev;
- 	int ok = 1;
--	int nTnodeBytes = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
-+	int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
-+
-+	if (tnodeSize < sizeof(yaffs_Tnode))
-+		tnodeSize = sizeof(yaffs_Tnode);
-+
- 
- 	if (tn) {
- 		if (level > 0) {
- 
--			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++){
-+			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
- 				if (tn->internal[i]) {
- 					ok = yaffs_CheckpointTnodeWorker(in,
- 							tn->internal[i],
-@@ -4235,10 +4304,9 @@ static int yaffs_CheckpointTnodeWorker(y
- 			}
- 		} else if (level == 0) {
- 			__u32 baseOffset = chunkOffset <<  YAFFS_TNODES_LEVEL0_BITS;
--			/* printf("write tnode at %d\n",baseOffset); */
--			ok = (yaffs_CheckpointWrite(dev,&baseOffset,sizeof(baseOffset)) == sizeof(baseOffset));
--			if(ok)
--				ok = (yaffs_CheckpointWrite(dev,tn,nTnodeBytes) == nTnodeBytes);
-+			ok = (yaffs_CheckpointWrite(dev, &baseOffset, sizeof(baseOffset)) == sizeof(baseOffset));
-+			if (ok)
-+				ok = (yaffs_CheckpointWrite(dev, tn, tnodeSize) == tnodeSize);
- 		}
- 	}
- 
-@@ -4251,13 +4319,13 @@ static int yaffs_WriteCheckpointTnodes(y
- 	__u32 endMarker = ~0;
- 	int ok = 1;
- 
--	if(obj->variantType == YAFFS_OBJECT_TYPE_FILE){
-+	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE) {
- 		ok = yaffs_CheckpointTnodeWorker(obj,
- 					    obj->variant.fileVariant.top,
- 					    obj->variant.fileVariant.topLevel,
- 					    0);
--		if(ok)
--			ok = (yaffs_CheckpointWrite(obj->myDev,&endMarker,sizeof(endMarker)) ==
-+		if (ok)
-+			ok = (yaffs_CheckpointWrite(obj->myDev, &endMarker, sizeof(endMarker)) ==
- 				sizeof(endMarker));
- 	}
- 
-@@ -4272,38 +4340,38 @@ static int yaffs_ReadCheckpointTnodes(ya
- 	yaffs_FileStructure *fileStructPtr = &obj->variant.fileVariant;
- 	yaffs_Tnode *tn;
- 	int nread = 0;
-+	int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
- 
--	ok = (yaffs_CheckpointRead(dev,&baseChunk,sizeof(baseChunk)) == sizeof(baseChunk));
-+	if (tnodeSize < sizeof(yaffs_Tnode))
-+		tnodeSize = sizeof(yaffs_Tnode);
- 
--	while(ok && (~baseChunk)){
-+	ok = (yaffs_CheckpointRead(dev, &baseChunk, sizeof(baseChunk)) == sizeof(baseChunk));
-+
-+	while (ok && (~baseChunk)) {
- 		nread++;
- 		/* Read level 0 tnode */
- 
- 
--		/* printf("read  tnode at %d\n",baseChunk); */
- 		tn = yaffs_GetTnodeRaw(dev);
--		if(tn)
--			ok = (yaffs_CheckpointRead(dev,tn,(dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8) ==
--			      (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
-+		if (tn)
-+			ok = (yaffs_CheckpointRead(dev, tn, tnodeSize) == tnodeSize);
- 		else
- 			ok = 0;
- 
--		if(tn && ok){
-+		if (tn && ok)
- 			ok = yaffs_AddOrFindLevel0Tnode(dev,
--					       		fileStructPtr,
--					       		baseChunk,
--					       		tn) ? 1 : 0;
-+							fileStructPtr,
-+							baseChunk,
-+							tn) ? 1 : 0;
- 
--		}
--
--		if(ok)
--			ok = (yaffs_CheckpointRead(dev,&baseChunk,sizeof(baseChunk)) == sizeof(baseChunk));
-+		if (ok)
-+			ok = (yaffs_CheckpointRead(dev, &baseChunk, sizeof(baseChunk)) == sizeof(baseChunk));
- 
- 	}
- 
--	T(YAFFS_TRACE_CHECKPOINT,(
-+	T(YAFFS_TRACE_CHECKPOINT, (
- 		TSTR("Checkpoint read tnodes %d records, last %d. ok %d" TENDSTR),
--		nread,baseChunk,ok));
-+		nread, baseChunk, ok));
- 
- 	return ok ? 1 : 0;
- }
-@@ -4315,41 +4383,40 @@ static int yaffs_WriteCheckpointObjects(
- 	yaffs_CheckpointObject cp;
- 	int i;
- 	int ok = 1;
--	struct list_head *lh;
-+	struct ylist_head *lh;
- 
- 
- 	/* Iterate through the objects in each hash entry,
- 	 * dumping them to the checkpointing stream.
- 	 */
- 
--	 for(i = 0; ok &&  i <  YAFFS_NOBJECT_BUCKETS; i++){
--	 	list_for_each(lh, &dev->objectBucket[i].list) {
-+	for (i = 0; ok &&  i <  YAFFS_NOBJECT_BUCKETS; i++) {
-+		ylist_for_each(lh, &dev->objectBucket[i].list) {
- 			if (lh) {
--				obj = list_entry(lh, yaffs_Object, hashLink);
-+				obj = ylist_entry(lh, yaffs_Object, hashLink);
- 				if (!obj->deferedFree) {
--					yaffs_ObjectToCheckpointObject(&cp,obj);
-+					yaffs_ObjectToCheckpointObject(&cp, obj);
- 					cp.structType = sizeof(cp);
- 
--					T(YAFFS_TRACE_CHECKPOINT,(
-+					T(YAFFS_TRACE_CHECKPOINT, (
- 						TSTR("Checkpoint write object %d parent %d type %d chunk %d obj addr %x" TENDSTR),
--						cp.objectId,cp.parentId,cp.variantType,cp.chunkId,(unsigned) obj));
-+						cp.objectId, cp.parentId, cp.variantType, cp.hdrChunk, (unsigned) obj));
- 
--					ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp));
-+					ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
- 
--					if(ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE){
-+					if (ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE)
- 						ok = yaffs_WriteCheckpointTnodes(obj);
--					}
- 				}
- 			}
- 		}
--	 }
-+	}
- 
--	 /* Dump end of list */
--	memset(&cp,0xFF,sizeof(yaffs_CheckpointObject));
-+	/* Dump end of list */
-+	memset(&cp, 0xFF, sizeof(yaffs_CheckpointObject));
- 	cp.structType = sizeof(cp);
- 
--	if(ok)
--		ok = (yaffs_CheckpointWrite(dev,&cp,sizeof(cp)) == sizeof(cp));
-+	if (ok)
-+		ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
- 
- 	return ok ? 1 : 0;
- }
-@@ -4362,38 +4429,39 @@ static int yaffs_ReadCheckpointObjects(y
- 	int done = 0;
- 	yaffs_Object *hardList = NULL;
- 
--	while(ok && !done) {
--		ok = (yaffs_CheckpointRead(dev,&cp,sizeof(cp)) == sizeof(cp));
--		if(cp.structType != sizeof(cp)) {
--			T(YAFFS_TRACE_CHECKPOINT,(TSTR("struct size %d instead of %d ok %d"TENDSTR),
--				cp.structType,sizeof(cp),ok));
-+	while (ok && !done) {
-+		ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp));
-+		if (cp.structType != sizeof(cp)) {
-+			T(YAFFS_TRACE_CHECKPOINT, (TSTR("struct size %d instead of %d ok %d"TENDSTR),
-+				cp.structType, sizeof(cp), ok));
- 			ok = 0;
- 		}
- 
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("Checkpoint read object %d parent %d type %d chunk %d " TENDSTR),
--			cp.objectId,cp.parentId,cp.variantType,cp.chunkId));
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("Checkpoint read object %d parent %d type %d chunk %d " TENDSTR),
-+			cp.objectId, cp.parentId, cp.variantType, cp.hdrChunk));
- 
--		if(ok && cp.objectId == ~0)
-+		if (ok && cp.objectId == ~0)
- 			done = 1;
--		else if(ok){
--			obj = yaffs_FindOrCreateObjectByNumber(dev,cp.objectId, cp.variantType);
--			if(obj) {
--				yaffs_CheckpointObjectToObject(obj,&cp);
--				if(obj->variantType == YAFFS_OBJECT_TYPE_FILE) {
-+		else if (ok) {
-+			obj = yaffs_FindOrCreateObjectByNumber(dev, cp.objectId, cp.variantType);
-+			if (obj) {
-+				ok = yaffs_CheckpointObjectToObject(obj, &cp);
-+				if (!ok)
-+					break;
-+				if (obj->variantType == YAFFS_OBJECT_TYPE_FILE) {
- 					ok = yaffs_ReadCheckpointTnodes(obj);
--				} else if(obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
-+				} else if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
- 					obj->hardLinks.next =
--						    (struct list_head *)
--						    hardList;
-+						(struct ylist_head *) hardList;
- 					hardList = obj;
- 				}
--
--			}
-+			} else
-+				ok = 0;
- 		}
- 	}
- 
--	if(ok)
--		yaffs_HardlinkFixup(dev,hardList);
-+	if (ok)
-+		yaffs_HardlinkFixup(dev, hardList);
- 
- 	return ok ? 1 : 0;
- }
-@@ -4403,11 +4471,11 @@ static int yaffs_WriteCheckpointSum(yaff
- 	__u32 checkpointSum;
- 	int ok;
- 
--	yaffs_GetCheckpointSum(dev,&checkpointSum);
-+	yaffs_GetCheckpointSum(dev, &checkpointSum);
- 
--	ok = (yaffs_CheckpointWrite(dev,&checkpointSum,sizeof(checkpointSum)) == sizeof(checkpointSum));
-+	ok = (yaffs_CheckpointWrite(dev, &checkpointSum, sizeof(checkpointSum)) == sizeof(checkpointSum));
- 
--	if(!ok)
-+	if (!ok)
- 		return 0;
- 
- 	return 1;
-@@ -4419,14 +4487,14 @@ static int yaffs_ReadCheckpointSum(yaffs
- 	__u32 checkpointSum1;
- 	int ok;
- 
--	yaffs_GetCheckpointSum(dev,&checkpointSum0);
-+	yaffs_GetCheckpointSum(dev, &checkpointSum0);
- 
--	ok = (yaffs_CheckpointRead(dev,&checkpointSum1,sizeof(checkpointSum1)) == sizeof(checkpointSum1));
-+	ok = (yaffs_CheckpointRead(dev, &checkpointSum1, sizeof(checkpointSum1)) == sizeof(checkpointSum1));
- 
--	if(!ok)
-+	if (!ok)
- 		return 0;
- 
--	if(checkpointSum0 != checkpointSum1)
-+	if (checkpointSum0 != checkpointSum1)
- 		return 0;
- 
- 	return 1;
-@@ -4435,46 +4503,43 @@ static int yaffs_ReadCheckpointSum(yaffs
- 
- static int yaffs_WriteCheckpointData(yaffs_Device *dev)
- {
--
- 	int ok = 1;
- 
--	if(dev->skipCheckpointWrite || !dev->isYaffs2){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("skipping checkpoint write" TENDSTR)));
-+	if (dev->skipCheckpointWrite || !dev->isYaffs2) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint write" TENDSTR)));
- 		ok = 0;
- 	}
- 
--	if(ok)
--		ok = yaffs_CheckpointOpen(dev,1);
-+	if (ok)
-+		ok = yaffs_CheckpointOpen(dev, 1);
- 
--	if(ok){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("write checkpoint validity" TENDSTR)));
--		ok = yaffs_WriteCheckpointValidityMarker(dev,1);
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint validity" TENDSTR)));
-+		ok = yaffs_WriteCheckpointValidityMarker(dev, 1);
- 	}
--	if(ok){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("write checkpoint device" TENDSTR)));
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint device" TENDSTR)));
- 		ok = yaffs_WriteCheckpointDevice(dev);
- 	}
--	if(ok){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("write checkpoint objects" TENDSTR)));
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint objects" TENDSTR)));
- 		ok = yaffs_WriteCheckpointObjects(dev);
- 	}
--	if(ok){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("write checkpoint validity" TENDSTR)));
--		ok = yaffs_WriteCheckpointValidityMarker(dev,0);
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint validity" TENDSTR)));
-+		ok = yaffs_WriteCheckpointValidityMarker(dev, 0);
- 	}
- 
--	if(ok){
-+	if (ok)
- 		ok = yaffs_WriteCheckpointSum(dev);
--	}
--
- 
--	if(!yaffs_CheckpointClose(dev))
--		 ok = 0;
-+	if (!yaffs_CheckpointClose(dev))
-+		ok = 0;
- 
--	if(ok)
--	    	dev->isCheckpointed = 1;
--	 else
--	 	dev->isCheckpointed = 0;
-+	if (ok)
-+		dev->isCheckpointed = 1;
-+	else
-+		dev->isCheckpointed = 0;
- 
- 	return dev->isCheckpointed;
- }
-@@ -4483,43 +4548,43 @@ static int yaffs_ReadCheckpointData(yaff
- {
- 	int ok = 1;
- 
--	if(dev->skipCheckpointRead || !dev->isYaffs2){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("skipping checkpoint read" TENDSTR)));
-+	if (dev->skipCheckpointRead || !dev->isYaffs2) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint read" TENDSTR)));
- 		ok = 0;
- 	}
- 
--	if(ok)
--		ok = yaffs_CheckpointOpen(dev,0); /* open for read */
-+	if (ok)
-+		ok = yaffs_CheckpointOpen(dev, 0); /* open for read */
- 
--	if(ok){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint validity" TENDSTR)));
--		ok = yaffs_ReadCheckpointValidityMarker(dev,1);
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint validity" TENDSTR)));
-+		ok = yaffs_ReadCheckpointValidityMarker(dev, 1);
- 	}
--	if(ok){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint device" TENDSTR)));
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint device" TENDSTR)));
- 		ok = yaffs_ReadCheckpointDevice(dev);
- 	}
--	if(ok){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint objects" TENDSTR)));
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint objects" TENDSTR)));
- 		ok = yaffs_ReadCheckpointObjects(dev);
- 	}
--	if(ok){
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint validity" TENDSTR)));
--		ok = yaffs_ReadCheckpointValidityMarker(dev,0);
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint validity" TENDSTR)));
-+		ok = yaffs_ReadCheckpointValidityMarker(dev, 0);
- 	}
- 
--	if(ok){
-+	if (ok) {
- 		ok = yaffs_ReadCheckpointSum(dev);
--		T(YAFFS_TRACE_CHECKPOINT,(TSTR("read checkpoint checksum %d" TENDSTR),ok));
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint checksum %d" TENDSTR), ok));
- 	}
- 
--	if(!yaffs_CheckpointClose(dev))
-+	if (!yaffs_CheckpointClose(dev))
- 		ok = 0;
- 
--	if(ok)
--	    	dev->isCheckpointed = 1;
--	 else
--	 	dev->isCheckpointed = 0;
-+	if (ok)
-+		dev->isCheckpointed = 1;
-+	else
-+		dev->isCheckpointed = 0;
- 
- 	return ok ? 1 : 0;
- 
-@@ -4527,11 +4592,11 @@ static int yaffs_ReadCheckpointData(yaff
- 
- static void yaffs_InvalidateCheckpoint(yaffs_Device *dev)
- {
--	if(dev->isCheckpointed ||
--	   dev->blocksInCheckpoint > 0){
-+	if (dev->isCheckpointed ||
-+			dev->blocksInCheckpoint > 0) {
- 		dev->isCheckpointed = 0;
- 		yaffs_CheckpointInvalidateStream(dev);
--		if(dev->superBlock && dev->markSuperBlockDirty)
-+		if (dev->superBlock && dev->markSuperBlockDirty)
- 			dev->markSuperBlockDirty(dev->superBlock);
- 	}
- }
-@@ -4540,18 +4605,18 @@ static void yaffs_InvalidateCheckpoint(y
- int yaffs_CheckpointSave(yaffs_Device *dev)
- {
- 
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("save entry: isCheckpointed %d"TENDSTR),dev->isCheckpointed));
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("save entry: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
- 
- 	yaffs_VerifyObjects(dev);
- 	yaffs_VerifyBlocks(dev);
- 	yaffs_VerifyFreeChunks(dev);
- 
--	if(!dev->isCheckpointed) {
-+	if (!dev->isCheckpointed) {
- 		yaffs_InvalidateCheckpoint(dev);
- 		yaffs_WriteCheckpointData(dev);
- 	}
- 
--	T(YAFFS_TRACE_ALWAYS,(TSTR("save exit: isCheckpointed %d"TENDSTR),dev->isCheckpointed));
-+	T(YAFFS_TRACE_ALWAYS, (TSTR("save exit: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
- 
- 	return dev->isCheckpointed;
- }
-@@ -4559,17 +4624,17 @@ int yaffs_CheckpointSave(yaffs_Device *d
- int yaffs_CheckpointRestore(yaffs_Device *dev)
- {
- 	int retval;
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("restore entry: isCheckpointed %d"TENDSTR),dev->isCheckpointed));
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("restore entry: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
- 
- 	retval = yaffs_ReadCheckpointData(dev);
- 
--	if(dev->isCheckpointed){
-+	if (dev->isCheckpointed) {
- 		yaffs_VerifyObjects(dev);
- 		yaffs_VerifyBlocks(dev);
- 		yaffs_VerifyFreeChunks(dev);
- 	}
- 
--	T(YAFFS_TRACE_CHECKPOINT,(TSTR("restore exit: isCheckpointed %d"TENDSTR),dev->isCheckpointed));
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("restore exit: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
- 
- 	return retval;
- }
-@@ -4584,12 +4649,12 @@ int yaffs_CheckpointRestore(yaffs_Device
-  * Curve-balls: the first chunk might also be the last chunk.
-  */
- 
--int yaffs_ReadDataFromFile(yaffs_Object * in, __u8 * buffer, loff_t offset,
--			   int nBytes)
-+int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 *buffer, loff_t offset,
-+			int nBytes)
- {
- 
- 	int chunk;
--	int start;
-+	__u32 start;
- 	int nToCopy;
- 	int n = nBytes;
- 	int nDone = 0;
-@@ -4600,27 +4665,26 @@ int yaffs_ReadDataFromFile(yaffs_Object
- 	dev = in->myDev;
- 
- 	while (n > 0) {
--		//chunk = offset / dev->nDataBytesPerChunk + 1;
--		//start = offset % dev->nDataBytesPerChunk;
--		yaffs_AddrToChunk(dev,offset,&chunk,&start);
-+		/* chunk = offset / dev->nDataBytesPerChunk + 1; */
-+		/* start = offset % dev->nDataBytesPerChunk; */
-+		yaffs_AddrToChunk(dev, offset, &chunk, &start);
- 		chunk++;
- 
- 		/* OK now check for the curveball where the start and end are in
- 		 * the same chunk.
- 		 */
--		if ((start + n) < dev->nDataBytesPerChunk) {
-+		if ((start + n) < dev->nDataBytesPerChunk)
- 			nToCopy = n;
--		} else {
-+		else
- 			nToCopy = dev->nDataBytesPerChunk - start;
--		}
- 
- 		cache = yaffs_FindChunkCache(in, chunk);
- 
- 		/* If the chunk is already in the cache or it is less than a whole chunk
--		 * then use the cache (if there is caching)
-+		 * or we're using inband tags then use the cache (if there is caching)
- 		 * else bypass the cache.
- 		 */
--		if (cache || nToCopy != dev->nDataBytesPerChunk) {
-+		if (cache || nToCopy != dev->nDataBytesPerChunk || dev->inbandTags) {
- 			if (dev->nShortOpCaches > 0) {
- 
- 				/* If we can't find the data in the cache, then load it up. */
-@@ -4641,14 +4705,9 @@ int yaffs_ReadDataFromFile(yaffs_Object
- 
- 				cache->locked = 1;
- 
--#ifdef CONFIG_YAFFS_WINCE
--				yfsd_UnlockYAFFS(TRUE);
--#endif
-+
- 				memcpy(buffer, &cache->data[start], nToCopy);
- 
--#ifdef CONFIG_YAFFS_WINCE
--				yfsd_LockYAFFS(TRUE);
--#endif
- 				cache->locked = 0;
- 			} else {
- 				/* Read into the local buffer then copy..*/
-@@ -4657,41 +4716,19 @@ int yaffs_ReadDataFromFile(yaffs_Object
- 				    yaffs_GetTempBuffer(dev, __LINE__);
- 				yaffs_ReadChunkDataFromObject(in, chunk,
- 							      localBuffer);
--#ifdef CONFIG_YAFFS_WINCE
--				yfsd_UnlockYAFFS(TRUE);
--#endif
-+
- 				memcpy(buffer, &localBuffer[start], nToCopy);
- 
--#ifdef CONFIG_YAFFS_WINCE
--				yfsd_LockYAFFS(TRUE);
--#endif
-+
- 				yaffs_ReleaseTempBuffer(dev, localBuffer,
- 							__LINE__);
- 			}
- 
- 		} else {
--#ifdef CONFIG_YAFFS_WINCE
--			__u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__);
--
--			/* Under WinCE can't do direct transfer. Need to use a local buffer.
--			 * This is because we otherwise screw up WinCE's memory mapper
--			 */
--			yaffs_ReadChunkDataFromObject(in, chunk, localBuffer);
--
--#ifdef CONFIG_YAFFS_WINCE
--			yfsd_UnlockYAFFS(TRUE);
--#endif
--			memcpy(buffer, localBuffer, dev->nDataBytesPerChunk);
- 
--#ifdef CONFIG_YAFFS_WINCE
--			yfsd_LockYAFFS(TRUE);
--			yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__);
--#endif
--
--#else
- 			/* A full chunk. Read directly into the supplied buffer. */
- 			yaffs_ReadChunkDataFromObject(in, chunk, buffer);
--#endif
-+
- 		}
- 
- 		n -= nToCopy;
-@@ -4704,28 +4741,37 @@ int yaffs_ReadDataFromFile(yaffs_Object
- 	return nDone;
- }
- 
--int yaffs_WriteDataToFile(yaffs_Object * in, const __u8 * buffer, loff_t offset,
--			  int nBytes, int writeThrough)
-+int yaffs_WriteDataToFile(yaffs_Object *in, const __u8 *buffer, loff_t offset,
-+			int nBytes, int writeThrough)
- {
- 
- 	int chunk;
--	int start;
-+	__u32 start;
- 	int nToCopy;
- 	int n = nBytes;
- 	int nDone = 0;
- 	int nToWriteBack;
- 	int startOfWrite = offset;
- 	int chunkWritten = 0;
--	int nBytesRead;
-+	__u32 nBytesRead;
-+	__u32 chunkStart;
- 
- 	yaffs_Device *dev;
- 
- 	dev = in->myDev;
- 
- 	while (n > 0 && chunkWritten >= 0) {
--		//chunk = offset / dev->nDataBytesPerChunk + 1;
--		//start = offset % dev->nDataBytesPerChunk;
--		yaffs_AddrToChunk(dev,offset,&chunk,&start);
-+		/* chunk = offset / dev->nDataBytesPerChunk + 1; */
-+		/* start = offset % dev->nDataBytesPerChunk; */
-+		yaffs_AddrToChunk(dev, offset, &chunk, &start);
-+
-+		if (chunk * dev->nDataBytesPerChunk + start != offset ||
-+				start >= dev->nDataBytesPerChunk) {
-+			T(YAFFS_TRACE_ERROR, (
-+			   TSTR("AddrToChunk of offset %d gives chunk %d start %d"
-+			   TENDSTR),
-+			   (int)offset, chunk, start));
-+		}
- 		chunk++;
- 
- 		/* OK now check for the curveball where the start and end are in
-@@ -4740,25 +4786,32 @@ int yaffs_WriteDataToFile(yaffs_Object *
- 			 * we need to write back as much as was there before.
- 			 */
- 
--			nBytesRead =
--			    in->variant.fileVariant.fileSize -
--			    ((chunk - 1) * dev->nDataBytesPerChunk);
-+			chunkStart = ((chunk - 1) * dev->nDataBytesPerChunk);
-+
-+			if (chunkStart > in->variant.fileVariant.fileSize)
-+				nBytesRead = 0; /* Past end of file */
-+			else
-+				nBytesRead = in->variant.fileVariant.fileSize - chunkStart;
- 
--			if (nBytesRead > dev->nDataBytesPerChunk) {
-+			if (nBytesRead > dev->nDataBytesPerChunk)
- 				nBytesRead = dev->nDataBytesPerChunk;
--			}
- 
- 			nToWriteBack =
- 			    (nBytesRead >
- 			     (start + n)) ? nBytesRead : (start + n);
- 
-+			if (nToWriteBack < 0 || nToWriteBack > dev->nDataBytesPerChunk)
-+				YBUG();
-+
- 		} else {
- 			nToCopy = dev->nDataBytesPerChunk - start;
- 			nToWriteBack = dev->nDataBytesPerChunk;
- 		}
- 
--		if (nToCopy != dev->nDataBytesPerChunk) {
--			/* An incomplete start or end chunk (or maybe both start and end chunk) */
-+		if (nToCopy != dev->nDataBytesPerChunk || dev->inbandTags) {
-+			/* An incomplete start or end chunk (or maybe both start and end chunk),
-+			 * or we're using inband tags, so we want to use the cache buffers.
-+			 */
- 			if (dev->nShortOpCaches > 0) {
- 				yaffs_ChunkCache *cache;
- 				/* If we can't find the data in the cache, then load the cache */
-@@ -4775,10 +4828,9 @@ int yaffs_WriteDataToFile(yaffs_Object *
- 					yaffs_ReadChunkDataFromObject(in, chunk,
- 								      cache->
- 								      data);
--				}
--				else if(cache &&
--				        !cache->dirty &&
--					!yaffs_CheckSpaceForAllocation(in->myDev)){
-+				} else if (cache &&
-+					!cache->dirty &&
-+					!yaffs_CheckSpaceForAllocation(in->myDev)) {
- 					/* Drop the cache if it was a read cache item and
- 					 * no space check has been made for it.
- 					 */
-@@ -4788,16 +4840,12 @@ int yaffs_WriteDataToFile(yaffs_Object *
- 				if (cache) {
- 					yaffs_UseChunkCache(dev, cache, 1);
- 					cache->locked = 1;
--#ifdef CONFIG_YAFFS_WINCE
--					yfsd_UnlockYAFFS(TRUE);
--#endif
-+
- 
- 					memcpy(&cache->data[start], buffer,
- 					       nToCopy);
- 
--#ifdef CONFIG_YAFFS_WINCE
--					yfsd_LockYAFFS(TRUE);
--#endif
-+
- 					cache->locked = 0;
- 					cache->nBytes = nToWriteBack;
- 
-@@ -4825,15 +4873,10 @@ int yaffs_WriteDataToFile(yaffs_Object *
- 				yaffs_ReadChunkDataFromObject(in, chunk,
- 							      localBuffer);
- 
--#ifdef CONFIG_YAFFS_WINCE
--				yfsd_UnlockYAFFS(TRUE);
--#endif
-+
- 
- 				memcpy(&localBuffer[start], buffer, nToCopy);
- 
--#ifdef CONFIG_YAFFS_WINCE
--				yfsd_LockYAFFS(TRUE);
--#endif
- 				chunkWritten =
- 				    yaffs_WriteChunkDataToObject(in, chunk,
- 								 localBuffer,
-@@ -4846,31 +4889,15 @@ int yaffs_WriteDataToFile(yaffs_Object *
- 			}
- 
- 		} else {
--
--#ifdef CONFIG_YAFFS_WINCE
--			/* Under WinCE can't do direct transfer. Need to use a local buffer.
--			 * This is because we otherwise screw up WinCE's memory mapper
--			 */
--			__u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__);
--#ifdef CONFIG_YAFFS_WINCE
--			yfsd_UnlockYAFFS(TRUE);
--#endif
--			memcpy(localBuffer, buffer, dev->nDataBytesPerChunk);
--#ifdef CONFIG_YAFFS_WINCE
--			yfsd_LockYAFFS(TRUE);
--#endif
--			chunkWritten =
--			    yaffs_WriteChunkDataToObject(in, chunk, localBuffer,
--							 dev->nDataBytesPerChunk,
--							 0);
--			yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__);
--#else
- 			/* A full chunk. Write directly from the supplied buffer. */
-+
-+
-+
- 			chunkWritten =
- 			    yaffs_WriteChunkDataToObject(in, chunk, buffer,
- 							 dev->nDataBytesPerChunk,
- 							 0);
--#endif
-+
- 			/* Since we've overwritten the cached data, we better invalidate it. */
- 			yaffs_InvalidateChunkCache(in, chunk);
- 		}
-@@ -4886,9 +4913,8 @@ int yaffs_WriteDataToFile(yaffs_Object *
- 
- 	/* Update file object */
- 
--	if ((startOfWrite + nDone) > in->variant.fileVariant.fileSize) {
-+	if ((startOfWrite + nDone) > in->variant.fileVariant.fileSize)
- 		in->variant.fileVariant.fileSize = (startOfWrite + nDone);
--	}
- 
- 	in->dirty = 1;
- 
-@@ -4898,7 +4924,7 @@ int yaffs_WriteDataToFile(yaffs_Object *
- 
- /* ---------------------- File resizing stuff ------------------ */
- 
--static void yaffs_PruneResizedChunks(yaffs_Object * in, int newSize)
-+static void yaffs_PruneResizedChunks(yaffs_Object *in, int newSize)
- {
- 
- 	yaffs_Device *dev = in->myDev;
-@@ -4939,11 +4965,11 @@ static void yaffs_PruneResizedChunks(yaf
- 
- }
- 
--int yaffs_ResizeFile(yaffs_Object * in, loff_t newSize)
-+int yaffs_ResizeFile(yaffs_Object *in, loff_t newSize)
- {
- 
- 	int oldFileSize = in->variant.fileVariant.fileSize;
--	int newSizeOfPartialChunk;
-+	__u32 newSizeOfPartialChunk;
- 	int newFullChunks;
- 
- 	yaffs_Device *dev = in->myDev;
-@@ -4955,13 +4981,11 @@ int yaffs_ResizeFile(yaffs_Object * in,
- 
- 	yaffs_CheckGarbageCollection(dev);
- 
--	if (in->variantType != YAFFS_OBJECT_TYPE_FILE) {
--		return yaffs_GetFileSize(in);
--	}
-+	if (in->variantType != YAFFS_OBJECT_TYPE_FILE)
-+		return YAFFS_FAIL;
- 
--	if (newSize == oldFileSize) {
--		return oldFileSize;
--	}
-+	if (newSize == oldFileSize)
-+		return YAFFS_OK;
- 
- 	if (newSize < oldFileSize) {
- 
-@@ -4994,21 +5018,20 @@ int yaffs_ResizeFile(yaffs_Object * in,
- 	}
- 
- 
--
- 	/* Write a new object header.
- 	 * show we've shrunk the file, if need be
- 	 * Do this only if the file is not in the deleted directories.
- 	 */
--	if (in->parent->objectId != YAFFS_OBJECTID_UNLINKED &&
--	    in->parent->objectId != YAFFS_OBJECTID_DELETED) {
-+	if (in->parent &&
-+	    in->parent->objectId != YAFFS_OBJECTID_UNLINKED &&
-+	    in->parent->objectId != YAFFS_OBJECTID_DELETED)
- 		yaffs_UpdateObjectHeader(in, NULL, 0,
- 					 (newSize < oldFileSize) ? 1 : 0, 0);
--	}
- 
--	return newSize;
-+	return YAFFS_OK;
- }
- 
--loff_t yaffs_GetFileSize(yaffs_Object * obj)
-+loff_t yaffs_GetFileSize(yaffs_Object *obj)
- {
- 	obj = yaffs_GetEquivalentObject(obj);
- 
-@@ -5024,7 +5047,7 @@ loff_t yaffs_GetFileSize(yaffs_Object *
- 
- 
- 
--int yaffs_FlushFile(yaffs_Object * in, int updateTime)
-+int yaffs_FlushFile(yaffs_Object *in, int updateTime)
- {
- 	int retVal;
- 	if (in->dirty) {
-@@ -5039,9 +5062,8 @@ int yaffs_FlushFile(yaffs_Object * in, i
- #endif
- 		}
- 
--		retVal =
--		    (yaffs_UpdateObjectHeader(in, NULL, 0, 0, 0) >=
--		     0) ? YAFFS_OK : YAFFS_FAIL;
-+		retVal = (yaffs_UpdateObjectHeader(in, NULL, 0, 0, 0) >=
-+			0) ? YAFFS_OK : YAFFS_FAIL;
- 	} else {
- 		retVal = YAFFS_OK;
- 	}
-@@ -5050,7 +5072,7 @@ int yaffs_FlushFile(yaffs_Object * in, i
- 
- }
- 
--static int yaffs_DoGenericObjectDeletion(yaffs_Object * in)
-+static int yaffs_DoGenericObjectDeletion(yaffs_Object *in)
- {
- 
- 	/* First off, invalidate the file's data in the cache, without flushing. */
-@@ -5058,13 +5080,13 @@ static int yaffs_DoGenericObjectDeletion
- 
- 	if (in->myDev->isYaffs2 && (in->parent != in->myDev->deletedDir)) {
- 		/* Move to the unlinked directory so we have a record that it was deleted. */
--		yaffs_ChangeObjectName(in, in->myDev->deletedDir,"deleted", 0, 0);
-+		yaffs_ChangeObjectName(in, in->myDev->deletedDir, _Y("deleted"), 0, 0);
- 
- 	}
- 
- 	yaffs_RemoveObjectFromDirectory(in);
--	yaffs_DeleteChunk(in->myDev, in->chunkId, 1, __LINE__);
--	in->chunkId = -1;
-+	yaffs_DeleteChunk(in->myDev, in->hdrChunk, 1, __LINE__);
-+	in->hdrChunk = 0;
- 
- 	yaffs_FreeObject(in);
- 	return YAFFS_OK;
-@@ -5075,62 +5097,63 @@ static int yaffs_DoGenericObjectDeletion
-  * and the inode associated with the file.
-  * It does not delete the links associated with the file.
-  */
--static int yaffs_UnlinkFile(yaffs_Object * in)
-+static int yaffs_UnlinkFileIfNeeded(yaffs_Object *in)
- {
- 
- 	int retVal;
- 	int immediateDeletion = 0;
- 
--	if (1) {
- #ifdef __KERNEL__
--		if (!in->myInode) {
--			immediateDeletion = 1;
--
--		}
-+	if (!in->myInode)
-+		immediateDeletion = 1;
- #else
--		if (in->inUse <= 0) {
--			immediateDeletion = 1;
--
--		}
-+	if (in->inUse <= 0)
-+		immediateDeletion = 1;
- #endif
--		if (immediateDeletion) {
--			retVal =
--			    yaffs_ChangeObjectName(in, in->myDev->deletedDir,
--						   "deleted", 0, 0);
--			T(YAFFS_TRACE_TRACING,
--			  (TSTR("yaffs: immediate deletion of file %d" TENDSTR),
--			   in->objectId));
--			in->deleted = 1;
--			in->myDev->nDeletedFiles++;
--			if (0 && in->myDev->isYaffs2) {
--				yaffs_ResizeFile(in, 0);
--			}
--			yaffs_SoftDeleteFile(in);
--		} else {
--			retVal =
--			    yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,
--						   "unlinked", 0, 0);
--		}
- 
-+	if (immediateDeletion) {
-+		retVal =
-+		    yaffs_ChangeObjectName(in, in->myDev->deletedDir,
-+					   _Y("deleted"), 0, 0);
-+		T(YAFFS_TRACE_TRACING,
-+		  (TSTR("yaffs: immediate deletion of file %d" TENDSTR),
-+		   in->objectId));
-+		in->deleted = 1;
-+		in->myDev->nDeletedFiles++;
-+		if (1 || in->myDev->isYaffs2)
-+			yaffs_ResizeFile(in, 0);
-+		yaffs_SoftDeleteFile(in);
-+	} else {
-+		retVal =
-+		    yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,
-+					   _Y("unlinked"), 0, 0);
- 	}
-+
-+
- 	return retVal;
- }
- 
--int yaffs_DeleteFile(yaffs_Object * in)
-+int yaffs_DeleteFile(yaffs_Object *in)
- {
- 	int retVal = YAFFS_OK;
-+	int deleted = in->deleted;
-+
-+	yaffs_ResizeFile(in, 0);
- 
- 	if (in->nDataChunks > 0) {
--		/* Use soft deletion if there is data in the file */
--		if (!in->unlinked) {
--			retVal = yaffs_UnlinkFile(in);
--		}
-+		/* Use soft deletion if there is data in the file.
-+		 * That won't be the case if it has been resized to zero.
-+		 */
-+		if (!in->unlinked)
-+			retVal = yaffs_UnlinkFileIfNeeded(in);
-+
- 		if (retVal == YAFFS_OK && in->unlinked && !in->deleted) {
- 			in->deleted = 1;
-+			deleted = 1;
- 			in->myDev->nDeletedFiles++;
- 			yaffs_SoftDeleteFile(in);
- 		}
--		return in->deleted ? YAFFS_OK : YAFFS_FAIL;
-+		return deleted ? YAFFS_OK : YAFFS_FAIL;
- 	} else {
- 		/* The file has no data chunks so we toss it immediately */
- 		yaffs_FreeTnode(in->myDev, in->variant.fileVariant.top);
-@@ -5141,62 +5164,75 @@ int yaffs_DeleteFile(yaffs_Object * in)
- 	}
- }
- 
--static int yaffs_DeleteDirectory(yaffs_Object * in)
-+static int yaffs_DeleteDirectory(yaffs_Object *in)
- {
- 	/* First check that the directory is empty. */
--	if (list_empty(&in->variant.directoryVariant.children)) {
-+	if (ylist_empty(&in->variant.directoryVariant.children))
- 		return yaffs_DoGenericObjectDeletion(in);
--	}
- 
- 	return YAFFS_FAIL;
- 
- }
- 
--static int yaffs_DeleteSymLink(yaffs_Object * in)
-+static int yaffs_DeleteSymLink(yaffs_Object *in)
- {
- 	YFREE(in->variant.symLinkVariant.alias);
- 
- 	return yaffs_DoGenericObjectDeletion(in);
- }
- 
--static int yaffs_DeleteHardLink(yaffs_Object * in)
-+static int yaffs_DeleteHardLink(yaffs_Object *in)
- {
- 	/* remove this hardlink from the list assocaited with the equivalent
- 	 * object
- 	 */
--	list_del(&in->hardLinks);
-+	ylist_del_init(&in->hardLinks);
- 	return yaffs_DoGenericObjectDeletion(in);
- }
- 
--static void yaffs_DestroyObject(yaffs_Object * obj)
-+int yaffs_DeleteObject(yaffs_Object *obj)
- {
-+int retVal = -1;
- 	switch (obj->variantType) {
- 	case YAFFS_OBJECT_TYPE_FILE:
--		yaffs_DeleteFile(obj);
-+		retVal = yaffs_DeleteFile(obj);
- 		break;
- 	case YAFFS_OBJECT_TYPE_DIRECTORY:
--		yaffs_DeleteDirectory(obj);
-+		return yaffs_DeleteDirectory(obj);
- 		break;
- 	case YAFFS_OBJECT_TYPE_SYMLINK:
--		yaffs_DeleteSymLink(obj);
-+		retVal = yaffs_DeleteSymLink(obj);
- 		break;
- 	case YAFFS_OBJECT_TYPE_HARDLINK:
--		yaffs_DeleteHardLink(obj);
-+		retVal = yaffs_DeleteHardLink(obj);
- 		break;
- 	case YAFFS_OBJECT_TYPE_SPECIAL:
--		yaffs_DoGenericObjectDeletion(obj);
-+		retVal = yaffs_DoGenericObjectDeletion(obj);
- 		break;
- 	case YAFFS_OBJECT_TYPE_UNKNOWN:
-+		retVal = 0;
- 		break;		/* should not happen. */
- 	}
-+
-+	return retVal;
- }
- 
--static int yaffs_UnlinkWorker(yaffs_Object * obj)
-+static int yaffs_UnlinkWorker(yaffs_Object *obj)
- {
- 
-+	int immediateDeletion = 0;
-+
-+#ifdef __KERNEL__
-+	if (!obj->myInode)
-+		immediateDeletion = 1;
-+#else
-+	if (obj->inUse <= 0)
-+		immediateDeletion = 1;
-+#endif
-+
- 	if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
- 		return yaffs_DeleteHardLink(obj);
--	} else if (!list_empty(&obj->hardLinks)) {
-+	} else if (!ylist_empty(&obj->hardLinks)) {
- 		/* Curve ball: We're unlinking an object that has a hardlink.
- 		 *
- 		 * This problem arises because we are not strictly following
-@@ -5215,24 +5251,24 @@ static int yaffs_UnlinkWorker(yaffs_Obje
- 		int retVal;
- 		YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
- 
--		hl = list_entry(obj->hardLinks.next, yaffs_Object, hardLinks);
-+		hl = ylist_entry(obj->hardLinks.next, yaffs_Object, hardLinks);
- 
--		list_del_init(&hl->hardLinks);
--		list_del_init(&hl->siblings);
-+		ylist_del_init(&hl->hardLinks);
-+		ylist_del_init(&hl->siblings);
- 
- 		yaffs_GetObjectName(hl, name, YAFFS_MAX_NAME_LENGTH + 1);
- 
- 		retVal = yaffs_ChangeObjectName(obj, hl->parent, name, 0, 0);
- 
--		if (retVal == YAFFS_OK) {
-+		if (retVal == YAFFS_OK)
- 			retVal = yaffs_DoGenericObjectDeletion(hl);
--		}
-+
- 		return retVal;
- 
--	} else {
-+	} else if (immediateDeletion) {
- 		switch (obj->variantType) {
- 		case YAFFS_OBJECT_TYPE_FILE:
--			return yaffs_UnlinkFile(obj);
-+			return yaffs_DeleteFile(obj);
- 			break;
- 		case YAFFS_OBJECT_TYPE_DIRECTORY:
- 			return yaffs_DeleteDirectory(obj);
-@@ -5248,21 +5284,22 @@ static int yaffs_UnlinkWorker(yaffs_Obje
- 		default:
- 			return YAFFS_FAIL;
- 		}
--	}
-+	} else
-+		return yaffs_ChangeObjectName(obj, obj->myDev->unlinkedDir,
-+					   _Y("unlinked"), 0, 0);
- }
- 
- 
--static int yaffs_UnlinkObject( yaffs_Object *obj)
-+static int yaffs_UnlinkObject(yaffs_Object *obj)
- {
- 
--	if (obj && obj->unlinkAllowed) {
-+	if (obj && obj->unlinkAllowed)
- 		return yaffs_UnlinkWorker(obj);
--	}
- 
- 	return YAFFS_FAIL;
- 
- }
--int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name)
-+int yaffs_Unlink(yaffs_Object *dir, const YCHAR *name)
- {
- 	yaffs_Object *obj;
- 
-@@ -5272,8 +5309,8 @@ int yaffs_Unlink(yaffs_Object * dir, con
- 
- /*----------------------- Initialisation Scanning ---------------------- */
- 
--static void yaffs_HandleShadowedObject(yaffs_Device * dev, int objId,
--				       int backwardScanning)
-+static void yaffs_HandleShadowedObject(yaffs_Device *dev, int objId,
-+				int backwardScanning)
- {
- 	yaffs_Object *obj;
- 
-@@ -5286,9 +5323,8 @@ static void yaffs_HandleShadowedObject(y
- 		/* Handle YAFFS2 case (backward scanning)
- 		 * If the shadowed object exists then ignore.
- 		 */
--		if (yaffs_FindObjectByNumber(dev, objId)) {
-+		if (yaffs_FindObjectByNumber(dev, objId))
- 			return;
--		}
- 	}
- 
- 	/* Let's create it (if it does not exist) assuming it is a file so that it can do shrinking etc.
-@@ -5297,6 +5333,8 @@ static void yaffs_HandleShadowedObject(y
- 	obj =
- 	    yaffs_FindOrCreateObjectByNumber(dev, objId,
- 					     YAFFS_OBJECT_TYPE_FILE);
-+	if (!obj)
-+		return;
- 	yaffs_AddObjectToDirectory(dev->unlinkedDir, obj);
- 	obj->variant.fileVariant.shrinkSize = 0;
- 	obj->valid = 1;		/* So that we don't read any other info for this file */
-@@ -5325,44 +5363,77 @@ static void yaffs_HardlinkFixup(yaffs_De
- 		if (in) {
- 			/* Add the hardlink pointers */
- 			hl->variant.hardLinkVariant.equivalentObject = in;
--			list_add(&hl->hardLinks, &in->hardLinks);
-+			ylist_add(&hl->hardLinks, &in->hardLinks);
- 		} else {
- 			/* Todo Need to report/handle this better.
- 			 * Got a problem... hardlink to a non-existant object
- 			 */
- 			hl->variant.hardLinkVariant.equivalentObject = NULL;
--			INIT_LIST_HEAD(&hl->hardLinks);
-+			YINIT_LIST_HEAD(&hl->hardLinks);
- 
- 		}
--
- 	}
-+}
-+
-+
- 
-+
-+
-+static int ybicmp(const void *a, const void *b)
-+{
-+	register int aseq = ((yaffs_BlockIndex *)a)->seq;
-+	register int bseq = ((yaffs_BlockIndex *)b)->seq;
-+	register int ablock = ((yaffs_BlockIndex *)a)->block;
-+	register int bblock = ((yaffs_BlockIndex *)b)->block;
-+	if (aseq == bseq)
-+		return ablock - bblock;
-+	else
-+		return aseq - bseq;
- }
- 
- 
-+struct yaffs_ShadowFixerStruct {
-+	int objectId;
-+	int shadowedId;
-+	struct yaffs_ShadowFixerStruct *next;
-+};
-+
- 
-+static void yaffs_StripDeletedObjects(yaffs_Device *dev)
-+{
-+	/*
-+	*  Sort out state of unlinked and deleted objects after scanning.
-+	*/
-+	struct ylist_head *i;
-+	struct ylist_head *n;
-+	yaffs_Object *l;
- 
-+	/* Soft delete all the unlinked files */
-+	ylist_for_each_safe(i, n,
-+		&dev->unlinkedDir->variant.directoryVariant.children) {
-+		if (i) {
-+			l = ylist_entry(i, yaffs_Object, siblings);
-+			yaffs_DeleteObject(l);
-+		}
-+	}
- 
--static int ybicmp(const void *a, const void *b){
--    register int aseq = ((yaffs_BlockIndex *)a)->seq;
--    register int bseq = ((yaffs_BlockIndex *)b)->seq;
--    register int ablock = ((yaffs_BlockIndex *)a)->block;
--    register int bblock = ((yaffs_BlockIndex *)b)->block;
--    if( aseq == bseq )
--        return ablock - bblock;
--    else
--        return aseq - bseq;
-+	ylist_for_each_safe(i, n,
-+		&dev->deletedDir->variant.directoryVariant.children) {
-+		if (i) {
-+			l = ylist_entry(i, yaffs_Object, siblings);
-+			yaffs_DeleteObject(l);
-+		}
-+	}
- 
- }
- 
--static int yaffs_Scan(yaffs_Device * dev)
-+static int yaffs_Scan(yaffs_Device *dev)
- {
- 	yaffs_ExtendedTags tags;
- 	int blk;
- 	int blockIterator;
- 	int startIterator;
- 	int endIterator;
--	int nBlocksToScan = 0;
- 	int result;
- 
- 	int chunk;
-@@ -5371,26 +5442,19 @@ static int yaffs_Scan(yaffs_Device * dev
- 	yaffs_BlockState state;
- 	yaffs_Object *hardList = NULL;
- 	yaffs_BlockInfo *bi;
--	int sequenceNumber;
-+	__u32 sequenceNumber;
- 	yaffs_ObjectHeader *oh;
- 	yaffs_Object *in;
- 	yaffs_Object *parent;
--	int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
- 
- 	int alloc_failed = 0;
- 
-+	struct yaffs_ShadowFixerStruct *shadowFixerList = NULL;
-+
- 
- 	__u8 *chunkData;
- 
--	yaffs_BlockIndex *blockIndex = NULL;
- 
--	if (dev->isYaffs2) {
--		T(YAFFS_TRACE_SCAN,
--		  (TSTR("yaffs_Scan is not for YAFFS2!" TENDSTR)));
--		return YAFFS_FAIL;
--	}
--
--	//TODO  Throw all the yaffs2 stuuf out of yaffs_Scan since it is only for yaffs1 format.
- 
- 	T(YAFFS_TRACE_SCAN,
- 	  (TSTR("yaffs_Scan starts  intstartblk %d intendblk %d..." TENDSTR),
-@@ -5400,12 +5464,6 @@ static int yaffs_Scan(yaffs_Device * dev
- 
- 	dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
- 
--	if (dev->isYaffs2) {
--		blockIndex = YMALLOC(nBlocks * sizeof(yaffs_BlockIndex));
--		if(!blockIndex)
--			return YAFFS_FAIL;
--	}
--
- 	/* Scan all the blocks to determine their state */
- 	for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
- 		bi = yaffs_GetBlockInfo(dev, blk);
-@@ -5418,6 +5476,9 @@ static int yaffs_Scan(yaffs_Device * dev
- 		bi->blockState = state;
- 		bi->sequenceNumber = sequenceNumber;
- 
-+		if (bi->sequenceNumber == YAFFS_SEQUENCE_BAD_BLOCK)
-+			bi->blockState = state = YAFFS_BLOCK_STATE_DEAD;
-+
- 		T(YAFFS_TRACE_SCAN_DEBUG,
- 		  (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
- 		   state, sequenceNumber));
-@@ -5430,70 +5491,21 @@ static int yaffs_Scan(yaffs_Device * dev
- 			  (TSTR("Block empty " TENDSTR)));
- 			dev->nErasedBlocks++;
- 			dev->nFreeChunks += dev->nChunksPerBlock;
--		} else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
--
--			/* Determine the highest sequence number */
--			if (dev->isYaffs2 &&
--			    sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
--			    sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
--
--				blockIndex[nBlocksToScan].seq = sequenceNumber;
--				blockIndex[nBlocksToScan].block = blk;
--
--				nBlocksToScan++;
--
--				if (sequenceNumber >= dev->sequenceNumber) {
--					dev->sequenceNumber = sequenceNumber;
--				}
--			} else if (dev->isYaffs2) {
--				/* TODO: Nasty sequence number! */
--				T(YAFFS_TRACE_SCAN,
--				  (TSTR
--				   ("Block scanning block %d has bad sequence number %d"
--				    TENDSTR), blk, sequenceNumber));
--
--			}
- 		}
- 	}
- 
--	/* Sort the blocks
--	 * Dungy old bubble sort for now...
--	 */
--	if (dev->isYaffs2) {
--		yaffs_BlockIndex temp;
--		int i;
--		int j;
--
--		for (i = 0; i < nBlocksToScan; i++)
--			for (j = i + 1; j < nBlocksToScan; j++)
--				if (blockIndex[i].seq > blockIndex[j].seq) {
--					temp = blockIndex[j];
--					blockIndex[j] = blockIndex[i];
--					blockIndex[i] = temp;
--				}
--	}
--
--	/* Now scan the blocks looking at the data. */
--	if (dev->isYaffs2) {
--		startIterator = 0;
--		endIterator = nBlocksToScan - 1;
--		T(YAFFS_TRACE_SCAN_DEBUG,
--		  (TSTR("%d blocks to be scanned" TENDSTR), nBlocksToScan));
--	} else {
--		startIterator = dev->internalStartBlock;
--		endIterator = dev->internalEndBlock;
--	}
-+	startIterator = dev->internalStartBlock;
-+	endIterator = dev->internalEndBlock;
- 
- 	/* For each block.... */
- 	for (blockIterator = startIterator; !alloc_failed && blockIterator <= endIterator;
- 	     blockIterator++) {
- 
--		if (dev->isYaffs2) {
--			/* get the block to scan in the correct order */
--			blk = blockIndex[blockIterator].block;
--		} else {
--			blk = blockIterator;
--		}
-+		YYIELD();
-+
-+		YYIELD();
-+
-+		blk = blockIterator;
- 
- 		bi = yaffs_GetBlockInfo(dev, blk);
- 		state = bi->blockState;
-@@ -5511,7 +5523,7 @@ static int yaffs_Scan(yaffs_Device * dev
- 
- 			/* Let's have a good look at this chunk... */
- 
--			if (!dev->isYaffs2 && tags.chunkDeleted) {
-+			if (tags.eccResult == YAFFS_ECC_RESULT_UNFIXED || tags.chunkDeleted) {
- 				/* YAFFS1 only...
- 				 * A deleted chunk
- 				 */
-@@ -5540,18 +5552,6 @@ static int yaffs_Scan(yaffs_Device * dev
- 					dev->allocationBlockFinder = blk;
- 					/* Set it to here to encourage the allocator to go forth from here. */
- 
--					/* Yaffs2 sanity check:
--					 * This should be the one with the highest sequence number
--					 */
--					if (dev->isYaffs2
--					    && (dev->sequenceNumber !=
--						bi->sequenceNumber)) {
--						T(YAFFS_TRACE_ALWAYS,
--						  (TSTR
--						   ("yaffs: Allocation block %d was not highest sequence id:"
--						    " block seq = %d, dev seq = %d"
--						    TENDSTR), blk,bi->sequenceNumber,dev->sequenceNumber));
--					}
- 				}
- 
- 				dev->nFreeChunks += (dev->nChunksPerBlock - c);
-@@ -5570,11 +5570,11 @@ static int yaffs_Scan(yaffs_Device * dev
- 				 * the same chunkId).
- 				 */
- 
--				if(!in)
-+				if (!in)
- 					alloc_failed = 1;
- 
--				if(in){
--					if(!yaffs_PutChunkIntoFile(in, tags.chunkId, chunk,1))
-+				if (in) {
-+					if (!yaffs_PutChunkIntoFile(in, tags.chunkId, chunk, 1))
- 						alloc_failed = 1;
- 				}
- 
-@@ -5617,7 +5617,7 @@ static int yaffs_Scan(yaffs_Device * dev
- 					 * deleted, and worse still it has changed type. Delete the old object.
- 					 */
- 
--					yaffs_DestroyObject(in);
-+					yaffs_DeleteObject(in);
- 
- 					in = 0;
- 				}
-@@ -5627,14 +5627,20 @@ static int yaffs_Scan(yaffs_Device * dev
- 								      objectId,
- 								      oh->type);
- 
--				if(!in)
-+				if (!in)
- 					alloc_failed = 1;
- 
- 				if (in && oh->shadowsObject > 0) {
--					yaffs_HandleShadowedObject(dev,
--								   oh->
--								   shadowsObject,
--								   0);
-+
-+					struct yaffs_ShadowFixerStruct *fixer;
-+					fixer = YMALLOC(sizeof(struct yaffs_ShadowFixerStruct));
-+					if (fixer) {
-+						fixer->next = shadowFixerList;
-+						shadowFixerList = fixer;
-+						fixer->objectId = tags.objectId;
-+						fixer->shadowedId = oh->shadowsObject;
-+					}
-+
- 				}
- 
- 				if (in && in->valid) {
-@@ -5643,12 +5649,10 @@ static int yaffs_Scan(yaffs_Device * dev
- 					unsigned existingSerial = in->serial;
- 					unsigned newSerial = tags.serialNumber;
- 
--					if (dev->isYaffs2 ||
--					    ((existingSerial + 1) & 3) ==
--					    newSerial) {
-+					if (((existingSerial + 1) & 3) == newSerial) {
- 						/* Use new one - destroy the exisiting one */
- 						yaffs_DeleteChunk(dev,
--								  in->chunkId,
-+								  in->hdrChunk,
- 								  1, __LINE__);
- 						in->valid = 0;
- 					} else {
-@@ -5681,7 +5685,8 @@ static int yaffs_Scan(yaffs_Device * dev
- 					in->yst_ctime = oh->yst_ctime;
- 					in->yst_rdev = oh->yst_rdev;
- #endif
--					in->chunkId = chunk;
-+					in->hdrChunk = chunk;
-+					in->serial = tags.serialNumber;
- 
- 				} else if (in && !in->valid) {
- 					/* we need to load this info */
-@@ -5705,7 +5710,8 @@ static int yaffs_Scan(yaffs_Device * dev
- 					in->yst_ctime = oh->yst_ctime;
- 					in->yst_rdev = oh->yst_rdev;
- #endif
--					in->chunkId = chunk;
-+					in->hdrChunk = chunk;
-+					in->serial = tags.serialNumber;
- 
- 					yaffs_SetObjectName(in, oh->name);
- 					in->dirty = 0;
-@@ -5718,25 +5724,25 @@ static int yaffs_Scan(yaffs_Device * dev
- 					    yaffs_FindOrCreateObjectByNumber
- 					    (dev, oh->parentObjectId,
- 					     YAFFS_OBJECT_TYPE_DIRECTORY);
--					if (parent->variantType ==
-+					if (!parent)
-+						alloc_failed = 1;
-+					if (parent && parent->variantType ==
- 					    YAFFS_OBJECT_TYPE_UNKNOWN) {
- 						/* Set up as a directory */
- 						parent->variantType =
--						    YAFFS_OBJECT_TYPE_DIRECTORY;
--						INIT_LIST_HEAD(&parent->variant.
--							       directoryVariant.
--							       children);
--					} else if (parent->variantType !=
--						   YAFFS_OBJECT_TYPE_DIRECTORY)
--					{
-+							YAFFS_OBJECT_TYPE_DIRECTORY;
-+						YINIT_LIST_HEAD(&parent->variant.
-+								directoryVariant.
-+								children);
-+					} else if (!parent || parent->variantType !=
-+						   YAFFS_OBJECT_TYPE_DIRECTORY) {
- 						/* Hoosterman, another problem....
- 						 * We're trying to use a non-directory as a directory
- 						 */
- 
- 						T(YAFFS_TRACE_ERROR,
- 						  (TSTR
--						   ("yaffs tragedy: attempting to use non-directory as"
--						    " a directory in scan. Put in lost+found."
-+						   ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
- 						    TENDSTR)));
- 						parent = dev->lostNFoundDir;
- 					}
-@@ -5760,15 +5766,6 @@ static int yaffs_Scan(yaffs_Device * dev
- 						/* Todo got a problem */
- 						break;
- 					case YAFFS_OBJECT_TYPE_FILE:
--						if (dev->isYaffs2
--						    && oh->isShrink) {
--							/* Prune back the shrunken chunks */
--							yaffs_PruneResizedChunks
--							    (in, oh->fileSize);
--							/* Mark the block as having a shrinkHeader */
--							bi->hasShrinkHeader = 1;
--						}
--
- 						if (dev->useHeaderFileSize)
- 
- 							in->variant.fileVariant.
-@@ -5778,11 +5775,11 @@ static int yaffs_Scan(yaffs_Device * dev
- 						break;
- 					case YAFFS_OBJECT_TYPE_HARDLINK:
- 						in->variant.hardLinkVariant.
--						    equivalentObjectId =
--						    oh->equivalentObjectId;
-+							equivalentObjectId =
-+							oh->equivalentObjectId;
- 						in->hardLinks.next =
--						    (struct list_head *)
--						    hardList;
-+							(struct ylist_head *)
-+							hardList;
- 						hardList = in;
- 						break;
- 					case YAFFS_OBJECT_TYPE_DIRECTORY:
-@@ -5794,15 +5791,17 @@ static int yaffs_Scan(yaffs_Device * dev
- 					case YAFFS_OBJECT_TYPE_SYMLINK:
- 						in->variant.symLinkVariant.alias =
- 						    yaffs_CloneString(oh->alias);
--						if(!in->variant.symLinkVariant.alias)
-+						if (!in->variant.symLinkVariant.alias)
- 							alloc_failed = 1;
- 						break;
- 					}
- 
-+/*
- 					if (parent == dev->deletedDir) {
- 						yaffs_DestroyObject(in);
- 						bi->hasShrinkHeader = 1;
- 					}
-+*/
- 				}
- 			}
- 		}
-@@ -5823,10 +5822,6 @@ static int yaffs_Scan(yaffs_Device * dev
- 
- 	}
- 
--	if (blockIndex) {
--		YFREE(blockIndex);
--	}
--
- 
- 	/* Ok, we've done all the scanning.
- 	 * Fix up the hard link chains.
-@@ -5834,32 +5829,36 @@ static int yaffs_Scan(yaffs_Device * dev
- 	 * hardlinks.
- 	 */
- 
--	yaffs_HardlinkFixup(dev,hardList);
-+	yaffs_HardlinkFixup(dev, hardList);
- 
--	/* Handle the unlinked files. Since they were left in an unlinked state we should
--	 * just delete them.
--	 */
-+	/* Fix up any shadowed objects */
- 	{
--		struct list_head *i;
--		struct list_head *n;
-+		struct yaffs_ShadowFixerStruct *fixer;
-+		yaffs_Object *obj;
- 
--		yaffs_Object *l;
--		/* Soft delete all the unlinked files */
--		list_for_each_safe(i, n,
--				   &dev->unlinkedDir->variant.directoryVariant.
--				   children) {
--			if (i) {
--				l = list_entry(i, yaffs_Object, siblings);
--				yaffs_DestroyObject(l);
--			}
-+		while (shadowFixerList) {
-+			fixer = shadowFixerList;
-+			shadowFixerList = fixer->next;
-+			/* Complete the rename transaction by deleting the shadowed object
-+			 * then setting the object header to unshadowed.
-+			 */
-+			obj = yaffs_FindObjectByNumber(dev, fixer->shadowedId);
-+			if (obj)
-+				yaffs_DeleteObject(obj);
-+
-+			obj = yaffs_FindObjectByNumber(dev, fixer->objectId);
-+
-+			if (obj)
-+				yaffs_UpdateObjectHeader(obj, NULL, 1, 0, 0);
-+
-+			YFREE(fixer);
- 		}
- 	}
- 
- 	yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
- 
--	if(alloc_failed){
-+	if (alloc_failed)
- 		return YAFFS_FAIL;
--	}
- 
- 	T(YAFFS_TRACE_SCAN, (TSTR("yaffs_Scan ends" TENDSTR)));
- 
-@@ -5871,25 +5870,27 @@ static void yaffs_CheckObjectDetailsLoad
- {
- 	__u8 *chunkData;
- 	yaffs_ObjectHeader *oh;
--	yaffs_Device *dev = in->myDev;
-+	yaffs_Device *dev;
- 	yaffs_ExtendedTags tags;
- 	int result;
- 	int alloc_failed = 0;
- 
--	if(!in)
-+	if (!in)
- 		return;
- 
-+	dev = in->myDev;
-+
- #if 0
--	T(YAFFS_TRACE_SCAN,(TSTR("details for object %d %s loaded" TENDSTR),
-+	T(YAFFS_TRACE_SCAN, (TSTR("details for object %d %s loaded" TENDSTR),
- 		in->objectId,
- 		in->lazyLoaded ? "not yet" : "already"));
- #endif
- 
--	if(in->lazyLoaded){
-+	if (in->lazyLoaded && in->hdrChunk > 0) {
- 		in->lazyLoaded = 0;
- 		chunkData = yaffs_GetTempBuffer(dev, __LINE__);
- 
--		result = yaffs_ReadChunkWithTagsFromNAND(dev,in->chunkId,chunkData,&tags);
-+		result = yaffs_ReadChunkWithTagsFromNAND(dev, in->hdrChunk, chunkData, &tags);
- 		oh = (yaffs_ObjectHeader *) chunkData;
- 
- 		in->yst_mode = oh->yst_mode;
-@@ -5911,18 +5912,18 @@ static void yaffs_CheckObjectDetailsLoad
- #endif
- 		yaffs_SetObjectName(in, oh->name);
- 
--		if(in->variantType == YAFFS_OBJECT_TYPE_SYMLINK){
--			 in->variant.symLinkVariant.alias =
-+		if (in->variantType == YAFFS_OBJECT_TYPE_SYMLINK) {
-+			in->variant.symLinkVariant.alias =
- 						    yaffs_CloneString(oh->alias);
--			if(!in->variant.symLinkVariant.alias)
-+			if (!in->variant.symLinkVariant.alias)
- 				alloc_failed = 1; /* Not returned to caller */
- 		}
- 
--		yaffs_ReleaseTempBuffer(dev,chunkData, __LINE__);
-+		yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
- 	}
- }
- 
--static int yaffs_ScanBackwards(yaffs_Device * dev)
-+static int yaffs_ScanBackwards(yaffs_Device *dev)
- {
- 	yaffs_ExtendedTags tags;
- 	int blk;
-@@ -5938,7 +5939,7 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 	yaffs_BlockState state;
- 	yaffs_Object *hardList = NULL;
- 	yaffs_BlockInfo *bi;
--	int sequenceNumber;
-+	__u32 sequenceNumber;
- 	yaffs_ObjectHeader *oh;
- 	yaffs_Object *in;
- 	yaffs_Object *parent;
-@@ -5972,12 +5973,12 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 	blockIndex = YMALLOC(nBlocks * sizeof(yaffs_BlockIndex));
- 
--	if(!blockIndex) {
-+	if (!blockIndex) {
- 		blockIndex = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockIndex));
- 		altBlockIndex = 1;
- 	}
- 
--	if(!blockIndex) {
-+	if (!blockIndex) {
- 		T(YAFFS_TRACE_SCAN,
- 		  (TSTR("yaffs_Scan() could not allocate block index!" TENDSTR)));
- 		return YAFFS_FAIL;
-@@ -5999,15 +6000,17 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 		bi->blockState = state;
- 		bi->sequenceNumber = sequenceNumber;
- 
--		if(bi->sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA)
-+		if (bi->sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA)
- 			bi->blockState = state = YAFFS_BLOCK_STATE_CHECKPOINT;
-+		if (bi->sequenceNumber == YAFFS_SEQUENCE_BAD_BLOCK)
-+			bi->blockState = state = YAFFS_BLOCK_STATE_DEAD;
- 
- 		T(YAFFS_TRACE_SCAN_DEBUG,
- 		  (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
- 		   state, sequenceNumber));
- 
- 
--		if(state == YAFFS_BLOCK_STATE_CHECKPOINT){
-+		if (state == YAFFS_BLOCK_STATE_CHECKPOINT) {
- 			dev->blocksInCheckpoint++;
- 
- 		} else if (state == YAFFS_BLOCK_STATE_DEAD) {
-@@ -6021,8 +6024,7 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 		} else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
- 
- 			/* Determine the highest sequence number */
--			if (dev->isYaffs2 &&
--			    sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
-+			if (sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
- 			    sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
- 
- 				blockIndex[nBlocksToScan].seq = sequenceNumber;
-@@ -6030,10 +6032,9 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 				nBlocksToScan++;
- 
--				if (sequenceNumber >= dev->sequenceNumber) {
-+				if (sequenceNumber >= dev->sequenceNumber)
- 					dev->sequenceNumber = sequenceNumber;
--				}
--			} else if (dev->isYaffs2) {
-+			} else {
- 				/* TODO: Nasty sequence number! */
- 				T(YAFFS_TRACE_SCAN,
- 				  (TSTR
-@@ -6053,11 +6054,13 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 	/* Sort the blocks */
- #ifndef CONFIG_YAFFS_USE_OWN_SORT
--	yaffs_qsort(blockIndex, nBlocksToScan,
--		sizeof(yaffs_BlockIndex), ybicmp);
-+	{
-+		/* Use qsort now. */
-+		yaffs_qsort(blockIndex, nBlocksToScan, sizeof(yaffs_BlockIndex), ybicmp);
-+	}
- #else
- 	{
--	 	/* Dungy old bubble sort... */
-+		/* Dungy old bubble sort... */
- 
- 		yaffs_BlockIndex temp;
- 		int i;
-@@ -6075,7 +6078,7 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 	YYIELD();
- 
--    	T(YAFFS_TRACE_SCAN, (TSTR("...done" TENDSTR)));
-+	T(YAFFS_TRACE_SCAN, (TSTR("...done" TENDSTR)));
- 
- 	/* Now scan the blocks looking at the data. */
- 	startIterator = 0;
-@@ -6085,10 +6088,10 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 	/* For each block.... backwards */
- 	for (blockIterator = endIterator; !alloc_failed && blockIterator >= startIterator;
--	     blockIterator--) {
--	        /* Cooperative multitasking! This loop can run for so
-+			blockIterator--) {
-+		/* Cooperative multitasking! This loop can run for so
- 		   long that watchdog timers expire. */
--	        YYIELD();
-+		YYIELD();
- 
- 		/* get the block to scan in the correct order */
- 		blk = blockIndex[blockIterator].block;
-@@ -6127,10 +6130,8 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 				 * this is the one being allocated from
- 				 */
- 
--				if(foundChunksInBlock)
--				{
-+				if (foundChunksInBlock) {
- 					/* This is a chunk that was skipped due to failing the erased check */
--
- 				} else if (c == 0) {
- 					/* We're looking at the first chunk in the block so the block is unused */
- 					state = YAFFS_BLOCK_STATE_EMPTY;
-@@ -6138,7 +6139,7 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 				} else {
- 					if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
- 					    state == YAFFS_BLOCK_STATE_ALLOCATING) {
--					    	if(dev->sequenceNumber == bi->sequenceNumber) {
-+						if (dev->sequenceNumber == bi->sequenceNumber) {
- 							/* this is the block being allocated from */
- 
- 							T(YAFFS_TRACE_SCAN,
-@@ -6150,27 +6151,31 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 							dev->allocationBlock = blk;
- 							dev->allocationPage = c;
- 							dev->allocationBlockFinder = blk;
--						}
--						else {
-+						} else {
- 							/* This is a partially written block that is not
- 							 * the current allocation block. This block must have
- 							 * had a write failure, so set up for retirement.
- 							 */
- 
--							 bi->needsRetiring = 1;
-+							 /* bi->needsRetiring = 1; ??? TODO */
- 							 bi->gcPrioritise = 1;
- 
- 							 T(YAFFS_TRACE_ALWAYS,
--							 (TSTR("Partially written block %d being set for retirement" TENDSTR),
-+							 (TSTR("Partially written block %d detected" TENDSTR),
- 							 blk));
- 						}
--
- 					}
--
- 				}
- 
- 				dev->nFreeChunks++;
- 
-+			} else if (tags.eccResult == YAFFS_ECC_RESULT_UNFIXED) {
-+				T(YAFFS_TRACE_SCAN,
-+				  (TSTR(" Unfixed ECC in chunk(%d:%d), chunk ignored"TENDSTR),
-+				  blk, c));
-+
-+				  dev->nFreeChunks++;
-+
- 			} else if (tags.chunkId > 0) {
- 				/* chunkId > 0 so it is a data chunk... */
- 				unsigned int endpos;
-@@ -6187,7 +6192,7 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 								      tags.
- 								      objectId,
- 								      YAFFS_OBJECT_TYPE_FILE);
--				if(!in){
-+				if (!in) {
- 					/* Out of memory */
- 					alloc_failed = 1;
- 				}
-@@ -6197,8 +6202,8 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 				    && chunkBase <
- 				    in->variant.fileVariant.shrinkSize) {
- 					/* This has not been invalidated by a resize */
--					if(!yaffs_PutChunkIntoFile(in, tags.chunkId,
--							       chunk, -1)){
-+					if (!yaffs_PutChunkIntoFile(in, tags.chunkId,
-+							       chunk, -1)) {
- 						alloc_failed = 1;
- 					}
- 
-@@ -6221,7 +6226,7 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 						    scannedFileSize;
- 					}
- 
--				} else if(in) {
-+				} else if (in) {
- 					/* This chunk has been invalidated by a resize, so delete */
- 					yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
- 
-@@ -6242,6 +6247,8 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 					in = yaffs_FindOrCreateObjectByNumber
- 					    (dev, tags.objectId,
- 					     tags.extraObjectType);
-+					if (!in)
-+						alloc_failed = 1;
- 				}
- 
- 				if (!in ||
-@@ -6251,8 +6258,7 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 				    tags.extraShadows ||
- 				    (!in->valid &&
- 				    (tags.objectId == YAFFS_OBJECTID_ROOT ||
--				     tags.objectId == YAFFS_OBJECTID_LOSTNFOUND))
--				    ) {
-+				     tags.objectId == YAFFS_OBJECTID_LOSTNFOUND))) {
- 
- 					/* If we don't have  valid info then we need to read the chunk
- 					 * TODO In future we can probably defer reading the chunk and
-@@ -6266,8 +6272,17 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 					oh = (yaffs_ObjectHeader *) chunkData;
- 
--					if (!in)
-+					if (dev->inbandTags) {
-+						/* Fix up the header if they got corrupted by inband tags */
-+						oh->shadowsObject = oh->inbandShadowsObject;
-+						oh->isShrink = oh->inbandIsShrink;
-+					}
-+
-+					if (!in) {
- 						in = yaffs_FindOrCreateObjectByNumber(dev, tags.objectId, oh->type);
-+						if (!in)
-+							alloc_failed = 1;
-+					}
- 
- 				}
- 
-@@ -6275,10 +6290,9 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 					/* TODO Hoosterman we have a problem! */
- 					T(YAFFS_TRACE_ERROR,
- 					  (TSTR
--					   ("yaffs tragedy: Could not make object for object  %d  "
--					    "at chunk %d during scan"
-+					   ("yaffs tragedy: Could not make object for object  %d at chunk %d during scan"
- 					    TENDSTR), tags.objectId, chunk));
--
-+					continue;
- 				}
- 
- 				if (in->valid) {
-@@ -6289,10 +6303,9 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 					if ((in->variantType == YAFFS_OBJECT_TYPE_FILE) &&
- 					     ((oh &&
--					       oh-> type == YAFFS_OBJECT_TYPE_FILE)||
-+					       oh->type == YAFFS_OBJECT_TYPE_FILE) ||
- 					      (tags.extraHeaderInfoAvailable  &&
--					       tags.extraObjectType == YAFFS_OBJECT_TYPE_FILE))
--					    ) {
-+					       tags.extraObjectType == YAFFS_OBJECT_TYPE_FILE))) {
- 						__u32 thisSize =
- 						    (oh) ? oh->fileSize : tags.
- 						    extraFileLength;
-@@ -6300,7 +6313,9 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 						    (oh) ? oh->
- 						    parentObjectId : tags.
- 						    extraParentObjectId;
--						unsigned isShrink =
-+
-+
-+						isShrink =
- 						    (oh) ? oh->isShrink : tags.
- 						    extraIsShrinkHeader;
- 
-@@ -6323,9 +6338,8 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 							    thisSize;
- 						}
- 
--						if (isShrink) {
-+						if (isShrink)
- 							bi->hasShrinkHeader = 1;
--						}
- 
- 					}
- 					/* Use existing - destroy this one. */
-@@ -6333,6 +6347,17 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 				}
- 
-+				if (!in->valid && in->variantType !=
-+				    (oh ? oh->type : tags.extraObjectType))
-+					T(YAFFS_TRACE_ERROR, (
-+						TSTR("yaffs tragedy: Bad object type, "
-+					    TCONT("%d != %d, for object %d at chunk ")
-+					    TCONT("%d during scan")
-+						TENDSTR), oh ?
-+					    oh->type : tags.extraObjectType,
-+					    in->variantType, tags.objectId,
-+					    chunk));
-+
- 				if (!in->valid &&
- 				    (tags.objectId == YAFFS_OBJECTID_ROOT ||
- 				     tags.objectId ==
-@@ -6340,7 +6365,7 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 					/* We only load some info, don't fiddle with directory structure */
- 					in->valid = 1;
- 
--					if(oh) {
-+					if (oh) {
- 						in->variantType = oh->type;
- 
- 						in->yst_mode = oh->yst_mode;
-@@ -6365,15 +6390,15 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 						in->lazyLoaded = 1;
- 					}
- 
--					in->chunkId = chunk;
-+					in->hdrChunk = chunk;
- 
- 				} else if (!in->valid) {
- 					/* we need to load this info */
- 
- 					in->valid = 1;
--					in->chunkId = chunk;
-+					in->hdrChunk = chunk;
- 
--					if(oh) {
-+					if (oh) {
- 						in->variantType = oh->type;
- 
- 						in->yst_mode = oh->yst_mode;
-@@ -6403,20 +6428,19 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 						yaffs_SetObjectName(in, oh->name);
- 						parent =
- 						    yaffs_FindOrCreateObjectByNumber
--					    		(dev, oh->parentObjectId,
--					     		 YAFFS_OBJECT_TYPE_DIRECTORY);
-+							(dev, oh->parentObjectId,
-+							 YAFFS_OBJECT_TYPE_DIRECTORY);
- 
- 						 fileSize = oh->fileSize;
-- 						 isShrink = oh->isShrink;
-+						 isShrink = oh->isShrink;
- 						 equivalentObjectId = oh->equivalentObjectId;
- 
--					}
--					else {
-+					} else {
- 						in->variantType = tags.extraObjectType;
- 						parent =
- 						    yaffs_FindOrCreateObjectByNumber
--					    		(dev, tags.extraParentObjectId,
--					     		 YAFFS_OBJECT_TYPE_DIRECTORY);
-+							(dev, tags.extraParentObjectId,
-+							 YAFFS_OBJECT_TYPE_DIRECTORY);
- 						 fileSize = tags.extraFileLength;
- 						 isShrink = tags.extraIsShrinkHeader;
- 						 equivalentObjectId = tags.extraEquivalentObjectId;
-@@ -6425,29 +6449,30 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 					}
- 					in->dirty = 0;
- 
-+					if (!parent)
-+						alloc_failed = 1;
-+
- 					/* directory stuff...
- 					 * hook up to parent
- 					 */
- 
--					if (parent->variantType ==
-+					if (parent && parent->variantType ==
- 					    YAFFS_OBJECT_TYPE_UNKNOWN) {
- 						/* Set up as a directory */
- 						parent->variantType =
--						    YAFFS_OBJECT_TYPE_DIRECTORY;
--						INIT_LIST_HEAD(&parent->variant.
--							       directoryVariant.
--							       children);
--					} else if (parent->variantType !=
--						   YAFFS_OBJECT_TYPE_DIRECTORY)
--					{
-+							YAFFS_OBJECT_TYPE_DIRECTORY;
-+						YINIT_LIST_HEAD(&parent->variant.
-+							directoryVariant.
-+							children);
-+					} else if (!parent || parent->variantType !=
-+						   YAFFS_OBJECT_TYPE_DIRECTORY) {
- 						/* Hoosterman, another problem....
- 						 * We're trying to use a non-directory as a directory
- 						 */
- 
- 						T(YAFFS_TRACE_ERROR,
- 						  (TSTR
--						   ("yaffs tragedy: attempting to use non-directory as"
--						    " a directory in scan. Put in lost+found."
-+						   ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
- 						    TENDSTR)));
- 						parent = dev->lostNFoundDir;
- 					}
-@@ -6494,12 +6519,12 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 
- 						break;
- 					case YAFFS_OBJECT_TYPE_HARDLINK:
--						if(!itsUnlinked) {
--						  in->variant.hardLinkVariant.equivalentObjectId =
--						    equivalentObjectId;
--						  in->hardLinks.next =
--						    (struct list_head *) hardList;
--						  hardList = in;
-+						if (!itsUnlinked) {
-+							in->variant.hardLinkVariant.equivalentObjectId =
-+								equivalentObjectId;
-+							in->hardLinks.next =
-+								(struct ylist_head *) hardList;
-+							hardList = in;
- 						}
- 						break;
- 					case YAFFS_OBJECT_TYPE_DIRECTORY:
-@@ -6509,12 +6534,11 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 						/* Do nothing */
- 						break;
- 					case YAFFS_OBJECT_TYPE_SYMLINK:
--						if(oh){
--						   in->variant.symLinkVariant.alias =
--						    yaffs_CloneString(oh->
--								      alias);
--						   if(!in->variant.symLinkVariant.alias)
--						   	alloc_failed = 1;
-+						if (oh) {
-+							in->variant.symLinkVariant.alias =
-+								yaffs_CloneString(oh->alias);
-+							if (!in->variant.symLinkVariant.alias)
-+								alloc_failed = 1;
- 						}
- 						break;
- 					}
-@@ -6551,75 +6575,129 @@ static int yaffs_ScanBackwards(yaffs_Dev
- 	 * We should now have scanned all the objects, now it's time to add these
- 	 * hardlinks.
- 	 */
--	yaffs_HardlinkFixup(dev,hardList);
-+	yaffs_HardlinkFixup(dev, hardList);
- 
- 
--	/*
--	*  Sort out state of unlinked and deleted objects.
--	*/
--	{
--		struct list_head *i;
--		struct list_head *n;
-+	yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
- 
--		yaffs_Object *l;
-+	if (alloc_failed)
-+		return YAFFS_FAIL;
- 
--		/* Soft delete all the unlinked files */
--		list_for_each_safe(i, n,
--				   &dev->unlinkedDir->variant.directoryVariant.
--				   children) {
--			if (i) {
--				l = list_entry(i, yaffs_Object, siblings);
--				yaffs_DestroyObject(l);
--			}
--		}
-+	T(YAFFS_TRACE_SCAN, (TSTR("yaffs_ScanBackwards ends" TENDSTR)));
- 
--		/* Soft delete all the deletedDir files */
--		list_for_each_safe(i, n,
--				   &dev->deletedDir->variant.directoryVariant.
--				   children) {
--			if (i) {
--				l = list_entry(i, yaffs_Object, siblings);
--				yaffs_DestroyObject(l);
-+	return YAFFS_OK;
-+}
- 
--			}
-+/*------------------------------  Directory Functions ----------------------------- */
-+
-+static void yaffs_VerifyObjectInDirectory(yaffs_Object *obj)
-+{
-+	struct ylist_head *lh;
-+	yaffs_Object *listObj;
-+
-+	int count = 0;
-+
-+	if (!obj) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("No object to verify" TENDSTR)));
-+		YBUG();
-+		return;
-+	}
-+
-+	if (yaffs_SkipVerification(obj->myDev))
-+		return;
-+
-+	if (!obj->parent) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("Object does not have parent" TENDSTR)));
-+		YBUG();
-+		return;
-+	}
-+
-+	if (obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("Parent is not directory" TENDSTR)));
-+		YBUG();
-+	}
-+
-+	/* Iterate through the objects in each hash entry */
-+
-+	ylist_for_each(lh, &obj->parent->variant.directoryVariant.children) {
-+		if (lh) {
-+			listObj = ylist_entry(lh, yaffs_Object, siblings);
-+			yaffs_VerifyObject(listObj);
-+			if (obj == listObj)
-+				count++;
- 		}
-+	 }
-+
-+	if (count != 1) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("Object in directory %d times" TENDSTR), count));
-+		YBUG();
- 	}
-+}
- 
--	yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
-+static void yaffs_VerifyDirectory(yaffs_Object *directory)
-+{
-+	struct ylist_head *lh;
-+	yaffs_Object *listObj;
- 
--	if(alloc_failed){
--		return YAFFS_FAIL;
-+	if (!directory) {
-+		YBUG();
-+		return;
- 	}
- 
--	T(YAFFS_TRACE_SCAN, (TSTR("yaffs_ScanBackwards ends" TENDSTR)));
-+	if (yaffs_SkipFullVerification(directory->myDev))
-+		return;
- 
--	return YAFFS_OK;
-+	if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("Directory has wrong type: %d" TENDSTR), directory->variantType));
-+		YBUG();
-+	}
-+
-+	/* Iterate through the objects in each hash entry */
-+
-+	ylist_for_each(lh, &directory->variant.directoryVariant.children) {
-+		if (lh) {
-+			listObj = ylist_entry(lh, yaffs_Object, siblings);
-+			if (listObj->parent != directory) {
-+				T(YAFFS_TRACE_ALWAYS, (TSTR("Object in directory list has wrong parent %p" TENDSTR), listObj->parent));
-+				YBUG();
-+			}
-+			yaffs_VerifyObjectInDirectory(listObj);
-+		}
-+	}
- }
- 
--/*------------------------------  Directory Functions ----------------------------- */
- 
--static void yaffs_RemoveObjectFromDirectory(yaffs_Object * obj)
-+static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj)
- {
- 	yaffs_Device *dev = obj->myDev;
-+	yaffs_Object *parent;
-+
-+	yaffs_VerifyObjectInDirectory(obj);
-+	parent = obj->parent;
-+
-+	yaffs_VerifyDirectory(parent);
- 
--	if(dev && dev->removeObjectCallback)
-+	if (dev && dev->removeObjectCallback)
- 		dev->removeObjectCallback(obj);
- 
--	list_del_init(&obj->siblings);
-+
-+	ylist_del_init(&obj->siblings);
- 	obj->parent = NULL;
-+
-+	yaffs_VerifyDirectory(parent);
- }
- 
- 
--static void yaffs_AddObjectToDirectory(yaffs_Object * directory,
--				       yaffs_Object * obj)
-+static void yaffs_AddObjectToDirectory(yaffs_Object *directory,
-+					yaffs_Object *obj)
- {
--
- 	if (!directory) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
- 		   ("tragedy: Trying to add an object to a null pointer directory"
- 		    TENDSTR)));
- 		YBUG();
-+		return;
- 	}
- 	if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
- 		T(YAFFS_TRACE_ALWAYS,
-@@ -6631,37 +6709,42 @@ static void yaffs_AddObjectToDirectory(y
- 
- 	if (obj->siblings.prev == NULL) {
- 		/* Not initialised */
--		INIT_LIST_HEAD(&obj->siblings);
--
--	} else if (!list_empty(&obj->siblings)) {
--		/* If it is holed up somewhere else, un hook it */
--		yaffs_RemoveObjectFromDirectory(obj);
-+		YBUG();
- 	}
-+
-+
-+	yaffs_VerifyDirectory(directory);
-+
-+	yaffs_RemoveObjectFromDirectory(obj);
-+
-+
- 	/* Now add it */
--	list_add(&obj->siblings, &directory->variant.directoryVariant.children);
-+	ylist_add(&obj->siblings, &directory->variant.directoryVariant.children);
- 	obj->parent = directory;
- 
- 	if (directory == obj->myDev->unlinkedDir
--	    || directory == obj->myDev->deletedDir) {
-+			|| directory == obj->myDev->deletedDir) {
- 		obj->unlinked = 1;
- 		obj->myDev->nUnlinkedFiles++;
- 		obj->renameAllowed = 0;
- 	}
-+
-+	yaffs_VerifyDirectory(directory);
-+	yaffs_VerifyObjectInDirectory(obj);
- }
- 
--yaffs_Object *yaffs_FindObjectByName(yaffs_Object * directory,
--				     const YCHAR * name)
-+yaffs_Object *yaffs_FindObjectByName(yaffs_Object *directory,
-+				     const YCHAR *name)
- {
- 	int sum;
- 
--	struct list_head *i;
-+	struct ylist_head *i;
- 	YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1];
- 
- 	yaffs_Object *l;
- 
--	if (!name) {
-+	if (!name)
- 		return NULL;
--	}
- 
- 	if (!directory) {
- 		T(YAFFS_TRACE_ALWAYS,
-@@ -6669,6 +6752,7 @@ yaffs_Object *yaffs_FindObjectByName(yaf
- 		   ("tragedy: yaffs_FindObjectByName: null pointer directory"
- 		    TENDSTR)));
- 		YBUG();
-+		return NULL;
- 	}
- 	if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
- 		T(YAFFS_TRACE_ALWAYS,
-@@ -6679,28 +6763,27 @@ yaffs_Object *yaffs_FindObjectByName(yaf
- 
- 	sum = yaffs_CalcNameSum(name);
- 
--	list_for_each(i, &directory->variant.directoryVariant.children) {
-+	ylist_for_each(i, &directory->variant.directoryVariant.children) {
- 		if (i) {
--			l = list_entry(i, yaffs_Object, siblings);
-+			l = ylist_entry(i, yaffs_Object, siblings);
-+
-+			if (l->parent != directory)
-+				YBUG();
- 
- 			yaffs_CheckObjectDetailsLoaded(l);
- 
- 			/* Special case for lost-n-found */
- 			if (l->objectId == YAFFS_OBJECTID_LOSTNFOUND) {
--				if (yaffs_strcmp(name, YAFFS_LOSTNFOUND_NAME) == 0) {
-+				if (yaffs_strcmp(name, YAFFS_LOSTNFOUND_NAME) == 0)
- 					return l;
--				}
--			} else if (yaffs_SumCompare(l->sum, sum) || l->chunkId <= 0)
--			{
--				/* LostnFound cunk called Objxxx
-+			} else if (yaffs_SumCompare(l->sum, sum) || l->hdrChunk <= 0) {
-+				/* LostnFound chunk called Objxxx
- 				 * Do a real check
- 				 */
- 				yaffs_GetObjectName(l, buffer,
- 						    YAFFS_MAX_NAME_LENGTH);
--				if (yaffs_strncmp(name, buffer,YAFFS_MAX_NAME_LENGTH) == 0) {
-+				if (yaffs_strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH) == 0)
- 					return l;
--				}
--
- 			}
- 		}
- 	}
-@@ -6710,10 +6793,10 @@ yaffs_Object *yaffs_FindObjectByName(yaf
- 
- 
- #if 0
--int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir,
--				   int (*fn) (yaffs_Object *))
-+int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,
-+					int (*fn) (yaffs_Object *))
- {
--	struct list_head *i;
-+	struct ylist_head *i;
- 	yaffs_Object *l;
- 
- 	if (!theDir) {
-@@ -6722,20 +6805,21 @@ int yaffs_ApplyToDirectoryChildren(yaffs
- 		   ("tragedy: yaffs_FindObjectByName: null pointer directory"
- 		    TENDSTR)));
- 		YBUG();
-+		return YAFFS_FAIL;
- 	}
- 	if (theDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
- 		   ("tragedy: yaffs_FindObjectByName: non-directory" TENDSTR)));
- 		YBUG();
-+		return YAFFS_FAIL;
- 	}
- 
--	list_for_each(i, &theDir->variant.directoryVariant.children) {
-+	ylist_for_each(i, &theDir->variant.directoryVariant.children) {
- 		if (i) {
--			l = list_entry(i, yaffs_Object, siblings);
--			if (l && !fn(l)) {
-+			l = ylist_entry(i, yaffs_Object, siblings);
-+			if (l && !fn(l))
- 				return YAFFS_FAIL;
--			}
- 		}
- 	}
- 
-@@ -6748,7 +6832,7 @@ int yaffs_ApplyToDirectoryChildren(yaffs
-  * actual object.
-  */
- 
--yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj)
-+yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj)
- {
- 	if (obj && obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
- 		/* We want the object id of the equivalent object, not this one */
-@@ -6756,10 +6840,9 @@ yaffs_Object *yaffs_GetEquivalentObject(
- 		yaffs_CheckObjectDetailsLoaded(obj);
- 	}
- 	return obj;
--
- }
- 
--int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize)
-+int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize)
- {
- 	memset(name, 0, buffSize * sizeof(YCHAR));
- 
-@@ -6767,18 +6850,26 @@ int yaffs_GetObjectName(yaffs_Object * o
- 
- 	if (obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) {
- 		yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1);
--	} else if (obj->chunkId <= 0) {
-+	} else if (obj->hdrChunk <= 0) {
- 		YCHAR locName[20];
-+		YCHAR numString[20];
-+		YCHAR *x = &numString[19];
-+		unsigned v = obj->objectId;
-+		numString[19] = 0;
-+		while (v > 0) {
-+			x--;
-+			*x = '0' + (v % 10);
-+			v /= 10;
-+		}
- 		/* make up a name */
--		yaffs_sprintf(locName, _Y("%s%d"), YAFFS_LOSTNFOUND_PREFIX,
--			      obj->objectId);
-+		yaffs_strcpy(locName, YAFFS_LOSTNFOUND_PREFIX);
-+		yaffs_strcat(locName, x);
- 		yaffs_strncpy(name, locName, buffSize - 1);
- 
- 	}
- #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
--	else if (obj->shortName[0]) {
-+	else if (obj->shortName[0])
- 		yaffs_strcpy(name, obj->shortName);
--	}
- #endif
- 	else {
- 		int result;
-@@ -6788,9 +6879,9 @@ int yaffs_GetObjectName(yaffs_Object * o
- 
- 		memset(buffer, 0, obj->myDev->nDataBytesPerChunk);
- 
--		if (obj->chunkId >= 0) {
-+		if (obj->hdrChunk > 0) {
- 			result = yaffs_ReadChunkWithTagsFromNAND(obj->myDev,
--							obj->chunkId, buffer,
-+							obj->hdrChunk, buffer,
- 							NULL);
- 		}
- 		yaffs_strncpy(name, oh->name, buffSize - 1);
-@@ -6801,46 +6892,43 @@ int yaffs_GetObjectName(yaffs_Object * o
- 	return yaffs_strlen(name);
- }
- 
--int yaffs_GetObjectFileLength(yaffs_Object * obj)
-+int yaffs_GetObjectFileLength(yaffs_Object *obj)
- {
--
- 	/* Dereference any hard linking */
- 	obj = yaffs_GetEquivalentObject(obj);
- 
--	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE) {
-+	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE)
- 		return obj->variant.fileVariant.fileSize;
--	}
--	if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) {
-+	if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
- 		return yaffs_strlen(obj->variant.symLinkVariant.alias);
--	} else {
-+	else {
- 		/* Only a directory should drop through to here */
- 		return obj->myDev->nDataBytesPerChunk;
- 	}
- }
- 
--int yaffs_GetObjectLinkCount(yaffs_Object * obj)
-+int yaffs_GetObjectLinkCount(yaffs_Object *obj)
- {
- 	int count = 0;
--	struct list_head *i;
-+	struct ylist_head *i;
- 
--	if (!obj->unlinked) {
--		count++;	/* the object itself */
--	}
--	list_for_each(i, &obj->hardLinks) {
--		count++;	/* add the hard links; */
--	}
--	return count;
-+	if (!obj->unlinked)
-+		count++;		/* the object itself */
-+
-+	ylist_for_each(i, &obj->hardLinks)
-+		count++;		/* add the hard links; */
- 
-+	return count;
- }
- 
--int yaffs_GetObjectInode(yaffs_Object * obj)
-+int yaffs_GetObjectInode(yaffs_Object *obj)
- {
- 	obj = yaffs_GetEquivalentObject(obj);
- 
- 	return obj->objectId;
- }
- 
--unsigned yaffs_GetObjectType(yaffs_Object * obj)
-+unsigned yaffs_GetObjectType(yaffs_Object *obj)
- {
- 	obj = yaffs_GetEquivalentObject(obj);
- 
-@@ -6872,19 +6960,18 @@ unsigned yaffs_GetObjectType(yaffs_Objec
- 	}
- }
- 
--YCHAR *yaffs_GetSymlinkAlias(yaffs_Object * obj)
-+YCHAR *yaffs_GetSymlinkAlias(yaffs_Object *obj)
- {
- 	obj = yaffs_GetEquivalentObject(obj);
--	if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK) {
-+	if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
- 		return yaffs_CloneString(obj->variant.symLinkVariant.alias);
--	} else {
-+	else
- 		return yaffs_CloneString(_Y(""));
--	}
- }
- 
- #ifndef CONFIG_YAFFS_WINCE
- 
--int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr)
-+int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr)
- {
- 	unsigned int valid = attr->ia_valid;
- 
-@@ -6910,7 +6997,7 @@ int yaffs_SetAttributes(yaffs_Object * o
- 	return YAFFS_OK;
- 
- }
--int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr)
-+int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr)
- {
- 	unsigned int valid = 0;
- 
-@@ -6934,13 +7021,12 @@ int yaffs_GetAttributes(yaffs_Object * o
- 	attr->ia_valid = valid;
- 
- 	return YAFFS_OK;
--
- }
- 
- #endif
- 
- #if 0
--int yaffs_DumpObject(yaffs_Object * obj)
-+int yaffs_DumpObject(yaffs_Object *obj)
- {
- 	YCHAR name[257];
- 
-@@ -6951,7 +7037,7 @@ int yaffs_DumpObject(yaffs_Object * obj)
- 	   ("Object %d, inode %d \"%s\"\n dirty %d valid %d serial %d sum %d"
- 	    " chunk %d type %d size %d\n"
- 	    TENDSTR), obj->objectId, yaffs_GetObjectInode(obj), name,
--	   obj->dirty, obj->valid, obj->serial, obj->sum, obj->chunkId,
-+	   obj->dirty, obj->valid, obj->serial, obj->sum, obj->hdrChunk,
- 	   yaffs_GetObjectType(obj), yaffs_GetObjectFileLength(obj)));
- 
- 	return YAFFS_OK;
-@@ -6960,7 +7046,7 @@ int yaffs_DumpObject(yaffs_Object * obj)
- 
- /*---------------------------- Initialisation code -------------------------------------- */
- 
--static int yaffs_CheckDevFunctions(const yaffs_Device * dev)
-+static int yaffs_CheckDevFunctions(const yaffs_Device *dev)
- {
- 
- 	/* Common functions, gotta have */
-@@ -7011,7 +7097,7 @@ static int yaffs_CreateInitialDirectorie
- 	    yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_LOSTNFOUND,
- 				      YAFFS_LOSTNFOUND_MODE | S_IFDIR);
- 
--	if(dev->lostNFoundDir && dev->rootDir && dev->unlinkedDir && dev->deletedDir){
-+	if (dev->lostNFoundDir && dev->rootDir && dev->unlinkedDir && dev->deletedDir) {
- 		yaffs_AddObjectToDirectory(dev->rootDir, dev->lostNFoundDir);
- 		return YAFFS_OK;
- 	}
-@@ -7019,7 +7105,7 @@ static int yaffs_CreateInitialDirectorie
- 	return YAFFS_FAIL;
- }
- 
--int yaffs_GutsInitialise(yaffs_Device * dev)
-+int yaffs_GutsInitialise(yaffs_Device *dev)
- {
- 	int init_failed = 0;
- 	unsigned x;
-@@ -7040,6 +7126,8 @@ int yaffs_GutsInitialise(yaffs_Device *
- 	dev->chunkOffset = 0;
- 	dev->nFreeChunks = 0;
- 
-+	dev->gcBlock = -1;
-+
- 	if (dev->startBlock == 0) {
- 		dev->internalStartBlock = dev->startBlock + 1;
- 		dev->internalEndBlock = dev->endBlock + 1;
-@@ -7049,18 +7137,18 @@ int yaffs_GutsInitialise(yaffs_Device *
- 
- 	/* Check geometry parameters. */
- 
--	if ((dev->isYaffs2 && dev->nDataBytesPerChunk < 1024) ||
--	    (!dev->isYaffs2 && dev->nDataBytesPerChunk != 512) ||
-+	if ((!dev->inbandTags && dev->isYaffs2 && dev->totalBytesPerChunk < 1024) ||
-+	    (!dev->isYaffs2 && dev->totalBytesPerChunk < 512) ||
-+	    (dev->inbandTags && !dev->isYaffs2) ||
- 	     dev->nChunksPerBlock < 2 ||
- 	     dev->nReservedBlocks < 2 ||
- 	     dev->internalStartBlock <= 0 ||
- 	     dev->internalEndBlock <= 0 ||
--	     dev->internalEndBlock <= (dev->internalStartBlock + dev->nReservedBlocks + 2)	// otherwise it is too small
--	    ) {
-+	     dev->internalEndBlock <= (dev->internalStartBlock + dev->nReservedBlocks + 2)) {	/* otherwise it is too small */
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
--		   ("yaffs: NAND geometry problems: chunk size %d, type is yaffs%s "
--		    TENDSTR), dev->nDataBytesPerChunk, dev->isYaffs2 ? "2" : ""));
-+		   ("yaffs: NAND geometry problems: chunk size %d, type is yaffs%s, inbandTags %d "
-+		    TENDSTR), dev->totalBytesPerChunk, dev->isYaffs2 ? "2" : "", dev->inbandTags));
- 		return YAFFS_FAIL;
- 	}
- 
-@@ -7070,6 +7158,12 @@ int yaffs_GutsInitialise(yaffs_Device *
- 		return YAFFS_FAIL;
- 	}
- 
-+	/* Sort out space for inband tags, if required */
-+	if (dev->inbandTags)
-+		dev->nDataBytesPerChunk = dev->totalBytesPerChunk - sizeof(yaffs_PackedTags2TagsPart);
-+	else
-+		dev->nDataBytesPerChunk = dev->totalBytesPerChunk;
-+
- 	/* Got the right mix of functions? */
- 	if (!yaffs_CheckDevFunctions(dev)) {
- 		/* Function missing */
-@@ -7097,31 +7191,18 @@ int yaffs_GutsInitialise(yaffs_Device *
- 
- 	dev->isMounted = 1;
- 
--
--
- 	/* OK now calculate a few things for the device */
- 
- 	/*
- 	 *  Calculate all the chunk size manipulation numbers:
- 	 */
--	 /* Start off assuming it is a power of 2 */
--	 dev->chunkShift = ShiftDiv(dev->nDataBytesPerChunk);
--	 dev->chunkMask = (1<<dev->chunkShift) - 1;
--
--	 if(dev->nDataBytesPerChunk == (dev->chunkMask + 1)){
--	 	/* Yes it is a power of 2, disable crumbs */
--		dev->crumbMask = 0;
--		dev->crumbShift = 0;
--		dev->crumbsPerChunk = 0;
--	 } else {
--	 	/* Not a power of 2, use crumbs instead */
--		dev->crumbShift = ShiftDiv(sizeof(yaffs_PackedTags2TagsPart));
--		dev->crumbMask = (1<<dev->crumbShift)-1;
--		dev->crumbsPerChunk = dev->nDataBytesPerChunk/(1 << dev->crumbShift);
--		dev->chunkShift = 0;
--		dev->chunkMask = 0;
--	}
--
-+	x = dev->nDataBytesPerChunk;
-+	/* We always use dev->chunkShift and dev->chunkDiv */
-+	dev->chunkShift = Shifts(x);
-+	x >>= dev->chunkShift;
-+	dev->chunkDiv = x;
-+	/* We only use chunk mask if chunkDiv is 1 */
-+	dev->chunkMask = (1<<dev->chunkShift) - 1;
- 
- 	/*
- 	 * Calculate chunkGroupBits.
-@@ -7133,16 +7214,15 @@ int yaffs_GutsInitialise(yaffs_Device *
- 	bits = ShiftsGE(x);
- 
- 	/* Set up tnode width if wide tnodes are enabled. */
--	if(!dev->wideTnodesDisabled){
-+	if (!dev->wideTnodesDisabled) {
- 		/* bits must be even so that we end up with 32-bit words */
--		if(bits & 1)
-+		if (bits & 1)
- 			bits++;
--		if(bits < 16)
-+		if (bits < 16)
- 			dev->tnodeWidth = 16;
- 		else
- 			dev->tnodeWidth = bits;
--	}
--	else
-+	} else
- 		dev->tnodeWidth = 16;
- 
- 	dev->tnodeMask = (1<<dev->tnodeWidth)-1;
-@@ -7193,7 +7273,7 @@ int yaffs_GutsInitialise(yaffs_Device *
- 	dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
- 
- 	/* Initialise temporary buffers and caches. */
--	if(!yaffs_InitialiseTempBuffers(dev))
-+	if (!yaffs_InitialiseTempBuffers(dev))
- 		init_failed = 1;
- 
- 	dev->srCache = NULL;
-@@ -7203,25 +7283,26 @@ int yaffs_GutsInitialise(yaffs_Device *
- 	if (!init_failed &&
- 	    dev->nShortOpCaches > 0) {
- 		int i;
--		__u8 *buf;
-+		void *buf;
- 		int srCacheBytes = dev->nShortOpCaches * sizeof(yaffs_ChunkCache);
- 
--		if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES) {
-+		if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES)
- 			dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES;
--		}
- 
--		buf = dev->srCache =  YMALLOC(srCacheBytes);
-+		dev->srCache =  YMALLOC(srCacheBytes);
- 
--		if(dev->srCache)
--			memset(dev->srCache,0,srCacheBytes);
-+		buf = (__u8 *) dev->srCache;
-+
-+		if (dev->srCache)
-+			memset(dev->srCache, 0, srCacheBytes);
- 
- 		for (i = 0; i < dev->nShortOpCaches && buf; i++) {
- 			dev->srCache[i].object = NULL;
- 			dev->srCache[i].lastUse = 0;
- 			dev->srCache[i].dirty = 0;
--			dev->srCache[i].data = buf = YMALLOC_DMA(dev->nDataBytesPerChunk);
-+			dev->srCache[i].data = buf = YMALLOC_DMA(dev->totalBytesPerChunk);
- 		}
--		if(!buf)
-+		if (!buf)
- 			init_failed = 1;
- 
- 		dev->srLastUse = 0;
-@@ -7229,29 +7310,30 @@ int yaffs_GutsInitialise(yaffs_Device *
- 
- 	dev->cacheHits = 0;
- 
--	if(!init_failed){
-+	if (!init_failed) {
- 		dev->gcCleanupList = YMALLOC(dev->nChunksPerBlock * sizeof(__u32));
--		if(!dev->gcCleanupList)
-+		if (!dev->gcCleanupList)
- 			init_failed = 1;
- 	}
- 
--	if (dev->isYaffs2) {
-+	if (dev->isYaffs2)
- 		dev->useHeaderFileSize = 1;
--	}
--	if(!init_failed && !yaffs_InitialiseBlocks(dev))
-+
-+	if (!init_failed && !yaffs_InitialiseBlocks(dev))
- 		init_failed = 1;
- 
- 	yaffs_InitialiseTnodes(dev);
- 	yaffs_InitialiseObjects(dev);
- 
--	if(!init_failed && !yaffs_CreateInitialDirectories(dev))
-+	if (!init_failed && !yaffs_CreateInitialDirectories(dev))
- 		init_failed = 1;
- 
- 
--	if(!init_failed){
-+	if (!init_failed) {
- 		/* Now scan the flash. */
- 		if (dev->isYaffs2) {
--			if(yaffs_CheckpointRestore(dev)) {
-+			if (yaffs_CheckpointRestore(dev)) {
-+				yaffs_CheckObjectDetailsLoaded(dev->rootDir);
- 				T(YAFFS_TRACE_ALWAYS,
- 				  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
- 			} else {
-@@ -7273,24 +7355,25 @@ int yaffs_GutsInitialise(yaffs_Device *
- 				dev->nBackgroundDeletions = 0;
- 				dev->oldestDirtySequence = 0;
- 
--				if(!init_failed && !yaffs_InitialiseBlocks(dev))
-+				if (!init_failed && !yaffs_InitialiseBlocks(dev))
- 					init_failed = 1;
- 
- 				yaffs_InitialiseTnodes(dev);
- 				yaffs_InitialiseObjects(dev);
- 
--				if(!init_failed && !yaffs_CreateInitialDirectories(dev))
-+				if (!init_failed && !yaffs_CreateInitialDirectories(dev))
- 					init_failed = 1;
- 
--				if(!init_failed && !yaffs_ScanBackwards(dev))
-+				if (!init_failed && !yaffs_ScanBackwards(dev))
- 					init_failed = 1;
- 			}
--		}else
--			if(!yaffs_Scan(dev))
-+		} else if (!yaffs_Scan(dev))
- 				init_failed = 1;
-+
-+		yaffs_StripDeletedObjects(dev);
- 	}
- 
--	if(init_failed){
-+	if (init_failed) {
- 		/* Clean up the mess */
- 		T(YAFFS_TRACE_TRACING,
- 		  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
-@@ -7318,7 +7401,7 @@ int yaffs_GutsInitialise(yaffs_Device *
- 
- }
- 
--void yaffs_Deinitialise(yaffs_Device * dev)
-+void yaffs_Deinitialise(yaffs_Device *dev)
- {
- 	if (dev->isMounted) {
- 		int i;
-@@ -7330,7 +7413,7 @@ void yaffs_Deinitialise(yaffs_Device * d
- 		    dev->srCache) {
- 
- 			for (i = 0; i < dev->nShortOpCaches; i++) {
--				if(dev->srCache[i].data)
-+				if (dev->srCache[i].data)
- 					YFREE(dev->srCache[i].data);
- 				dev->srCache[i].data = NULL;
- 			}
-@@ -7341,16 +7424,17 @@ void yaffs_Deinitialise(yaffs_Device * d
- 
- 		YFREE(dev->gcCleanupList);
- 
--		for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
-+		for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
- 			YFREE(dev->tempBuffer[i].buffer);
--		}
- 
- 		dev->isMounted = 0;
--	}
- 
-+		if (dev->deinitialiseNAND)
-+			dev->deinitialiseNAND(dev);
-+	}
- }
- 
--static int yaffs_CountFreeChunks(yaffs_Device * dev)
-+static int yaffs_CountFreeChunks(yaffs_Device *dev)
- {
- 	int nFree;
- 	int b;
-@@ -7358,7 +7442,7 @@ static int yaffs_CountFreeChunks(yaffs_D
- 	yaffs_BlockInfo *blk;
- 
- 	for (nFree = 0, b = dev->internalStartBlock; b <= dev->internalEndBlock;
--	     b++) {
-+			b++) {
- 		blk = yaffs_GetBlockInfo(dev, b);
- 
- 		switch (blk->blockState) {
-@@ -7373,19 +7457,19 @@ static int yaffs_CountFreeChunks(yaffs_D
- 		default:
- 			break;
- 		}
--
- 	}
- 
- 	return nFree;
- }
- 
--int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev)
-+int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
- {
- 	/* This is what we report to the outside world */
- 
- 	int nFree;
- 	int nDirtyCacheChunks;
- 	int blocksForCheckpoint;
-+	int i;
- 
- #if 1
- 	nFree = dev->nFreeChunks;
-@@ -7397,12 +7481,9 @@ int yaffs_GetNumberOfFreeChunks(yaffs_De
- 
- 	/* Now count the number of dirty chunks in the cache and subtract those */
- 
--	{
--		int i;
--		for (nDirtyCacheChunks = 0, i = 0; i < dev->nShortOpCaches; i++) {
--			if (dev->srCache[i].dirty)
--				nDirtyCacheChunks++;
--		}
-+	for (nDirtyCacheChunks = 0, i = 0; i < dev->nShortOpCaches; i++) {
-+		if (dev->srCache[i].dirty)
-+			nDirtyCacheChunks++;
- 	}
- 
- 	nFree -= nDirtyCacheChunks;
-@@ -7410,8 +7491,8 @@ int yaffs_GetNumberOfFreeChunks(yaffs_De
- 	nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
- 
- 	/* Now we figure out how much to reserve for the checkpoint and report that... */
--	blocksForCheckpoint = dev->nCheckpointReservedBlocks - dev->blocksInCheckpoint;
--	if(blocksForCheckpoint < 0)
-+	blocksForCheckpoint = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
-+	if (blocksForCheckpoint < 0)
- 		blocksForCheckpoint = 0;
- 
- 	nFree -= (blocksForCheckpoint * dev->nChunksPerBlock);
-@@ -7425,12 +7506,12 @@ int yaffs_GetNumberOfFreeChunks(yaffs_De
- 
- static int yaffs_freeVerificationFailures;
- 
--static void yaffs_VerifyFreeChunks(yaffs_Device * dev)
-+static void yaffs_VerifyFreeChunks(yaffs_Device *dev)
- {
- 	int counted;
- 	int difference;
- 
--	if(yaffs_SkipVerification(dev))
-+	if (yaffs_SkipVerification(dev))
- 		return;
- 
- 	counted = yaffs_CountFreeChunks(dev);
-@@ -7447,23 +7528,25 @@ static void yaffs_VerifyFreeChunks(yaffs
- 
- /*---------------------------------------- YAFFS test code ----------------------*/
- 
--#define yaffs_CheckStruct(structure,syze, name) \
--           if(sizeof(structure) != syze) \
--	       { \
--	         T(YAFFS_TRACE_ALWAYS,(TSTR("%s should be %d but is %d\n" TENDSTR),\
--		 name,syze,sizeof(structure))); \
--	         return YAFFS_FAIL; \
--		}
-+#define yaffs_CheckStruct(structure, syze, name) \
-+	do { \
-+		if (sizeof(structure) != syze) { \
-+			T(YAFFS_TRACE_ALWAYS, (TSTR("%s should be %d but is %d\n" TENDSTR),\
-+				name, syze, sizeof(structure))); \
-+			return YAFFS_FAIL; \
-+		} \
-+	} while (0)
- 
- static int yaffs_CheckStructures(void)
- {
--/*      yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags") */
--/*      yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion") */
--/*      yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare") */
-+/*      yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags"); */
-+/*      yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion"); */
-+/*      yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare"); */
- #ifndef CONFIG_YAFFS_TNODE_LIST_DEBUG
--	yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode")
-+	yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode");
- #endif
--	    yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader")
--
--	    return YAFFS_OK;
-+#ifndef CONFIG_YAFFS_WINCE
-+	yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader");
-+#endif
-+	return YAFFS_OK;
- }
---- a/fs/yaffs2/yaffs_guts.h
-+++ b/fs/yaffs2/yaffs_guts.h
-@@ -90,7 +90,7 @@
- 
- #define YAFFS_MAX_SHORT_OP_CACHES	20
- 
--#define YAFFS_N_TEMP_BUFFERS		4
-+#define YAFFS_N_TEMP_BUFFERS		6
- 
- /* We limit the number attempts at sucessfully saving a chunk of data.
-  * Small-page devices have 32 pages per block; large-page devices have 64.
-@@ -108,6 +108,9 @@
- #define YAFFS_LOWEST_SEQUENCE_NUMBER	0x00001000
- #define YAFFS_HIGHEST_SEQUENCE_NUMBER	0xEFFFFF00
- 
-+/* Special sequence number for bad block that failed to be marked bad */
-+#define YAFFS_SEQUENCE_BAD_BLOCK	0xFFFF0000
-+
- /* ChunkCache is used for short read/write operations.*/
- typedef struct {
- 	struct yaffs_ObjectStruct *object;
-@@ -134,11 +137,10 @@ typedef struct {
- typedef struct {
- 	unsigned chunkId:20;
- 	unsigned serialNumber:2;
--	unsigned byteCount:10;
-+	unsigned byteCountLSB:10;
- 	unsigned objectId:18;
- 	unsigned ecc:12;
--	unsigned unusedStuff:2;
--
-+	unsigned byteCountMSB:2;
- } yaffs_Tags;
- 
- typedef union {
-@@ -277,13 +279,13 @@ typedef struct {
- 
- 	int softDeletions:10;	/* number of soft deleted pages */
- 	int pagesInUse:10;	/* number of pages in use */
--	yaffs_BlockState blockState:4;	/* One of the above block states */
-+	unsigned blockState:4;	/* One of the above block states. NB use unsigned because enum is sometimes an int */
- 	__u32 needsRetiring:1;	/* Data has failed on this block, need to get valid data off */
--                        	/* and retire the block. */
--	__u32 skipErasedCheck: 1; /* If this is set we can skip the erased check on this block */
--	__u32 gcPrioritise: 1; 	/* An ECC check or blank check has failed on this block.
-+				/* and retire the block. */
-+	__u32 skipErasedCheck:1; /* If this is set we can skip the erased check on this block */
-+	__u32 gcPrioritise:1; 	/* An ECC check or blank check has failed on this block.
- 				   It should be prioritised for GC */
--        __u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
-+	__u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
- 
- #ifdef CONFIG_YAFFS_YAFFS2
- 	__u32 hasShrinkHeader:1; /* This block has at least one shrink object header */
-@@ -300,11 +302,11 @@ typedef struct {
- 
- 	/* Apply to everything  */
- 	int parentObjectId;
--	__u16 sum__NoLongerUsed;	/* checksum of name. No longer used */
-+	__u16 sum__NoLongerUsed;        /* checksum of name. No longer used */
- 	YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
- 
--	/* Thes following apply to directories, files, symlinks - not hard links */
--	__u32 yst_mode;		/* protection */
-+	/* The following apply to directories, files, symlinks - not hard links */
-+	__u32 yst_mode;         /* protection */
- 
- #ifdef CONFIG_YAFFS_WINCE
- 	__u32 notForWinCE[5];
-@@ -331,11 +333,14 @@ typedef struct {
- 	__u32 win_ctime[2];
- 	__u32 win_atime[2];
- 	__u32 win_mtime[2];
--	__u32 roomToGrow[4];
- #else
--	__u32 roomToGrow[10];
-+	__u32 roomToGrow[6];
-+
- #endif
-+	__u32 inbandShadowsObject;
-+	__u32 inbandIsShrink;
- 
-+	__u32 reservedSpace[2];
- 	int shadowsObject;	/* This object header shadows the specified object if > 0 */
- 
- 	/* isShrink applies to object headers written when we shrink the file (ie resize) */
-@@ -381,7 +386,7 @@ typedef struct {
- } yaffs_FileStructure;
- 
- typedef struct {
--	struct list_head children;	/* list of child links */
-+	struct ylist_head children;     /* list of child links */
- } yaffs_DirectoryStructure;
- 
- typedef struct {
-@@ -418,23 +423,24 @@ struct yaffs_ObjectStruct {
- 				 * still in the inode cache. Free of object is defered.
- 				 * until the inode is released.
- 				 */
-+	__u8 beingCreated:1;	/* This object is still being created so skip some checks. */
- 
- 	__u8 serial;		/* serial number of chunk in NAND. Cached here */
- 	__u16 sum;		/* sum of the name to speed searching */
- 
--	struct yaffs_DeviceStruct *myDev;	/* The device I'm on */
-+	struct yaffs_DeviceStruct *myDev;       /* The device I'm on */
- 
--	struct list_head hashLink;	/* list of objects in this hash bucket */
-+	struct ylist_head hashLink;     /* list of objects in this hash bucket */
- 
--	struct list_head hardLinks;	/* all the equivalent hard linked objects */
-+	struct ylist_head hardLinks;    /* all the equivalent hard linked objects */
- 
- 	/* directory structure stuff */
- 	/* also used for linking up the free list */
- 	struct yaffs_ObjectStruct *parent;
--	struct list_head siblings;
-+	struct ylist_head siblings;
- 
- 	/* Where's my object header in NAND? */
--	int chunkId;
-+	int hdrChunk;
- 
- 	int nDataChunks;	/* Number of data chunks attached to the file. */
- 
-@@ -485,7 +491,7 @@ struct yaffs_ObjectList_struct {
- typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
- 
- typedef struct {
--	struct list_head list;
-+	struct ylist_head list;
- 	int count;
- } yaffs_ObjectBucket;
- 
-@@ -495,11 +501,10 @@ typedef struct {
-  */
- 
- typedef struct {
--        int structType;
-+	int structType;
- 	__u32 objectId;
- 	__u32 parentId;
--	int chunkId;
--
-+	int hdrChunk;
- 	yaffs_ObjectType variantType:3;
- 	__u8 deleted:1;
- 	__u8 softDeleted:1;
-@@ -511,8 +516,7 @@ typedef struct {
- 
- 	int nDataChunks;
- 	__u32 fileSizeOrEquivalentObjectId;
--
--}yaffs_CheckpointObject;
-+} yaffs_CheckpointObject;
- 
- /*--------------------- Temporary buffers ----------------
-  *
-@@ -528,13 +532,13 @@ typedef struct {
- /*----------------- Device ---------------------------------*/
- 
- struct yaffs_DeviceStruct {
--	struct list_head devList;
-+	struct ylist_head devList;
- 	const char *name;
- 
- 	/* Entry parameters set up way early. Yaffs sets up the rest.*/
- 	int nDataBytesPerChunk;	/* Should be a power of 2 >= 512 */
- 	int nChunksPerBlock;	/* does not need to be a power of 2 */
--	int nBytesPerSpare;	/* spare area size */
-+	int spareBytesPerChunk;	/* spare area size */
- 	int startBlock;		/* Start block we're allowed to use */
- 	int endBlock;		/* End block we're allowed to use */
- 	int nReservedBlocks;	/* We want this tuneable so that we can reduce */
-@@ -544,9 +548,7 @@ struct yaffs_DeviceStruct {
- 	/* Stuff used by the shared space checkpointing mechanism */
- 	/* If this value is zero, then this mechanism is disabled */
- 
--	int nCheckpointReservedBlocks; /* Blocks to reserve for checkpoint data */
--
--
-+/*	int nCheckpointReservedBlocks; */ /* Blocks to reserve for checkpoint data */
- 
- 
- 	int nShortOpCaches;	/* If <= 0, then short op caching is disabled, else
-@@ -560,30 +562,31 @@ struct yaffs_DeviceStruct {
- 	void *genericDevice;	/* Pointer to device context
- 				 * On an mtd this holds the mtd pointer.
- 				 */
--        void *superBlock;
-+	void *superBlock;
- 
- 	/* NAND access functions (Must be set before calling YAFFS)*/
- 
--	int (*writeChunkToNAND) (struct yaffs_DeviceStruct * dev,
--				 int chunkInNAND, const __u8 * data,
--				 const yaffs_Spare * spare);
--	int (*readChunkFromNAND) (struct yaffs_DeviceStruct * dev,
--				  int chunkInNAND, __u8 * data,
--				  yaffs_Spare * spare);
--	int (*eraseBlockInNAND) (struct yaffs_DeviceStruct * dev,
--				 int blockInNAND);
--	int (*initialiseNAND) (struct yaffs_DeviceStruct * dev);
-+	int (*writeChunkToNAND) (struct yaffs_DeviceStruct *dev,
-+					int chunkInNAND, const __u8 *data,
-+					const yaffs_Spare *spare);
-+	int (*readChunkFromNAND) (struct yaffs_DeviceStruct *dev,
-+					int chunkInNAND, __u8 *data,
-+					yaffs_Spare *spare);
-+	int (*eraseBlockInNAND) (struct yaffs_DeviceStruct *dev,
-+					int blockInNAND);
-+	int (*initialiseNAND) (struct yaffs_DeviceStruct *dev);
-+	int (*deinitialiseNAND) (struct yaffs_DeviceStruct *dev);
- 
- #ifdef CONFIG_YAFFS_YAFFS2
--	int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct * dev,
--					 int chunkInNAND, const __u8 * data,
--					 const yaffs_ExtendedTags * tags);
--	int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct * dev,
--					  int chunkInNAND, __u8 * data,
--					  yaffs_ExtendedTags * tags);
--	int (*markNANDBlockBad) (struct yaffs_DeviceStruct * dev, int blockNo);
--	int (*queryNANDBlock) (struct yaffs_DeviceStruct * dev, int blockNo,
--			       yaffs_BlockState * state, int *sequenceNumber);
-+	int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct *dev,
-+					 int chunkInNAND, const __u8 *data,
-+					 const yaffs_ExtendedTags *tags);
-+	int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct *dev,
-+					  int chunkInNAND, __u8 *data,
-+					  yaffs_ExtendedTags *tags);
-+	int (*markNANDBlockBad) (struct yaffs_DeviceStruct *dev, int blockNo);
-+	int (*queryNANDBlock) (struct yaffs_DeviceStruct *dev, int blockNo,
-+			       yaffs_BlockState *state, __u32 *sequenceNumber);
- #endif
- 
- 	int isYaffs2;
-@@ -595,10 +598,12 @@ struct yaffs_DeviceStruct {
- 	void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj);
- 
- 	/* Callback to mark the superblock dirsty */
--	void (*markSuperBlockDirty)(void * superblock);
-+	void (*markSuperBlockDirty)(void *superblock);
- 
- 	int wideTnodesDisabled; /* Set to disable wide tnodes */
- 
-+	YCHAR *pathDividers;	/* String of legal path dividers */
-+
- 
- 	/* End of stuff that must be set before initialisation. */
- 
-@@ -615,16 +620,14 @@ struct yaffs_DeviceStruct {
- 	__u32 tnodeWidth;
- 	__u32 tnodeMask;
- 
--	/* Stuff to support various file offses to chunk/offset translations */
--	/* "Crumbs" for nDataBytesPerChunk not being a power of 2 */
--	__u32 crumbMask;
--	__u32 crumbShift;
--	__u32 crumbsPerChunk;
--
--	/* Straight shifting for nDataBytesPerChunk being a power of 2 */
--	__u32 chunkShift;
--	__u32 chunkMask;
--
-+	/* Stuff for figuring out file offset to chunk conversions */
-+	__u32 chunkShift; /* Shift value */
-+	__u32 chunkDiv;   /* Divisor after shifting: 1 for power-of-2 sizes */
-+	__u32 chunkMask;  /* Mask to use for power-of-2 case */
-+
-+	/* Stuff to handle inband tags */
-+	int inbandTags;
-+	__u32 totalBytesPerChunk;
- 
- #ifdef __KERNEL__
- 
-@@ -633,7 +636,7 @@ struct yaffs_DeviceStruct {
- 	__u8 *spareBuffer;	/* For mtdif2 use. Don't know the size of the buffer
- 				 * at compile time so we have to allocate it.
- 				 */
--	void (*putSuperFunc) (struct super_block * sb);
-+	void (*putSuperFunc) (struct super_block *sb);
- #endif
- 
- 	int isMounted;
-@@ -663,6 +666,8 @@ struct yaffs_DeviceStruct {
- 	__u32 checkpointSum;
- 	__u32 checkpointXor;
- 
-+	int nCheckpointBlocksRequired; /* Number of blocks needed to store current checkpoint set */
-+
- 	/* Block Info */
- 	yaffs_BlockInfo *blockInfo;
- 	__u8 *chunkBits;	/* bitmap of chunks in use */
-@@ -684,11 +689,15 @@ struct yaffs_DeviceStruct {
- 	yaffs_TnodeList *allocatedTnodeList;
- 
- 	int isDoingGC;
-+	int gcBlock;
-+	int gcChunk;
- 
- 	int nObjectsCreated;
- 	yaffs_Object *freeObjects;
- 	int nFreeObjects;
- 
-+	int nHardLinks;
-+
- 	yaffs_ObjectList *allocatedObjectList;
- 
- 	yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS];
-@@ -745,8 +754,10 @@ struct yaffs_DeviceStruct {
- 	int nBackgroundDeletions;	/* Count of background deletions. */
- 
- 
-+	/* Temporary buffer management */
- 	yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS];
- 	int maxTemp;
-+	int tempInUse;
- 	int unmanagedTempAllocations;
- 	int unmanagedTempDeallocations;
- 
-@@ -758,9 +769,9 @@ struct yaffs_DeviceStruct {
- 
- typedef struct yaffs_DeviceStruct yaffs_Device;
- 
--/* The static layout of bllock usage etc is stored in the super block header */
-+/* The static layout of block usage etc is stored in the super block header */
- typedef struct {
--        int StructType;
-+	int StructType;
- 	int version;
- 	int checkpointStartBlock;
- 	int checkpointEndBlock;
-@@ -773,7 +784,7 @@ typedef struct {
-  * must be preserved over unmount/mount cycles.
-  */
- typedef struct {
--        int structType;
-+	int structType;
- 	int nErasedBlocks;
- 	int allocationBlock;	/* Current block being allocated off */
- 	__u32 allocationPage;
-@@ -791,57 +802,45 @@ typedef struct {
- 
- 
- typedef struct {
--    int structType;
--    __u32 magic;
--    __u32 version;
--    __u32 head;
-+	int structType;
-+	__u32 magic;
-+	__u32 version;
-+	__u32 head;
- } yaffs_CheckpointValidity;
- 
--/* Function to manipulate block info */
--static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
--{
--	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
--		T(YAFFS_TRACE_ERROR,
--		  (TSTR
--		   ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
--		   blk));
--		YBUG();
--	}
--	return &dev->blockInfo[blk - dev->internalStartBlock];
--}
- 
- /*----------------------- YAFFS Functions -----------------------*/
- 
--int yaffs_GutsInitialise(yaffs_Device * dev);
--void yaffs_Deinitialise(yaffs_Device * dev);
-+int yaffs_GutsInitialise(yaffs_Device *dev);
-+void yaffs_Deinitialise(yaffs_Device *dev);
- 
--int yaffs_GetNumberOfFreeChunks(yaffs_Device * dev);
-+int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev);
- 
--int yaffs_RenameObject(yaffs_Object * oldDir, const YCHAR * oldName,
--		       yaffs_Object * newDir, const YCHAR * newName);
-+int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
-+		       yaffs_Object *newDir, const YCHAR *newName);
- 
--int yaffs_Unlink(yaffs_Object * dir, const YCHAR * name);
--int yaffs_DeleteFile(yaffs_Object * obj);
-+int yaffs_Unlink(yaffs_Object *dir, const YCHAR *name);
-+int yaffs_DeleteObject(yaffs_Object *obj);
- 
--int yaffs_GetObjectName(yaffs_Object * obj, YCHAR * name, int buffSize);
--int yaffs_GetObjectFileLength(yaffs_Object * obj);
--int yaffs_GetObjectInode(yaffs_Object * obj);
--unsigned yaffs_GetObjectType(yaffs_Object * obj);
--int yaffs_GetObjectLinkCount(yaffs_Object * obj);
-+int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize);
-+int yaffs_GetObjectFileLength(yaffs_Object *obj);
-+int yaffs_GetObjectInode(yaffs_Object *obj);
-+unsigned yaffs_GetObjectType(yaffs_Object *obj);
-+int yaffs_GetObjectLinkCount(yaffs_Object *obj);
- 
--int yaffs_SetAttributes(yaffs_Object * obj, struct iattr *attr);
--int yaffs_GetAttributes(yaffs_Object * obj, struct iattr *attr);
-+int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr);
-+int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr);
- 
- /* File operations */
--int yaffs_ReadDataFromFile(yaffs_Object * obj, __u8 * buffer, loff_t offset,
--			   int nBytes);
--int yaffs_WriteDataToFile(yaffs_Object * obj, const __u8 * buffer, loff_t offset,
--			  int nBytes, int writeThrough);
--int yaffs_ResizeFile(yaffs_Object * obj, loff_t newSize);
--
--yaffs_Object *yaffs_MknodFile(yaffs_Object * parent, const YCHAR * name,
--			      __u32 mode, __u32 uid, __u32 gid);
--int yaffs_FlushFile(yaffs_Object * obj, int updateTime);
-+int yaffs_ReadDataFromFile(yaffs_Object *obj, __u8 *buffer, loff_t offset,
-+				int nBytes);
-+int yaffs_WriteDataToFile(yaffs_Object *obj, const __u8 *buffer, loff_t offset,
-+				int nBytes, int writeThrough);
-+int yaffs_ResizeFile(yaffs_Object *obj, loff_t newSize);
-+
-+yaffs_Object *yaffs_MknodFile(yaffs_Object *parent, const YCHAR *name,
-+				__u32 mode, __u32 uid, __u32 gid);
-+int yaffs_FlushFile(yaffs_Object *obj, int updateTime);
- 
- /* Flushing and checkpointing */
- void yaffs_FlushEntireDeviceCache(yaffs_Device *dev);
-@@ -850,33 +849,33 @@ int yaffs_CheckpointSave(yaffs_Device *d
- int yaffs_CheckpointRestore(yaffs_Device *dev);
- 
- /* Directory operations */
--yaffs_Object *yaffs_MknodDirectory(yaffs_Object * parent, const YCHAR * name,
--				   __u32 mode, __u32 uid, __u32 gid);
--yaffs_Object *yaffs_FindObjectByName(yaffs_Object * theDir, const YCHAR * name);
--int yaffs_ApplyToDirectoryChildren(yaffs_Object * theDir,
-+yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent, const YCHAR *name,
-+				__u32 mode, __u32 uid, __u32 gid);
-+yaffs_Object *yaffs_FindObjectByName(yaffs_Object *theDir, const YCHAR *name);
-+int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,
- 				   int (*fn) (yaffs_Object *));
- 
--yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device * dev, __u32 number);
-+yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev, __u32 number);
- 
- /* Link operations */
--yaffs_Object *yaffs_Link(yaffs_Object * parent, const YCHAR * name,
--			 yaffs_Object * equivalentObject);
-+yaffs_Object *yaffs_Link(yaffs_Object *parent, const YCHAR *name,
-+			 yaffs_Object *equivalentObject);
- 
--yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object * obj);
-+yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj);
- 
- /* Symlink operations */
--yaffs_Object *yaffs_MknodSymLink(yaffs_Object * parent, const YCHAR * name,
-+yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const YCHAR *name,
- 				 __u32 mode, __u32 uid, __u32 gid,
--				 const YCHAR * alias);
--YCHAR *yaffs_GetSymlinkAlias(yaffs_Object * obj);
-+				 const YCHAR *alias);
-+YCHAR *yaffs_GetSymlinkAlias(yaffs_Object *obj);
- 
- /* Special inodes (fifos, sockets and devices) */
--yaffs_Object *yaffs_MknodSpecial(yaffs_Object * parent, const YCHAR * name,
-+yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent, const YCHAR *name,
- 				 __u32 mode, __u32 uid, __u32 gid, __u32 rdev);
- 
- /* Special directories */
--yaffs_Object *yaffs_Root(yaffs_Device * dev);
--yaffs_Object *yaffs_LostNFound(yaffs_Device * dev);
-+yaffs_Object *yaffs_Root(yaffs_Device *dev);
-+yaffs_Object *yaffs_LostNFound(yaffs_Device *dev);
- 
- #ifdef CONFIG_YAFFS_WINCE
- /* CONFIG_YAFFS_WINCE special stuff */
-@@ -885,18 +884,21 @@ void yfsd_WinFileTimeNow(__u32 target[2]
- 
- #ifdef __KERNEL__
- 
--void yaffs_HandleDeferedFree(yaffs_Object * obj);
-+void yaffs_HandleDeferedFree(yaffs_Object *obj);
- #endif
- 
- /* Debug dump  */
--int yaffs_DumpObject(yaffs_Object * obj);
-+int yaffs_DumpObject(yaffs_Object *obj);
- 
--void yaffs_GutsTest(yaffs_Device * dev);
-+void yaffs_GutsTest(yaffs_Device *dev);
- 
- /* A few useful functions */
--void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
--void yaffs_DeleteChunk(yaffs_Device * dev, int chunkId, int markNAND, int lyn);
--int yaffs_CheckFF(__u8 * buffer, int nBytes);
-+void yaffs_InitialiseTags(yaffs_ExtendedTags *tags);
-+void yaffs_DeleteChunk(yaffs_Device *dev, int chunkId, int markNAND, int lyn);
-+int yaffs_CheckFF(__u8 *buffer, int nBytes);
- void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
- 
-+__u8 *yaffs_GetTempBuffer(yaffs_Device *dev, int lineNo);
-+void yaffs_ReleaseTempBuffer(yaffs_Device *dev, __u8 *buffer, int lineNo);
-+
- #endif
---- a/fs/yaffs2/yaffs_mtdif1.c
-+++ b/fs/yaffs2/yaffs_mtdif1.c
-@@ -26,7 +26,7 @@
- #include "yportenv.h"
- #include "yaffs_guts.h"
- #include "yaffs_packedtags1.h"
--#include "yaffs_tagscompat.h"	// for yaffs_CalcTagsECC
-+#include "yaffs_tagscompat.h"	/* for yaffs_CalcTagsECC */
- 
- #include "linux/kernel.h"
- #include "linux/version.h"
-@@ -34,9 +34,9 @@
- #include "linux/mtd/mtd.h"
- 
- /* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 
--const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.3 2007/05/15 20:16:11 ian Exp $";
-+const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.10 2009-03-09 07:41:10 charles Exp $";
- 
- #ifndef CONFIG_YAFFS_9BYTE_TAGS
- # define YTAG1_SIZE 8
-@@ -89,9 +89,9 @@ static struct nand_ecclayout nand_oob_16
-  * Returns YAFFS_OK or YAFFS_FAIL.
-  */
- int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev,
--	int chunkInNAND, const __u8 * data, const yaffs_ExtendedTags * etags)
-+	int chunkInNAND, const __u8 *data, const yaffs_ExtendedTags *etags)
- {
--	struct mtd_info * mtd = dev->genericDevice;
-+	struct mtd_info *mtd = dev->genericDevice;
- 	int chunkBytes = dev->nDataBytesPerChunk;
- 	loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
- 	struct mtd_oob_ops ops;
-@@ -146,7 +146,7 @@ int nandmtd1_WriteChunkWithTagsToNAND(ya
- 
- /* Return with empty ExtendedTags but add eccResult.
-  */
--static int rettags(yaffs_ExtendedTags * etags, int eccResult, int retval)
-+static int rettags(yaffs_ExtendedTags *etags, int eccResult, int retval)
- {
- 	if (etags) {
- 		memset(etags, 0, sizeof(*etags));
-@@ -169,9 +169,9 @@ static int rettags(yaffs_ExtendedTags *
-  * Returns YAFFS_OK or YAFFS_FAIL.
-  */
- int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
--	int chunkInNAND, __u8 * data, yaffs_ExtendedTags * etags)
-+	int chunkInNAND, __u8 *data, yaffs_ExtendedTags *etags)
- {
--	struct mtd_info * mtd = dev->genericDevice;
-+	struct mtd_info *mtd = dev->genericDevice;
- 	int chunkBytes = dev->nDataBytesPerChunk;
- 	loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
- 	int eccres = YAFFS_ECC_RESULT_NO_ERROR;
-@@ -189,7 +189,7 @@ int nandmtd1_ReadChunkWithTagsFromNAND(y
- 	ops.datbuf = data;
- 	ops.oobbuf = (__u8 *)&pt1;
- 
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
-+#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 20))
- 	/* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug;
- 	 * help it out with ops.len = ops.ooblen when ops.datbuf == NULL.
- 	 */
-@@ -284,11 +284,11 @@ int nandmtd1_ReadChunkWithTagsFromNAND(y
-  */
- int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
- {
--	struct mtd_info * mtd = dev->genericDevice;
-+	struct mtd_info *mtd = dev->genericDevice;
- 	int blocksize = dev->nChunksPerBlock * dev->nDataBytesPerChunk;
- 	int retval;
- 
--	yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", blockNo);
-+	yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad\n", blockNo);
- 
- 	retval = mtd->block_markbad(mtd, (loff_t)blocksize * blockNo);
- 	return (retval) ? YAFFS_FAIL : YAFFS_OK;
-@@ -298,7 +298,7 @@ int nandmtd1_MarkNANDBlockBad(struct yaf
-  *
-  * Returns YAFFS_OK or YAFFS_FAIL.
-  */
--static int nandmtd1_TestPrerequists(struct mtd_info * mtd)
-+static int nandmtd1_TestPrerequists(struct mtd_info *mtd)
- {
- 	/* 2.6.18 has mtd->ecclayout->oobavail */
- 	/* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
-@@ -323,10 +323,11 @@ static int nandmtd1_TestPrerequists(stru
-  * Always returns YAFFS_OK.
-  */
- int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--	yaffs_BlockState * pState, int *pSequenceNumber)
-+	yaffs_BlockState *pState, __u32 *pSequenceNumber)
- {
--	struct mtd_info * mtd = dev->genericDevice;
-+	struct mtd_info *mtd = dev->genericDevice;
- 	int chunkNo = blockNo * dev->nChunksPerBlock;
-+	loff_t addr = (loff_t)chunkNo * dev->nDataBytesPerChunk;
- 	yaffs_ExtendedTags etags;
- 	int state = YAFFS_BLOCK_STATE_DEAD;
- 	int seqnum = 0;
-@@ -335,21 +336,22 @@ int nandmtd1_QueryNANDBlock(struct yaffs
- 	/* We don't yet have a good place to test for MTD config prerequists.
- 	 * Do it here as we are called during the initial scan.
- 	 */
--	if (nandmtd1_TestPrerequists(mtd) != YAFFS_OK) {
-+	if (nandmtd1_TestPrerequists(mtd) != YAFFS_OK)
- 		return YAFFS_FAIL;
--	}
- 
- 	retval = nandmtd1_ReadChunkWithTagsFromNAND(dev, chunkNo, NULL, &etags);
-+	etags.blockBad = (mtd->block_isbad)(mtd, addr);
- 	if (etags.blockBad) {
- 		yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
--			"block %d is marked bad", blockNo);
-+			"block %d is marked bad\n", blockNo);
- 		state = YAFFS_BLOCK_STATE_DEAD;
--	}
--	else if (etags.chunkUsed) {
-+	} else if (etags.eccResult != YAFFS_ECC_RESULT_NO_ERROR) {
-+		/* bad tags, need to look more closely */
-+		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
-+	} else if (etags.chunkUsed) {
- 		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
- 		seqnum = etags.sequenceNumber;
--	}
--	else {
-+	} else {
- 		state = YAFFS_BLOCK_STATE_EMPTY;
- 	}
- 
-@@ -360,4 +362,4 @@ int nandmtd1_QueryNANDBlock(struct yaffs
- 	return YAFFS_OK;
- }
- 
--#endif /*KERNEL_VERSION*/
-+#endif /*MTD_VERSION*/
---- a/fs/yaffs2/yaffs_mtdif1.h
-+++ b/fs/yaffs2/yaffs_mtdif1.h
-@@ -14,15 +14,15 @@
- #ifndef __YAFFS_MTDIF1_H__
- #define __YAFFS_MTDIF1_H__
- 
--int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
--	const __u8 * data, const yaffs_ExtendedTags * tags);
-+int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
-+	const __u8 *data, const yaffs_ExtendedTags *tags);
- 
--int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
--	__u8 * data, yaffs_ExtendedTags * tags);
-+int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
-+	__u8 *data, yaffs_ExtendedTags *tags);
- 
- int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
- 
- int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--	yaffs_BlockState * state, int *sequenceNumber);
-+	yaffs_BlockState *state, __u32 *sequenceNumber);
- 
- #endif
---- a/fs/yaffs2/yaffs_mtdif2.c
-+++ b/fs/yaffs2/yaffs_mtdif2.c
-@@ -14,7 +14,7 @@
- /* mtd interface for YAFFS2 */
- 
- const char *yaffs_mtdif2_c_version =
--    "$Id: yaffs_mtdif2.c,v 1.17 2007-02-14 01:09:06 wookey Exp $";
-+	"$Id: yaffs_mtdif2.c,v 1.23 2009-03-06 17:20:53 wookey Exp $";
- 
- #include "yportenv.h"
- 
-@@ -27,19 +27,23 @@ const char *yaffs_mtdif2_c_version =
- 
- #include "yaffs_packedtags2.h"
- 
--int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
--				      const __u8 * data,
--				      const yaffs_ExtendedTags * tags)
-+/* NB For use with inband tags....
-+ * We assume that the data buffer is of size totalBytersPerChunk so that we can also
-+ * use it to load the tags.
-+ */
-+int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
-+				      const __u8 *data,
-+				      const yaffs_ExtendedTags *tags)
- {
- 	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 	struct mtd_oob_ops ops;
- #else
- 	size_t dummy;
- #endif
- 	int retval = 0;
- 
--	loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
-+	loff_t addr;
- 
- 	yaffs_PackedTags2 pt;
- 
-@@ -48,46 +52,40 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
- 	   ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
- 	    TENDSTR), chunkInNAND, data, tags));
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
--	if (tags)
--		yaffs_PackTags2(&pt, tags);
--	else
--		BUG(); /* both tags and data should always be present */
- 
--	if (data) {
--		ops.mode = MTD_OOB_AUTO;
--		ops.ooblen = sizeof(pt);
--		ops.len = dev->nDataBytesPerChunk;
--		ops.ooboffs = 0;
--		ops.datbuf = (__u8 *)data;
--		ops.oobbuf = (void *)&pt;
--		retval = mtd->write_oob(mtd, addr, &ops);
-+	addr  = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
-+
-+	/* For yaffs2 writing there must be both data and tags.
-+	 * If we're using inband tags, then the tags are stuffed into
-+	 * the end of the data buffer.
-+	 */
-+	if (!data || !tags)
-+		BUG();
-+	else if (dev->inbandTags) {
-+		yaffs_PackedTags2TagsPart *pt2tp;
-+		pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
-+		yaffs_PackTags2TagsPart(pt2tp, tags);
- 	} else
--		BUG(); /* both tags and data should always be present */
--#else
--	if (tags) {
- 		yaffs_PackTags2(&pt, tags);
--	}
- 
--	if (data && tags) {
--		if (dev->useNANDECC)
--			retval =
--			    mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
--					   &dummy, data, (__u8 *) & pt, NULL);
--		else
--			retval =
--			    mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
--					   &dummy, data, (__u8 *) & pt, NULL);
--	} else {
--		if (data)
--			retval =
--			    mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy,
--				       data);
--		if (tags)
--			retval =
--			    mtd->write_oob(mtd, addr, mtd->oobsize, &dummy,
--					   (__u8 *) & pt);
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+	ops.mode = MTD_OOB_AUTO;
-+	ops.ooblen = (dev->inbandTags) ? 0 : sizeof(pt);
-+	ops.len = dev->totalBytesPerChunk;
-+	ops.ooboffs = 0;
-+	ops.datbuf = (__u8 *)data;
-+	ops.oobbuf = (dev->inbandTags) ? NULL : (void *)&pt;
-+	retval = mtd->write_oob(mtd, addr, &ops);
- 
-+#else
-+	if (!dev->inbandTags) {
-+		retval =
-+		    mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+				   &dummy, data, (__u8 *) &pt, NULL);
-+	} else {
-+		retval =
-+		    mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy,
-+			       data);
- 	}
- #endif
- 
-@@ -97,17 +95,18 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
- 		return YAFFS_FAIL;
- }
- 
--int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
--				       __u8 * data, yaffs_ExtendedTags * tags)
-+int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
-+				       __u8 *data, yaffs_ExtendedTags *tags)
- {
- 	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 	struct mtd_oob_ops ops;
- #endif
- 	size_t dummy;
- 	int retval = 0;
-+	int localData = 0;
- 
--	loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
-+	loff_t addr = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
- 
- 	yaffs_PackedTags2 pt;
- 
-@@ -116,9 +115,20 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
- 	   ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
- 	    TENDSTR), chunkInNAND, data, tags));
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
--	if (data && !tags)
--		retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
-+	if (dev->inbandTags) {
-+
-+		if (!data) {
-+			localData = 1;
-+			data = yaffs_GetTempBuffer(dev, __LINE__);
-+		}
-+
-+
-+	}
-+
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+	if (dev->inbandTags || (data && !tags))
-+		retval = mtd->read(mtd, addr, dev->totalBytesPerChunk,
- 				&dummy, data);
- 	else if (tags) {
- 		ops.mode = MTD_OOB_AUTO;
-@@ -130,38 +140,42 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
- 		retval = mtd->read_oob(mtd, addr, &ops);
- 	}
- #else
--	if (data && tags) {
--		if (dev->useNANDECC) {
--			retval =
--			    mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
--					  &dummy, data, dev->spareBuffer,
--					  NULL);
--		} else {
--			retval =
--			    mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+	if (!dev->inbandTags && data && tags) {
-+
-+		retval = mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
- 					  &dummy, data, dev->spareBuffer,
- 					  NULL);
--		}
- 	} else {
- 		if (data)
- 			retval =
- 			    mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
- 				      data);
--		if (tags)
-+		if (!dev->inbandTags && tags)
- 			retval =
- 			    mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
- 					  dev->spareBuffer);
- 	}
- #endif
- 
--	memcpy(&pt, dev->spareBuffer, sizeof(pt));
- 
--	if (tags)
--		yaffs_UnpackTags2(tags, &pt);
-+	if (dev->inbandTags) {
-+		if (tags) {
-+			yaffs_PackedTags2TagsPart *pt2tp;
-+			pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
-+			yaffs_UnpackTags2TagsPart(tags, pt2tp);
-+		}
-+	} else {
-+		if (tags) {
-+			memcpy(&pt, dev->spareBuffer, sizeof(pt));
-+			yaffs_UnpackTags2(tags, &pt);
-+		}
-+	}
-+
-+	if (localData)
-+		yaffs_ReleaseTempBuffer(dev, data, __LINE__);
- 
--	if(tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
-+	if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
- 		tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
--
- 	if (retval == 0)
- 		return YAFFS_OK;
- 	else
-@@ -178,7 +192,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaf
- 	retval =
- 	    mtd->block_markbad(mtd,
- 			       blockNo * dev->nChunksPerBlock *
--			       dev->nDataBytesPerChunk);
-+			       dev->totalBytesPerChunk);
- 
- 	if (retval == 0)
- 		return YAFFS_OK;
-@@ -188,7 +202,7 @@ int nandmtd2_MarkNANDBlockBad(struct yaf
- }
- 
- int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--			    yaffs_BlockState * state, int *sequenceNumber)
-+			    yaffs_BlockState *state, __u32 *sequenceNumber)
- {
- 	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
- 	int retval;
-@@ -198,7 +212,7 @@ int nandmtd2_QueryNANDBlock(struct yaffs
- 	retval =
- 	    mtd->block_isbad(mtd,
- 			     blockNo * dev->nChunksPerBlock *
--			     dev->nDataBytesPerChunk);
-+			     dev->totalBytesPerChunk);
- 
- 	if (retval) {
- 		T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));
---- a/fs/yaffs2/yaffs_mtdif2.h
-+++ b/fs/yaffs2/yaffs_mtdif2.h
-@@ -17,13 +17,13 @@
- #define __YAFFS_MTDIF2_H__
- 
- #include "yaffs_guts.h"
--int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND,
--				      const __u8 * data,
--				      const yaffs_ExtendedTags * tags);
--int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
--				       __u8 * data, yaffs_ExtendedTags * tags);
-+int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
-+				const __u8 *data,
-+				const yaffs_ExtendedTags *tags);
-+int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
-+				__u8 *data, yaffs_ExtendedTags *tags);
- int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
- int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--			    yaffs_BlockState * state, int *sequenceNumber);
-+			yaffs_BlockState *state, __u32 *sequenceNumber);
- 
- #endif
---- a/fs/yaffs2/yaffs_mtdif.c
-+++ b/fs/yaffs2/yaffs_mtdif.c
-@@ -12,7 +12,7 @@
-  */
- 
- const char *yaffs_mtdif_c_version =
--    "$Id: yaffs_mtdif.c,v 1.19 2007-02-14 01:09:06 wookey Exp $";
-+	"$Id: yaffs_mtdif.c,v 1.22 2009-03-06 17:20:51 wookey Exp $";
- 
- #include "yportenv.h"
- 
-@@ -24,7 +24,7 @@ const char *yaffs_mtdif_c_version =
- #include "linux/time.h"
- #include "linux/mtd/nand.h"
- 
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
-+#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 18))
- static struct nand_oobinfo yaffs_oobinfo = {
- 	.useecc = 1,
- 	.eccbytes = 6,
-@@ -36,7 +36,7 @@ static struct nand_oobinfo yaffs_noeccin
- };
- #endif
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob)
- {
- 	oob[0] = spare->tagByte0;
-@@ -45,8 +45,8 @@ static inline void translate_spare2oob(c
- 	oob[3] = spare->tagByte3;
- 	oob[4] = spare->tagByte4;
- 	oob[5] = spare->tagByte5 & 0x3f;
--	oob[5] |= spare->blockStatus == 'Y' ? 0: 0x80;
--	oob[5] |= spare->pageStatus == 0 ? 0: 0x40;
-+	oob[5] |= spare->blockStatus == 'Y' ? 0 : 0x80;
-+	oob[5] |= spare->pageStatus == 0 ? 0 : 0x40;
- 	oob[6] = spare->tagByte6;
- 	oob[7] = spare->tagByte7;
- }
-@@ -71,18 +71,18 @@ static inline void translate_oob2spare(y
- }
- #endif
- 
--int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
--			     const __u8 * data, const yaffs_Spare * spare)
-+int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
-+			     const __u8 *data, const yaffs_Spare *spare)
- {
- 	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 	struct mtd_oob_ops ops;
- #endif
- 	size_t dummy;
- 	int retval = 0;
- 
- 	loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 	__u8 spareAsBytes[8]; /* OOB */
- 
- 	if (data && !spare)
-@@ -135,18 +135,18 @@ int nandmtd_WriteChunkToNAND(yaffs_Devic
- 		return YAFFS_FAIL;
- }
- 
--int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
--			      yaffs_Spare * spare)
-+int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
-+			      yaffs_Spare *spare)
- {
- 	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 	struct mtd_oob_ops ops;
- #endif
- 	size_t dummy;
- 	int retval = 0;
- 
- 	loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
-+#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 	__u8 spareAsBytes[8]; /* OOB */
- 
- 	if (data && !spare)
-@@ -205,7 +205,7 @@ int nandmtd_ReadChunkFromNAND(yaffs_Devi
- 		return YAFFS_FAIL;
- }
- 
--int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber)
-+int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
- {
- 	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
- 	__u32 addr =
-@@ -234,7 +234,7 @@ int nandmtd_EraseBlockInNAND(yaffs_Devic
- 		return YAFFS_FAIL;
- }
- 
--int nandmtd_InitialiseNAND(yaffs_Device * dev)
-+int nandmtd_InitialiseNAND(yaffs_Device *dev)
- {
- 	return YAFFS_OK;
- }
---- a/fs/yaffs2/yaffs_mtdif.h
-+++ b/fs/yaffs2/yaffs_mtdif.h
-@@ -18,10 +18,15 @@
- 
- #include "yaffs_guts.h"
- 
--int nandmtd_WriteChunkToNAND(yaffs_Device * dev, int chunkInNAND,
--			     const __u8 * data, const yaffs_Spare * spare);
--int nandmtd_ReadChunkFromNAND(yaffs_Device * dev, int chunkInNAND, __u8 * data,
--			      yaffs_Spare * spare);
--int nandmtd_EraseBlockInNAND(yaffs_Device * dev, int blockNumber);
--int nandmtd_InitialiseNAND(yaffs_Device * dev);
-+#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 18))
-+extern struct nand_oobinfo yaffs_oobinfo;
-+extern struct nand_oobinfo yaffs_noeccinfo;
-+#endif
-+
-+int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
-+			const __u8 *data, const yaffs_Spare *spare);
-+int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
-+			yaffs_Spare *spare);
-+int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
-+int nandmtd_InitialiseNAND(yaffs_Device *dev);
- #endif
---- a/fs/yaffs2/yaffs_nand.c
-+++ b/fs/yaffs2/yaffs_nand.c
-@@ -12,16 +12,17 @@
-  */
- 
- const char *yaffs_nand_c_version =
--    "$Id: yaffs_nand.c,v 1.7 2007-02-14 01:09:06 wookey Exp $";
-+	"$Id: yaffs_nand.c,v 1.10 2009-03-06 17:20:54 wookey Exp $";
- 
- #include "yaffs_nand.h"
- #include "yaffs_tagscompat.h"
- #include "yaffs_tagsvalidity.h"
- 
-+#include "yaffs_getblockinfo.h"
- 
--int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
--					   __u8 * buffer,
--					   yaffs_ExtendedTags * tags)
-+int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
-+					   __u8 *buffer,
-+					   yaffs_ExtendedTags *tags)
- {
- 	int result;
- 	yaffs_ExtendedTags localTags;
-@@ -29,7 +30,7 @@ int yaffs_ReadChunkWithTagsFromNAND(yaff
- 	int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
- 
- 	/* If there are no tags provided, use local tags to get prioritised gc working */
--	if(!tags)
-+	if (!tags)
- 		tags = &localTags;
- 
- 	if (dev->readChunkWithTagsFromNAND)
-@@ -40,20 +41,20 @@ int yaffs_ReadChunkWithTagsFromNAND(yaff
- 									realignedChunkInNAND,
- 									buffer,
- 									tags);
--	if(tags &&
--	   tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR){
-+	if (tags &&
-+	   tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR) {
- 
- 		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
--                yaffs_HandleChunkError(dev,bi);
-+		yaffs_HandleChunkError(dev, bi);
- 	}
- 
- 	return result;
- }
- 
--int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
-+int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
- 						   int chunkInNAND,
--						   const __u8 * buffer,
--						   yaffs_ExtendedTags * tags)
-+						   const __u8 *buffer,
-+						   yaffs_ExtendedTags *tags)
- {
- 	chunkInNAND -= dev->chunkOffset;
- 
-@@ -84,7 +85,7 @@ int yaffs_WriteChunkWithTagsToNAND(yaffs
- 								       tags);
- }
- 
--int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo)
-+int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo)
- {
- 	blockNo -= dev->blockOffset;
- 
-@@ -95,10 +96,10 @@ int yaffs_MarkBlockBad(yaffs_Device * de
- 		return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
- }
- 
--int yaffs_QueryInitialBlockState(yaffs_Device * dev,
-+int yaffs_QueryInitialBlockState(yaffs_Device *dev,
- 						 int blockNo,
--						 yaffs_BlockState * state,
--						 unsigned *sequenceNumber)
-+						 yaffs_BlockState *state,
-+						 __u32 *sequenceNumber)
- {
- 	blockNo -= dev->blockOffset;
- 
---- a/fs/yaffs2/yaffs_nandemul2k.h
-+++ b/fs/yaffs2/yaffs_nandemul2k.h
-@@ -21,14 +21,14 @@
- #include "yaffs_guts.h"
- 
- int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
--					int chunkInNAND, const __u8 * data,
--					yaffs_ExtendedTags * tags);
-+					int chunkInNAND, const __u8 *data,
-+					const yaffs_ExtendedTags *tags);
- int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
--					 int chunkInNAND, __u8 * data,
--					 yaffs_ExtendedTags * tags);
-+					 int chunkInNAND, __u8 *data,
-+					 yaffs_ExtendedTags *tags);
- int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
- int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--			      yaffs_BlockState * state, int *sequenceNumber);
-+			      yaffs_BlockState *state, __u32 *sequenceNumber);
- int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
- 				int blockInNAND);
- int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev);
---- a/fs/yaffs2/yaffs_nand.h
-+++ b/fs/yaffs2/yaffs_nand.h
-@@ -19,21 +19,21 @@
- 
- 
- 
--int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND,
--					   __u8 * buffer,
--					   yaffs_ExtendedTags * tags);
--
--int yaffs_WriteChunkWithTagsToNAND(yaffs_Device * dev,
--						   int chunkInNAND,
--						   const __u8 * buffer,
--						   yaffs_ExtendedTags * tags);
--
--int yaffs_MarkBlockBad(yaffs_Device * dev, int blockNo);
--
--int yaffs_QueryInitialBlockState(yaffs_Device * dev,
--						 int blockNo,
--						 yaffs_BlockState * state,
--						 unsigned *sequenceNumber);
-+int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
-+					__u8 *buffer,
-+					yaffs_ExtendedTags *tags);
-+
-+int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
-+						int chunkInNAND,
-+						const __u8 *buffer,
-+						yaffs_ExtendedTags *tags);
-+
-+int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo);
-+
-+int yaffs_QueryInitialBlockState(yaffs_Device *dev,
-+						int blockNo,
-+						yaffs_BlockState *state,
-+						unsigned *sequenceNumber);
- 
- int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
- 				  int blockInNAND);
---- a/fs/yaffs2/yaffs_packedtags1.c
-+++ b/fs/yaffs2/yaffs_packedtags1.c
-@@ -14,7 +14,7 @@
- #include "yaffs_packedtags1.h"
- #include "yportenv.h"
- 
--void yaffs_PackTags1(yaffs_PackedTags1 * pt, const yaffs_ExtendedTags * t)
-+void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ExtendedTags *t)
- {
- 	pt->chunkId = t->chunkId;
- 	pt->serialNumber = t->serialNumber;
-@@ -27,7 +27,7 @@ void yaffs_PackTags1(yaffs_PackedTags1 *
- 
- }
- 
--void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt)
-+void yaffs_UnpackTags1(yaffs_ExtendedTags *t, const yaffs_PackedTags1 *pt)
- {
- 	static const __u8 allFF[] =
- 	    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-@@ -35,9 +35,8 @@ void yaffs_UnpackTags1(yaffs_ExtendedTag
- 
- 	if (memcmp(allFF, pt, sizeof(yaffs_PackedTags1))) {
- 		t->blockBad = 0;
--		if (pt->shouldBeFF != 0xFFFFFFFF) {
-+		if (pt->shouldBeFF != 0xFFFFFFFF)
- 			t->blockBad = 1;
--		}
- 		t->chunkUsed = 1;
- 		t->objectId = pt->objectId;
- 		t->chunkId = pt->chunkId;
-@@ -47,6 +46,5 @@ void yaffs_UnpackTags1(yaffs_ExtendedTag
- 		t->serialNumber = pt->serialNumber;
- 	} else {
- 		memset(t, 0, sizeof(yaffs_ExtendedTags));
--
- 	}
- }
---- a/fs/yaffs2/yaffs_packedtags1.h
-+++ b/fs/yaffs2/yaffs_packedtags1.h
-@@ -32,6 +32,6 @@ typedef struct {
- 
- } yaffs_PackedTags1;
- 
--void yaffs_PackTags1(yaffs_PackedTags1 * pt, const yaffs_ExtendedTags * t);
--void yaffs_UnpackTags1(yaffs_ExtendedTags * t, const yaffs_PackedTags1 * pt);
-+void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ExtendedTags *t);
-+void yaffs_UnpackTags1(yaffs_ExtendedTags *t, const yaffs_PackedTags1 *pt);
- #endif
---- a/fs/yaffs2/yaffs_packedtags2.c
-+++ b/fs/yaffs2/yaffs_packedtags2.c
-@@ -37,60 +37,68 @@
- #define EXTRA_OBJECT_TYPE_SHIFT (28)
- #define EXTRA_OBJECT_TYPE_MASK  ((0x0F) << EXTRA_OBJECT_TYPE_SHIFT)
- 
--static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 * pt)
-+
-+static void yaffs_DumpPackedTags2TagsPart(const yaffs_PackedTags2TagsPart *ptt)
- {
- 	T(YAFFS_TRACE_MTD,
- 	  (TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR),
--	   pt->t.objectId, pt->t.chunkId, pt->t.byteCount,
--	   pt->t.sequenceNumber));
-+	   ptt->objectId, ptt->chunkId, ptt->byteCount,
-+	   ptt->sequenceNumber));
-+}
-+static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 *pt)
-+{
-+	yaffs_DumpPackedTags2TagsPart(&pt->t);
- }
- 
--static void yaffs_DumpTags2(const yaffs_ExtendedTags * t)
-+static void yaffs_DumpTags2(const yaffs_ExtendedTags *t)
- {
- 	T(YAFFS_TRACE_MTD,
- 	  (TSTR
--	   ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte "
--	    "%d del %d ser %d seq %d"
-+	   ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d"
- 	    TENDSTR), t->eccResult, t->blockBad, t->chunkUsed, t->objectId,
- 	   t->chunkId, t->byteCount, t->chunkDeleted, t->serialNumber,
- 	   t->sequenceNumber));
- 
- }
- 
--void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t)
-+void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *ptt,
-+		const yaffs_ExtendedTags *t)
- {
--	pt->t.chunkId = t->chunkId;
--	pt->t.sequenceNumber = t->sequenceNumber;
--	pt->t.byteCount = t->byteCount;
--	pt->t.objectId = t->objectId;
-+	ptt->chunkId = t->chunkId;
-+	ptt->sequenceNumber = t->sequenceNumber;
-+	ptt->byteCount = t->byteCount;
-+	ptt->objectId = t->objectId;
- 
- 	if (t->chunkId == 0 && t->extraHeaderInfoAvailable) {
- 		/* Store the extra header info instead */
- 		/* We save the parent object in the chunkId */
--		pt->t.chunkId = EXTRA_HEADER_INFO_FLAG
-+		ptt->chunkId = EXTRA_HEADER_INFO_FLAG
- 			| t->extraParentObjectId;
--		if (t->extraIsShrinkHeader) {
--			pt->t.chunkId |= EXTRA_SHRINK_FLAG;
--		}
--		if (t->extraShadows) {
--			pt->t.chunkId |= EXTRA_SHADOWS_FLAG;
--		}
-+		if (t->extraIsShrinkHeader)
-+			ptt->chunkId |= EXTRA_SHRINK_FLAG;
-+		if (t->extraShadows)
-+			ptt->chunkId |= EXTRA_SHADOWS_FLAG;
- 
--		pt->t.objectId &= ~EXTRA_OBJECT_TYPE_MASK;
--		pt->t.objectId |=
-+		ptt->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
-+		ptt->objectId |=
- 		    (t->extraObjectType << EXTRA_OBJECT_TYPE_SHIFT);
- 
--		if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
--			pt->t.byteCount = t->extraEquivalentObjectId;
--		} else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE) {
--			pt->t.byteCount = t->extraFileLength;
--		} else {
--			pt->t.byteCount = 0;
--		}
-+		if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK)
-+			ptt->byteCount = t->extraEquivalentObjectId;
-+		else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE)
-+			ptt->byteCount = t->extraFileLength;
-+		else
-+			ptt->byteCount = 0;
- 	}
- 
--	yaffs_DumpPackedTags2(pt);
-+	yaffs_DumpPackedTags2TagsPart(ptt);
- 	yaffs_DumpTags2(t);
-+}
-+
-+
-+void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t)
-+{
-+	yaffs_PackTags2TagsPart(&pt->t, t);
- 
- #ifndef YAFFS_IGNORE_TAGS_ECC
- 	{
-@@ -101,82 +109,98 @@ void yaffs_PackTags2(yaffs_PackedTags2 *
- #endif
- }
- 
--void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt)
-+
-+void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags *t,
-+		yaffs_PackedTags2TagsPart *ptt)
- {
- 
- 	memset(t, 0, sizeof(yaffs_ExtendedTags));
- 
- 	yaffs_InitialiseTags(t);
- 
--	if (pt->t.sequenceNumber != 0xFFFFFFFF) {
--		/* Page is in use */
--#ifdef YAFFS_IGNORE_TAGS_ECC
--		{
--			t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
--		}
--#else
--		{
--			yaffs_ECCOther ecc;
--			int result;
--			yaffs_ECCCalculateOther((unsigned char *)&pt->t,
--						sizeof
--						(yaffs_PackedTags2TagsPart),
--						&ecc);
--			result =
--			    yaffs_ECCCorrectOther((unsigned char *)&pt->t,
--						  sizeof
--						  (yaffs_PackedTags2TagsPart),
--						  &pt->ecc, &ecc);
--			switch(result){
--				case 0:
--					t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
--					break;
--				case 1:
--					t->eccResult = YAFFS_ECC_RESULT_FIXED;
--					break;
--				case -1:
--					t->eccResult = YAFFS_ECC_RESULT_UNFIXED;
--					break;
--				default:
--					t->eccResult = YAFFS_ECC_RESULT_UNKNOWN;
--			}
--		}
--#endif
-+	if (ptt->sequenceNumber != 0xFFFFFFFF) {
- 		t->blockBad = 0;
- 		t->chunkUsed = 1;
--		t->objectId = pt->t.objectId;
--		t->chunkId = pt->t.chunkId;
--		t->byteCount = pt->t.byteCount;
-+		t->objectId = ptt->objectId;
-+		t->chunkId = ptt->chunkId;
-+		t->byteCount = ptt->byteCount;
- 		t->chunkDeleted = 0;
- 		t->serialNumber = 0;
--		t->sequenceNumber = pt->t.sequenceNumber;
-+		t->sequenceNumber = ptt->sequenceNumber;
- 
- 		/* Do extra header info stuff */
- 
--		if (pt->t.chunkId & EXTRA_HEADER_INFO_FLAG) {
-+		if (ptt->chunkId & EXTRA_HEADER_INFO_FLAG) {
- 			t->chunkId = 0;
- 			t->byteCount = 0;
- 
- 			t->extraHeaderInfoAvailable = 1;
- 			t->extraParentObjectId =
--			    pt->t.chunkId & (~(ALL_EXTRA_FLAGS));
-+			    ptt->chunkId & (~(ALL_EXTRA_FLAGS));
- 			t->extraIsShrinkHeader =
--			    (pt->t.chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
-+			    (ptt->chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
- 			t->extraShadows =
--			    (pt->t.chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
-+			    (ptt->chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
- 			t->extraObjectType =
--			    pt->t.objectId >> EXTRA_OBJECT_TYPE_SHIFT;
-+			    ptt->objectId >> EXTRA_OBJECT_TYPE_SHIFT;
- 			t->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
- 
--			if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK) {
--				t->extraEquivalentObjectId = pt->t.byteCount;
--			} else {
--				t->extraFileLength = pt->t.byteCount;
-+			if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK)
-+				t->extraEquivalentObjectId = ptt->byteCount;
-+			else
-+				t->extraFileLength = ptt->byteCount;
-+		}
-+	}
-+
-+	yaffs_DumpPackedTags2TagsPart(ptt);
-+	yaffs_DumpTags2(t);
-+
-+}
-+
-+
-+void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt)
-+{
-+
-+	yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_NO_ERROR;
-+
-+	if (pt->t.sequenceNumber != 0xFFFFFFFF) {
-+		/* Page is in use */
-+#ifndef YAFFS_IGNORE_TAGS_ECC
-+		{
-+			yaffs_ECCOther ecc;
-+			int result;
-+			yaffs_ECCCalculateOther((unsigned char *)&pt->t,
-+						sizeof
-+						(yaffs_PackedTags2TagsPart),
-+						&ecc);
-+			result =
-+			    yaffs_ECCCorrectOther((unsigned char *)&pt->t,
-+						  sizeof
-+						  (yaffs_PackedTags2TagsPart),
-+						  &pt->ecc, &ecc);
-+			switch (result) {
-+			case 0:
-+				eccResult = YAFFS_ECC_RESULT_NO_ERROR;
-+				break;
-+			case 1:
-+				eccResult = YAFFS_ECC_RESULT_FIXED;
-+				break;
-+			case -1:
-+				eccResult = YAFFS_ECC_RESULT_UNFIXED;
-+				break;
-+			default:
-+				eccResult = YAFFS_ECC_RESULT_UNKNOWN;
- 			}
- 		}
-+#endif
- 	}
- 
-+	yaffs_UnpackTags2TagsPart(t, &pt->t);
-+
-+	t->eccResult = eccResult;
-+
- 	yaffs_DumpPackedTags2(pt);
- 	yaffs_DumpTags2(t);
- 
- }
-+
---- a/fs/yaffs2/yaffs_packedtags2.h
-+++ b/fs/yaffs2/yaffs_packedtags2.h
-@@ -33,6 +33,11 @@ typedef struct {
- 	yaffs_ECCOther ecc;
- } yaffs_PackedTags2;
- 
--void yaffs_PackTags2(yaffs_PackedTags2 * pt, const yaffs_ExtendedTags * t);
--void yaffs_UnpackTags2(yaffs_ExtendedTags * t, yaffs_PackedTags2 * pt);
-+/* Full packed tags with ECC, used for oob tags */
-+void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t);
-+void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt);
-+
-+/* Only the tags part (no ECC for use with inband tags */
-+void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *pt, const yaffs_ExtendedTags *t);
-+void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags *t, yaffs_PackedTags2TagsPart *pt);
- #endif
---- a/fs/yaffs2/yaffs_qsort.c
-+++ b/fs/yaffs2/yaffs_qsort.c
-@@ -28,12 +28,12 @@
-  */
- 
- #include "yportenv.h"
--//#include <linux/string.h>
-+/* #include <linux/string.h> */
- 
- /*
-  * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
-  */
--#define swapcode(TYPE, parmi, parmj, n) { 		\
-+#define swapcode(TYPE, parmi, parmj, n) do { 		\
- 	long i = (n) / sizeof (TYPE); 			\
- 	register TYPE *pi = (TYPE *) (parmi); 		\
- 	register TYPE *pj = (TYPE *) (parmj); 		\
-@@ -41,28 +41,29 @@
- 		register TYPE	t = *pi;		\
- 		*pi++ = *pj;				\
- 		*pj++ = t;				\
--        } while (--i > 0);				\
--}
-+	} while (--i > 0);				\
-+} while (0)
- 
- #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
--	es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
-+	es % sizeof(long) ? 2 : es == sizeof(long) ? 0 : 1;
- 
- static __inline void
- swapfunc(char *a, char *b, int n, int swaptype)
- {
- 	if (swaptype <= 1)
--		swapcode(long, a, b, n)
-+		swapcode(long, a, b, n);
- 	else
--		swapcode(char, a, b, n)
-+		swapcode(char, a, b, n);
- }
- 
--#define swap(a, b)					\
-+#define yswap(a, b) do {					\
- 	if (swaptype == 0) {				\
- 		long t = *(long *)(a);			\
- 		*(long *)(a) = *(long *)(b);		\
- 		*(long *)(b) = t;			\
- 	} else						\
--		swapfunc(a, b, es, swaptype)
-+		swapfunc(a, b, es, swaptype);		\
-+} while (0)
- 
- #define vecswap(a, b, n) 	if ((n) > 0) swapfunc(a, b, n, swaptype)
- 
-@@ -70,12 +71,12 @@ static __inline char *
- med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *))
- {
- 	return cmp(a, b) < 0 ?
--	       (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
--              :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
-+		(cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a))
-+		: (cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c));
- }
- 
- #ifndef min
--#define min(a,b) (((a) < (b)) ? (a) : (b))
-+#define min(a, b) (((a) < (b)) ? (a) : (b))
- #endif
- 
- void
-@@ -92,7 +93,7 @@ loop:	SWAPINIT(a, es);
- 		for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es)
- 			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
- 			     pl -= es)
--				swap(pl, pl - es);
-+				yswap(pl, pl - es);
- 		return;
- 	}
- 	pm = (char *)a + (n / 2) * es;
-@@ -107,7 +108,7 @@ loop:	SWAPINIT(a, es);
- 		}
- 		pm = med3(pl, pm, pn, cmp);
- 	}
--	swap(a, pm);
-+	yswap(a, pm);
- 	pa = pb = (char *)a + es;
- 
- 	pc = pd = (char *)a + (n - 1) * es;
-@@ -115,7 +116,7 @@ loop:	SWAPINIT(a, es);
- 		while (pb <= pc && (r = cmp(pb, a)) <= 0) {
- 			if (r == 0) {
- 				swap_cnt = 1;
--				swap(pa, pb);
-+				yswap(pa, pb);
- 				pa += es;
- 			}
- 			pb += es;
-@@ -123,14 +124,14 @@ loop:	SWAPINIT(a, es);
- 		while (pb <= pc && (r = cmp(pc, a)) >= 0) {
- 			if (r == 0) {
- 				swap_cnt = 1;
--				swap(pc, pd);
-+				yswap(pc, pd);
- 				pd -= es;
- 			}
- 			pc -= es;
- 		}
- 		if (pb > pc)
- 			break;
--		swap(pb, pc);
-+		yswap(pb, pc);
- 		swap_cnt = 1;
- 		pb += es;
- 		pc -= es;
-@@ -139,7 +140,7 @@ loop:	SWAPINIT(a, es);
- 		for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
- 			for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
- 			     pl -= es)
--				swap(pl, pl - es);
-+				yswap(pl, pl - es);
- 		return;
- 	}
- 
-@@ -148,9 +149,11 @@ loop:	SWAPINIT(a, es);
- 	vecswap(a, pb - r, r);
- 	r = min((long)(pd - pc), (long)(pn - pd - es));
- 	vecswap(pb, pn - r, r);
--	if ((r = pb - pa) > es)
-+	r = pb - pa;
-+	if (r > es)
- 		yaffs_qsort(a, r / es, es, cmp);
--	if ((r = pd - pc) > es) {
-+	r = pd - pc;
-+	if (r > es) {
- 		/* Iterate rather than recurse to save stack space */
- 		a = pn - r;
- 		n = r / es;
---- a/fs/yaffs2/yaffs_qsort.h
-+++ b/fs/yaffs2/yaffs_qsort.h
-@@ -17,7 +17,7 @@
- #ifndef __YAFFS_QSORT_H__
- #define __YAFFS_QSORT_H__
- 
--extern void yaffs_qsort (void *const base, size_t total_elems, size_t size,
--                   int (*cmp)(const void *, const void *));
-+extern void yaffs_qsort(void *const base, size_t total_elems, size_t size,
-+			int (*cmp)(const void *, const void *));
- 
- #endif
---- a/fs/yaffs2/yaffs_tagscompat.c
-+++ b/fs/yaffs2/yaffs_tagscompat.c
-@@ -14,16 +14,17 @@
- #include "yaffs_guts.h"
- #include "yaffs_tagscompat.h"
- #include "yaffs_ecc.h"
-+#include "yaffs_getblockinfo.h"
- 
--static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND);
-+static void yaffs_HandleReadDataError(yaffs_Device *dev, int chunkInNAND);
- #ifdef NOTYET
--static void yaffs_CheckWrittenBlock(yaffs_Device * dev, int chunkInNAND);
--static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
--				     const __u8 * data,
--				     const yaffs_Spare * spare);
--static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
--				    const yaffs_Spare * spare);
--static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND);
-+static void yaffs_CheckWrittenBlock(yaffs_Device *dev, int chunkInNAND);
-+static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
-+				     const __u8 *data,
-+				     const yaffs_Spare *spare);
-+static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
-+				    const yaffs_Spare *spare);
-+static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND);
- #endif
- 
- static const char yaffs_countBitsTable[256] = {
-@@ -54,13 +55,13 @@ int yaffs_CountBits(__u8 x)
- 
- /********** Tags ECC calculations  *********/
- 
--void yaffs_CalcECC(const __u8 * data, yaffs_Spare * spare)
-+void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
- {
- 	yaffs_ECCCalculate(data, spare->ecc1);
- 	yaffs_ECCCalculate(&data[256], spare->ecc2);
- }
- 
--void yaffs_CalcTagsECC(yaffs_Tags * tags)
-+void yaffs_CalcTagsECC(yaffs_Tags *tags)
- {
- 	/* Calculate an ecc */
- 
-@@ -74,9 +75,8 @@ void yaffs_CalcTagsECC(yaffs_Tags * tags
- 	for (i = 0; i < 8; i++) {
- 		for (j = 1; j & 0xff; j <<= 1) {
- 			bit++;
--			if (b[i] & j) {
-+			if (b[i] & j)
- 				ecc ^= bit;
--			}
- 		}
- 	}
- 
-@@ -84,7 +84,7 @@ void yaffs_CalcTagsECC(yaffs_Tags * tags
- 
- }
- 
--int yaffs_CheckECCOnTags(yaffs_Tags * tags)
-+int yaffs_CheckECCOnTags(yaffs_Tags *tags)
- {
- 	unsigned ecc = tags->ecc;
- 
-@@ -115,8 +115,8 @@ int yaffs_CheckECCOnTags(yaffs_Tags * ta
- 
- /********** Tags **********/
- 
--static void yaffs_LoadTagsIntoSpare(yaffs_Spare * sparePtr,
--				    yaffs_Tags * tagsPtr)
-+static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr,
-+				yaffs_Tags *tagsPtr)
- {
- 	yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr;
- 
-@@ -132,8 +132,8 @@ static void yaffs_LoadTagsIntoSpare(yaff
- 	sparePtr->tagByte7 = tu->asBytes[7];
- }
- 
--static void yaffs_GetTagsFromSpare(yaffs_Device * dev, yaffs_Spare * sparePtr,
--				   yaffs_Tags * tagsPtr)
-+static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,
-+				yaffs_Tags *tagsPtr)
- {
- 	yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr;
- 	int result;
-@@ -148,21 +148,20 @@ static void yaffs_GetTagsFromSpare(yaffs
- 	tu->asBytes[7] = sparePtr->tagByte7;
- 
- 	result = yaffs_CheckECCOnTags(tagsPtr);
--	if (result > 0) {
-+	if (result > 0)
- 		dev->tagsEccFixed++;
--	} else if (result < 0) {
-+	else if (result < 0)
- 		dev->tagsEccUnfixed++;
--	}
- }
- 
--static void yaffs_SpareInitialise(yaffs_Spare * spare)
-+static void yaffs_SpareInitialise(yaffs_Spare *spare)
- {
- 	memset(spare, 0xFF, sizeof(yaffs_Spare));
- }
- 
- static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,
--				  int chunkInNAND, const __u8 * data,
--				  yaffs_Spare * spare)
-+				int chunkInNAND, const __u8 *data,
-+				yaffs_Spare *spare)
- {
- 	if (chunkInNAND < dev->startBlock * dev->nChunksPerBlock) {
- 		T(YAFFS_TRACE_ERROR,
-@@ -177,9 +176,9 @@ static int yaffs_WriteChunkToNAND(struct
- 
- static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
- 				   int chunkInNAND,
--				   __u8 * data,
--				   yaffs_Spare * spare,
--				   yaffs_ECCResult * eccResult,
-+				   __u8 *data,
-+				   yaffs_Spare *spare,
-+				   yaffs_ECCResult *eccResult,
- 				   int doErrorCorrection)
- {
- 	int retVal;
-@@ -252,9 +251,11 @@ static int yaffs_ReadChunkFromNAND(struc
- 		/* Must allocate enough memory for spare+2*sizeof(int) */
- 		/* for ecc results from device. */
- 		struct yaffs_NANDSpare nspare;
--		retVal =
--		    dev->readChunkFromNAND(dev, chunkInNAND, data,
--					   (yaffs_Spare *) & nspare);
-+
-+		memset(&nspare, 0, sizeof(nspare));
-+
-+		retVal = dev->readChunkFromNAND(dev, chunkInNAND, data,
-+					(yaffs_Spare *) &nspare);
- 		memcpy(spare, &nspare, sizeof(yaffs_Spare));
- 		if (data && doErrorCorrection) {
- 			if (nspare.eccres1 > 0) {
-@@ -302,8 +303,7 @@ static int yaffs_ReadChunkFromNAND(struc
- static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
- 				  int chunkInNAND)
- {
--
--	static int init = 0;
-+	static int init;
- 	static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK];
- 	static __u8 data[YAFFS_BYTES_PER_CHUNK];
- 	/* Might as well always allocate the larger size for */
-@@ -331,12 +331,12 @@ static int yaffs_CheckChunkErased(struct
-  * Functions for robustisizing
-  */
- 
--static void yaffs_HandleReadDataError(yaffs_Device * dev, int chunkInNAND)
-+static void yaffs_HandleReadDataError(yaffs_Device *dev, int chunkInNAND)
- {
- 	int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
- 
- 	/* Mark the block for retirement */
--	yaffs_GetBlockInfo(dev, blockInNAND)->needsRetiring = 1;
-+	yaffs_GetBlockInfo(dev, blockInNAND + dev->blockOffset)->needsRetiring = 1;
- 	T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
- 	  (TSTR("**>>Block %d marked for retirement" TENDSTR), blockInNAND));
- 
-@@ -348,22 +348,22 @@ static void yaffs_HandleReadDataError(ya
- }
- 
- #ifdef NOTYET
--static void yaffs_CheckWrittenBlock(yaffs_Device * dev, int chunkInNAND)
-+static void yaffs_CheckWrittenBlock(yaffs_Device *dev, int chunkInNAND)
- {
- }
- 
--static void yaffs_HandleWriteChunkOk(yaffs_Device * dev, int chunkInNAND,
--				     const __u8 * data,
--				     const yaffs_Spare * spare)
-+static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
-+				     const __u8 *data,
-+				     const yaffs_Spare *spare)
- {
- }
- 
--static void yaffs_HandleUpdateChunk(yaffs_Device * dev, int chunkInNAND,
--				    const yaffs_Spare * spare)
-+static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
-+				    const yaffs_Spare *spare)
- {
- }
- 
--static void yaffs_HandleWriteChunkError(yaffs_Device * dev, int chunkInNAND)
-+static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND)
- {
- 	int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
- 
-@@ -373,8 +373,8 @@ static void yaffs_HandleWriteChunkError(
- 	yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
- }
- 
--static int yaffs_VerifyCompare(const __u8 * d0, const __u8 * d1,
--			       const yaffs_Spare * s0, const yaffs_Spare * s1)
-+static int yaffs_VerifyCompare(const __u8 *d0, const __u8 *d1,
-+			       const yaffs_Spare *s0, const yaffs_Spare *s1)
- {
- 
- 	if (memcmp(d0, d1, YAFFS_BYTES_PER_CHUNK) != 0 ||
-@@ -398,28 +398,35 @@ static int yaffs_VerifyCompare(const __u
- }
- #endif				/* NOTYET */
- 
--int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device * dev,
--						    int chunkInNAND,
--						    const __u8 * data,
--						    const yaffs_ExtendedTags *
--						    eTags)
-+int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
-+						int chunkInNAND,
-+						const __u8 *data,
-+						const yaffs_ExtendedTags *eTags)
- {
- 	yaffs_Spare spare;
- 	yaffs_Tags tags;
- 
- 	yaffs_SpareInitialise(&spare);
- 
--	if (eTags->chunkDeleted) {
-+	if (eTags->chunkDeleted)
- 		spare.pageStatus = 0;
--	} else {
-+	else {
- 		tags.objectId = eTags->objectId;
- 		tags.chunkId = eTags->chunkId;
--		tags.byteCount = eTags->byteCount;
-+
-+		tags.byteCountLSB = eTags->byteCount & 0x3ff;
-+
-+		if (dev->nDataBytesPerChunk >= 1024)
-+			tags.byteCountMSB = (eTags->byteCount >> 10) & 3;
-+		else
-+			tags.byteCountMSB = 3;
-+
-+
- 		tags.serialNumber = eTags->serialNumber;
- 
--		if (!dev->useNANDECC && data) {
-+		if (!dev->useNANDECC && data)
- 			yaffs_CalcECC(data, &spare);
--		}
-+
- 		yaffs_LoadTagsIntoSpare(&spare, &tags);
- 
- 	}
-@@ -427,15 +434,15 @@ int yaffs_TagsCompatabilityWriteChunkWit
- 	return yaffs_WriteChunkToNAND(dev, chunkInNAND, data, &spare);
- }
- 
--int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
-+int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,
- 						     int chunkInNAND,
--						     __u8 * data,
--						     yaffs_ExtendedTags * eTags)
-+						     __u8 *data,
-+						     yaffs_ExtendedTags *eTags)
- {
- 
- 	yaffs_Spare spare;
- 	yaffs_Tags tags;
--	yaffs_ECCResult eccResult;
-+	yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_UNKNOWN;
- 
- 	static yaffs_Spare spareFF;
- 	static int init;
-@@ -466,7 +473,11 @@ int yaffs_TagsCompatabilityReadChunkWith
- 
- 				eTags->objectId = tags.objectId;
- 				eTags->chunkId = tags.chunkId;
--				eTags->byteCount = tags.byteCount;
-+				eTags->byteCount = tags.byteCountLSB;
-+
-+				if (dev->nDataBytesPerChunk >= 1024)
-+					eTags->byteCount |= (((unsigned) tags.byteCountMSB) << 10);
-+
- 				eTags->serialNumber = tags.serialNumber;
- 			}
- 		}
-@@ -497,9 +508,9 @@ int yaffs_TagsCompatabilityMarkNANDBlock
- }
- 
- int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
--					  int blockNo, yaffs_BlockState *
--					  state,
--					  int *sequenceNumber)
-+					  int blockNo,
-+					  yaffs_BlockState *state,
-+					  __u32 *sequenceNumber)
- {
- 
- 	yaffs_Spare spare0, spare1;
---- a/fs/yaffs2/yaffs_tagscompat.h
-+++ b/fs/yaffs2/yaffs_tagscompat.h
-@@ -17,24 +17,23 @@
- #define __YAFFS_TAGSCOMPAT_H__
- 
- #include "yaffs_guts.h"
--int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device * dev,
--						    int chunkInNAND,
--						    const __u8 * data,
--						    const yaffs_ExtendedTags *
--						    tags);
--int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device * dev,
--						     int chunkInNAND,
--						     __u8 * data,
--						     yaffs_ExtendedTags *
--						     tags);
-+int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
-+						int chunkInNAND,
-+						const __u8 *data,
-+						const yaffs_ExtendedTags *tags);
-+int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,
-+						int chunkInNAND,
-+						__u8 *data,
-+						yaffs_ExtendedTags *tags);
- int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
- 					    int blockNo);
- int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
--					  int blockNo, yaffs_BlockState *
--					  state, int *sequenceNumber);
-+					  int blockNo,
-+					  yaffs_BlockState *state,
-+					  __u32 *sequenceNumber);
- 
--void yaffs_CalcTagsECC(yaffs_Tags * tags);
--int yaffs_CheckECCOnTags(yaffs_Tags * tags);
-+void yaffs_CalcTagsECC(yaffs_Tags *tags);
-+int yaffs_CheckECCOnTags(yaffs_Tags *tags);
- int yaffs_CountBits(__u8 byte);
- 
- #endif
---- a/fs/yaffs2/yaffs_tagsvalidity.c
-+++ b/fs/yaffs2/yaffs_tagsvalidity.c
-@@ -13,14 +13,14 @@
- 
- #include "yaffs_tagsvalidity.h"
- 
--void yaffs_InitialiseTags(yaffs_ExtendedTags * tags)
-+void yaffs_InitialiseTags(yaffs_ExtendedTags *tags)
- {
- 	memset(tags, 0, sizeof(yaffs_ExtendedTags));
- 	tags->validMarker0 = 0xAAAAAAAA;
- 	tags->validMarker1 = 0x55555555;
- }
- 
--int yaffs_ValidateTags(yaffs_ExtendedTags * tags)
-+int yaffs_ValidateTags(yaffs_ExtendedTags *tags)
- {
- 	return (tags->validMarker0 == 0xAAAAAAAA &&
- 		tags->validMarker1 == 0x55555555);
---- a/fs/yaffs2/yaffs_tagsvalidity.h
-+++ b/fs/yaffs2/yaffs_tagsvalidity.h
-@@ -19,6 +19,6 @@
- 
- #include "yaffs_guts.h"
- 
--void yaffs_InitialiseTags(yaffs_ExtendedTags * tags);
--int yaffs_ValidateTags(yaffs_ExtendedTags * tags);
-+void yaffs_InitialiseTags(yaffs_ExtendedTags *tags);
-+int yaffs_ValidateTags(yaffs_ExtendedTags *tags);
- #endif
---- a/fs/yaffs2/yportenv.h
-+++ b/fs/yaffs2/yportenv.h
-@@ -17,17 +17,28 @@
- #ifndef __YPORTENV_H__
- #define __YPORTENV_H__
- 
-+/*
-+ * Define the MTD version in terms of Linux Kernel versions
-+ * This allows yaffs to be used independantly of the kernel
-+ * as well as with it.
-+ */
-+
-+#define MTD_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-+
- #if defined CONFIG_YAFFS_WINCE
- 
- #include "ywinceenv.h"
- 
--#elif  defined __KERNEL__
-+#elif defined __KERNEL__
- 
- #include "moduleconfig.h"
- 
- /* Linux kernel */
-+
- #include <linux/version.h>
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
-+#define MTD_VERSION_CODE LINUX_VERSION_CODE
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
- #include <linux/config.h>
- #endif
- #include <linux/kernel.h>
-@@ -40,12 +51,13 @@
- #define YCHAR char
- #define YUCHAR unsigned char
- #define _Y(x)     x
--#define yaffs_strcpy(a,b)    strcpy(a,b)
--#define yaffs_strncpy(a,b,c) strncpy(a,b,c)
--#define yaffs_strncmp(a,b,c) strncmp(a,b,c)
--#define yaffs_strlen(s)	     strlen(s)
--#define yaffs_sprintf	     sprintf
--#define yaffs_toupper(a)     toupper(a)
-+#define yaffs_strcat(a, b)     strcat(a, b)
-+#define yaffs_strcpy(a, b)     strcpy(a, b)
-+#define yaffs_strncpy(a, b, c) strncpy(a, b, c)
-+#define yaffs_strncmp(a, b, c) strncmp(a, b, c)
-+#define yaffs_strlen(s)	       strlen(s)
-+#define yaffs_sprintf	       sprintf
-+#define yaffs_toupper(a)       toupper(a)
- 
- #define Y_INLINE inline
- 
-@@ -53,19 +65,19 @@
- #define YAFFS_LOSTNFOUND_PREFIX		"obj"
- 
- /* #define YPRINTF(x) printk x */
--#define YMALLOC(x) kmalloc(x,GFP_KERNEL)
-+#define YMALLOC(x) kmalloc(x, GFP_NOFS)
- #define YFREE(x)   kfree(x)
- #define YMALLOC_ALT(x) vmalloc(x)
- #define YFREE_ALT(x)   vfree(x)
- #define YMALLOC_DMA(x) YMALLOC(x)
- 
--// KR - added for use in scan so processes aren't blocked indefinitely.
-+/* KR - added for use in scan so processes aren't blocked indefinitely. */
- #define YYIELD() schedule()
- 
- #define YAFFS_ROOT_MODE			0666
- #define YAFFS_LOSTNFOUND_MODE		0666
- 
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- #define Y_CURRENT_TIME CURRENT_TIME.tv_sec
- #define Y_TIME_CONVERT(x) (x).tv_sec
- #else
-@@ -73,11 +85,12 @@
- #define Y_TIME_CONVERT(x) (x)
- #endif
- 
--#define yaffs_SumCompare(x,y) ((x) == (y))
--#define yaffs_strcmp(a,b) strcmp(a,b)
-+#define yaffs_SumCompare(x, y) ((x) == (y))
-+#define yaffs_strcmp(a, b) strcmp(a, b)
- 
- #define TENDSTR "\n"
- #define TSTR(x) KERN_WARNING x
-+#define TCONT(x) x
- #define TOUT(p) printk p
- 
- #define yaffs_trace(mask, fmt, args...) \
-@@ -90,6 +103,8 @@
- 
- #elif defined CONFIG_YAFFS_DIRECT
- 
-+#define MTD_VERSION_CODE MTD_VERSION(2, 6, 22)
-+
- /* Direct interface */
- #include "ydirectenv.h"
- 
-@@ -111,11 +126,12 @@
- #define YCHAR char
- #define YUCHAR unsigned char
- #define _Y(x)     x
--#define yaffs_strcpy(a,b)    strcpy(a,b)
--#define yaffs_strncpy(a,b,c) strncpy(a,b,c)
--#define yaffs_strlen(s)	     strlen(s)
--#define yaffs_sprintf	     sprintf
--#define yaffs_toupper(a)     toupper(a)
-+#define yaffs_strcat(a, b)     strcat(a, b)
-+#define yaffs_strcpy(a, b)     strcpy(a, b)
-+#define yaffs_strncpy(a, b, c) strncpy(a, b, c)
-+#define yaffs_strlen(s)	       strlen(s)
-+#define yaffs_sprintf	       sprintf
-+#define yaffs_toupper(a)       toupper(a)
- 
- #define Y_INLINE inline
- 
-@@ -133,8 +149,8 @@
- #define YAFFS_ROOT_MODE				0666
- #define YAFFS_LOSTNFOUND_MODE		0666
- 
--#define yaffs_SumCompare(x,y) ((x) == (y))
--#define yaffs_strcmp(a,b) strcmp(a,b)
-+#define yaffs_SumCompare(x, y) ((x) == (y))
-+#define yaffs_strcmp(a, b) strcmp(a, b)
- 
- #else
- /* Should have specified a configuration type */
-@@ -178,10 +194,10 @@ extern unsigned int yaffs_wr_attempts;
- #define YAFFS_TRACE_ALWAYS		0xF0000000
- 
- 
--#define T(mask,p) do{ if((mask) & (yaffs_traceMask | YAFFS_TRACE_ALWAYS)) TOUT(p);} while(0)
-+#define T(mask, p) do { if ((mask) & (yaffs_traceMask | YAFFS_TRACE_ALWAYS)) TOUT(p); } while (0)
- 
--#ifndef CONFIG_YAFFS_WINCE
--#define YBUG() T(YAFFS_TRACE_BUG,(TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR),__LINE__))
-+#ifndef YBUG
-+#define YBUG() do {T(YAFFS_TRACE_BUG, (TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR), __LINE__)); } while (0)
- #endif
- 
- #endif
diff --git a/target/linux/generic/patches-2.6.38/502-yaffs_git_2010_10_20.patch b/target/linux/generic/patches-2.6.38/502-yaffs_git_2010_10_20.patch
deleted file mode 100644
index c9f1eadb10..0000000000
--- a/target/linux/generic/patches-2.6.38/502-yaffs_git_2010_10_20.patch
+++ /dev/null
@@ -1,27068 +0,0 @@
---- a/fs/Kconfig
-+++ b/fs/Kconfig
-@@ -35,7 +35,6 @@ source "fs/gfs2/Kconfig"
- source "fs/ocfs2/Kconfig"
- source "fs/btrfs/Kconfig"
- source "fs/nilfs2/Kconfig"
--source "fs/yaffs2/Kconfig"
- 
- endif # BLOCK
- 
-@@ -177,6 +176,10 @@ source "fs/hfsplus/Kconfig"
- source "fs/befs/Kconfig"
- source "fs/bfs/Kconfig"
- source "fs/efs/Kconfig"
-+
-+# Patched by YAFFS
-+source "fs/yaffs2/Kconfig"
-+
- source "fs/jffs2/Kconfig"
- # UBIFS File system configuration
- source "fs/ubifs/Kconfig"
---- a/fs/Makefile
-+++ b/fs/Makefile
-@@ -122,5 +122,6 @@ obj-$(CONFIG_BTRFS_FS)		+= btrfs/
- obj-$(CONFIG_GFS2_FS)           += gfs2/
- obj-$(CONFIG_EXOFS_FS)          += exofs/
- obj-$(CONFIG_CEPH_FS)		+= ceph/
--obj-$(CONFIG_YAFFS_FS)		+= yaffs2/
- 
-+# Patched by YAFFS
-+obj-$(CONFIG_YAFFS_FS)		+= yaffs2/
---- a/fs/yaffs2/devextras.h
-+++ b/fs/yaffs2/devextras.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -24,6 +24,8 @@
- #define __EXTRAS_H__
- 
- 
-+#include "yportenv.h"
-+
- #if !(defined __KERNEL__)
- 
- /* Definition of types */
-@@ -33,103 +35,6 @@ typedef unsigned __u32;
- 
- #endif
- 
--/*
-- * This is a simple doubly linked list implementation that matches the
-- * way the Linux kernel doubly linked list implementation works.
-- */
--
--struct ylist_head {
--	struct ylist_head *next; /* next in chain */
--	struct ylist_head *prev; /* previous in chain */
--};
--
--
--/* Initialise a static list */
--#define YLIST_HEAD(name) \
--struct ylist_head name = { &(name), &(name)}
--
--
--
--/* Initialise a list head to an empty list */
--#define YINIT_LIST_HEAD(p) \
--do { \
--	(p)->next = (p);\
--	(p)->prev = (p); \
--} while (0)
--
--
--/* Add an element to a list */
--static __inline__ void ylist_add(struct ylist_head *newEntry,
--				struct ylist_head *list)
--{
--	struct ylist_head *listNext = list->next;
--
--	list->next = newEntry;
--	newEntry->prev = list;
--	newEntry->next = listNext;
--	listNext->prev = newEntry;
--
--}
--
--static __inline__ void ylist_add_tail(struct ylist_head *newEntry,
--				 struct ylist_head *list)
--{
--	struct ylist_head *listPrev = list->prev;
--
--	list->prev = newEntry;
--	newEntry->next = list;
--	newEntry->prev = listPrev;
--	listPrev->next = newEntry;
--
--}
--
--
--/* Take an element out of its current list, with or without
-- * reinitialising the links.of the entry*/
--static __inline__ void ylist_del(struct ylist_head *entry)
--{
--	struct ylist_head *listNext = entry->next;
--	struct ylist_head *listPrev = entry->prev;
--
--	listNext->prev = listPrev;
--	listPrev->next = listNext;
--
--}
--
--static __inline__ void ylist_del_init(struct ylist_head *entry)
--{
--	ylist_del(entry);
--	entry->next = entry->prev = entry;
--}
--
--
--/* Test if the list is empty */
--static __inline__ int ylist_empty(struct ylist_head *entry)
--{
--	return (entry->next == entry);
--}
--
--
--/* ylist_entry takes a pointer to a list entry and offsets it to that
-- * we can find a pointer to the object it is embedded in.
-- */
--
--
--#define ylist_entry(entry, type, member) \
--	((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))
--
--
--/* ylist_for_each and list_for_each_safe  iterate over lists.
-- * ylist_for_each_safe uses temporary storage to make the list delete safe
-- */
--
--#define ylist_for_each(itervar, list) \
--	for (itervar = (list)->next; itervar != (list); itervar = itervar->next)
--
--#define ylist_for_each_safe(itervar, saveVar, list) \
--	for (itervar = (list)->next, saveVar = (list)->next->next; \
--		itervar != (list); itervar = saveVar, saveVar = saveVar->next)
--
- 
- #if !(defined __KERNEL__)
- 
---- a/fs/yaffs2/Kconfig
-+++ b/fs/yaffs2/Kconfig
-@@ -90,23 +90,15 @@ config YAFFS_AUTO_YAFFS2
- 
- 	  If unsure, say Y.
- 
--config YAFFS_DISABLE_LAZY_LOAD
--	bool "Disable lazy loading"
--	depends on YAFFS_YAFFS2
-+config YAFFS_DISABLE_TAGS_ECC
-+	bool "Disable YAFFS from doing ECC on tags by default"
-+	depends on YAFFS_FS && YAFFS_YAFFS2
- 	default n
- 	help
--	  "Lazy loading" defers loading file details until they are
--	  required. This saves mount time, but makes the first look-up
--	  a bit longer.
--
--	  Lazy loading will only happen if enabled by this option being 'n'
--	  and if the appropriate tags are available, else yaffs2 will
--	  automatically fall back to immediate loading and do the right
--	  thing.
--
--	  Lazy laoding will be required by checkpointing.
--
--	  Setting this to 'y' will disable lazy loading.
-+	  This defaults Yaffs to using its own ECC calculations on tags instead of
-+	  just relying on the MTD.
-+	  This behavior can also be overridden with tags_ecc_on and
-+	  tags_ecc_off mount options.
- 
- 	  If unsure, say N.
- 
-@@ -154,3 +146,45 @@ config YAFFS_SHORT_NAMES_IN_RAM
- 	  but makes look-ups faster.
- 
- 	  If unsure, say Y.
-+
-+config YAFFS_EMPTY_LOST_AND_FOUND
-+	bool "Empty lost and found on boot"
-+	depends on YAFFS_FS
-+	default n
-+	help
-+	  If this is enabled then the contents of lost and found is
-+	  automatically dumped at mount.
-+
-+	  If unsure, say N.
-+
-+config YAFFS_DISABLE_BLOCK_REFRESHING
-+	bool "Disable yaffs2 block refreshing"
-+	depends on YAFFS_FS
-+	default n
-+	help
-+	 If this is set, then block refreshing is disabled.
-+	 Block refreshing infrequently refreshes the oldest block in
-+	 a yaffs2 file system. This mechanism helps to refresh flash to
-+	 mitigate against data loss. This is particularly useful for MLC.
-+
-+	  If unsure, say N.
-+
-+config YAFFS_DISABLE_BACKGROUND
-+	bool "Disable yaffs2 background processing"
-+	depends on YAFFS_FS
-+	default n
-+	help
-+	 If this is set, then background processing is disabled.
-+	 Background processing makes many foreground activities faster.
-+
-+	  If unsure, say N.
-+
-+config YAFFS_XATTR
-+	bool "Enable yaffs2 xattr support"
-+	depends on YAFFS_FS
-+	default y
-+	help
-+	 If this is set then yaffs2 will provide xattr support.
-+	 If unsure, say Y.
-+
-+
---- a/fs/yaffs2/Makefile
-+++ b/fs/yaffs2/Makefile
-@@ -4,7 +4,14 @@
- 
- obj-$(CONFIG_YAFFS_FS) += yaffs.o
- 
--yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
--yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
-+yaffs-y := yaffs_ecc.o yaffs_vfs_glue.o yaffs_guts.o yaffs_checkptrw.o
-+yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o
- yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
- yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
-+yaffs-y += yaffs_nameval.o
-+yaffs-y += yaffs_allocator.o
-+yaffs-y += yaffs_yaffs1.o
-+yaffs-y += yaffs_yaffs2.o
-+yaffs-y += yaffs_bitmap.o
-+yaffs-y += yaffs_verify.o
-+
---- a/fs/yaffs2/moduleconfig.h
-+++ b/fs/yaffs2/moduleconfig.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Martin Fouts <Martin.Fouts@palmsource.com>
-@@ -29,25 +29,46 @@
- /* Meaning: Yaffs does its own ECC, rather than using MTD ECC */
- /* #define CONFIG_YAFFS_DOES_ECC */
- 
-+/* Default: Selected */
-+/* Meaning: Yaffs does its own ECC on tags for packed tags rather than use mtd */
-+#define CONFIG_YAFFS_DOES_TAGS_ECC
-+
- /* Default: Not selected */
- /* Meaning: ECC byte order is 'wrong'.  Only meaningful if */
- /*          CONFIG_YAFFS_DOES_ECC is set */
- /* #define CONFIG_YAFFS_ECC_WRONG_ORDER */
- 
--/* Default: Selected */
--/* Meaning: Disables testing whether chunks are erased before writing to them*/
--#define CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK
-+/* Default: Not selected */
-+/* Meaning: Always test whether chunks are erased before writing to them.
-+	    Use during mtd debugging and init. */
-+/* #define CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED */
-+
-+/* Default: Not Selected */
-+/* Meaning: At mount automatically empty all files from lost and found. */
-+/* This is done to fix an old problem where rmdir was not checking for an */
-+/* empty directory. This can also be achieved with a mount option. */
-+#define CONFIG_YAFFS_EMPTY_LOST_AND_FOUND
- 
- /* Default: Selected */
- /* Meaning: Cache short names, taking more RAM, but faster look-ups */
- #define CONFIG_YAFFS_SHORT_NAMES_IN_RAM
- 
--/* Default: 10 */
--/* Meaning: set the count of blocks to reserve for checkpointing */
--#define CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS 10
-+/* Default: Unselected */
-+/* Meaning: Select to disable block refreshing. */
-+/* Block Refreshing periodically rewrites the oldest block. */
-+/* #define CONFIG_DISABLE_BLOCK_REFRESHING */
-+
-+/* Default: Unselected */
-+/* Meaning: Select to disable background processing */
-+/* #define CONFIG_DISABLE_BACKGROUND */
-+
-+
-+/* Default: Selected */
-+/* Meaning: Enable XATTR support */
-+#define CONFIG_YAFFS_XATTR
- 
- /*
--Older-style on-NAND data format has a "pageStatus" byte to record
-+Older-style on-NAND data format has a "page_status" byte to record
- chunk/page state.  This byte is zeroed when the page is discarded.
- Choose this option if you have existing on-NAND data in this format
- that you need to continue to support.  New data written also uses the
-@@ -57,7 +78,7 @@ adjusted to use the older-style format.
- MTD versions in yaffs_mtdif1.c.
- */
- /* Default: Not selected */
--/* Meaning: Use older-style on-NAND data format with pageStatus byte */
-+/* Meaning: Use older-style on-NAND data format with page_status byte */
- /* #define CONFIG_YAFFS_9BYTE_TAGS */
- 
- #endif /* YAFFS_OUT_OF_TREE */
---- /dev/null
-+++ b/fs/yaffs2/yaffs_allocator.c
-@@ -0,0 +1,409 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+
-+#include "yaffs_allocator.h"
-+#include "yaffs_guts.h"
-+#include "yaffs_trace.h"
-+#include "yportenv.h"
-+
-+#ifdef CONFIG_YAFFS_YMALLOC_ALLOCATOR
-+
-+void yaffs_deinit_raw_tnodes_and_objs(yaffs_dev_t *dev)
-+{
-+	dev = dev;
-+}
-+
-+void yaffs_init_raw_tnodes_and_objs(yaffs_dev_t *dev)
-+{
-+	dev = dev;
-+}
-+
-+yaffs_tnode_t *yaffs_alloc_raw_tnode(yaffs_dev_t *dev)
-+{
-+	return (yaffs_tnode_t *)YMALLOC(dev->tnode_size);
-+}
-+
-+void yaffs_free_raw_tnode(yaffs_dev_t *dev, yaffs_tnode_t *tn)
-+{
-+	dev = dev;
-+	YFREE(tn);
-+}
-+
-+void yaffs_init_raw_objs(yaffs_dev_t *dev)
-+{
-+	dev = dev;
-+}
-+
-+void yaffs_deinit_raw_objs(yaffs_dev_t *dev)
-+{
-+	dev = dev;
-+}
-+
-+yaffs_obj_t *yaffs_alloc_raw_obj(yaffs_dev_t *dev)
-+{
-+	dev = dev;
-+	return (yaffs_obj_t *) YMALLOC(sizeof(yaffs_obj_t));
-+}
-+
-+
-+void yaffs_free_raw_obj(yaffs_dev_t *dev, yaffs_obj_t *obj)
-+{
-+
-+	dev = dev;
-+	YFREE(obj);
-+}
-+
-+#else
-+
-+struct yaffs_tnode_list {
-+	struct yaffs_tnode_list *next;
-+	yaffs_tnode_t *tnodes;
-+};
-+
-+typedef struct yaffs_tnode_list yaffs_tnodelist_t;
-+
-+struct yaffs_obj_tList_struct {
-+	yaffs_obj_t *objects;
-+	struct yaffs_obj_tList_struct *next;
-+};
-+
-+typedef struct yaffs_obj_tList_struct yaffs_obj_tList;
-+
-+
-+struct yaffs_AllocatorStruct {
-+	int n_tnodesCreated;
-+	yaffs_tnode_t *freeTnodes;
-+	int nFreeTnodes;
-+	yaffs_tnodelist_t *allocatedTnodeList;
-+
-+	int n_objCreated;
-+	yaffs_obj_t *freeObjects;
-+	int nFreeObjects;
-+
-+	yaffs_obj_tList *allocatedObjectList;
-+};
-+
-+typedef struct yaffs_AllocatorStruct yaffs_Allocator;
-+
-+
-+static void yaffs_deinit_raw_tnodes(yaffs_dev_t *dev)
-+{
-+
-+	yaffs_Allocator *allocator = (yaffs_Allocator *)dev->allocator;
-+
-+	yaffs_tnodelist_t *tmp;
-+
-+	if(!allocator){
-+		YBUG();
-+		return;
-+	}
-+
-+	while (allocator->allocatedTnodeList) {
-+		tmp = allocator->allocatedTnodeList->next;
-+
-+		YFREE(allocator->allocatedTnodeList->tnodes);
-+		YFREE(allocator->allocatedTnodeList);
-+		allocator->allocatedTnodeList = tmp;
-+
-+	}
-+
-+	allocator->freeTnodes = NULL;
-+	allocator->nFreeTnodes = 0;
-+	allocator->n_tnodesCreated = 0;
-+}
-+
-+static void yaffs_init_raw_tnodes(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+
-+	if(allocator){
-+		allocator->allocatedTnodeList = NULL;
-+		allocator->freeTnodes = NULL;
-+		allocator->nFreeTnodes = 0;
-+		allocator->n_tnodesCreated = 0;
-+	} else
-+		YBUG();
-+}
-+
-+static int yaffs_create_tnodes(yaffs_dev_t *dev, int n_tnodes)
-+{
-+	yaffs_Allocator *allocator = (yaffs_Allocator *)dev->allocator;
-+	int i;
-+	yaffs_tnode_t *newTnodes;
-+	__u8 *mem;
-+	yaffs_tnode_t *curr;
-+	yaffs_tnode_t *next;
-+	yaffs_tnodelist_t *tnl;
-+
-+	if(!allocator){
-+		YBUG();
-+		return YAFFS_FAIL;
-+	}
-+
-+	if (n_tnodes < 1)
-+		return YAFFS_OK;
-+
-+
-+	/* make these things */
-+
-+	newTnodes = YMALLOC(n_tnodes * dev->tnode_size);
-+	mem = (__u8 *)newTnodes;
-+
-+	if (!newTnodes) {
-+		T(YAFFS_TRACE_ERROR,
-+			(TSTR("yaffs: Could not allocate Tnodes" TENDSTR)));
-+		return YAFFS_FAIL;
-+	}
-+
-+	/* New hookup for wide tnodes */
-+	for (i = 0; i < n_tnodes - 1; i++) {
-+		curr = (yaffs_tnode_t *) &mem[i * dev->tnode_size];
-+		next = (yaffs_tnode_t *) &mem[(i+1) * dev->tnode_size];
-+		curr->internal[0] = next;
-+	}
-+
-+	curr = (yaffs_tnode_t *) &mem[(n_tnodes - 1) * dev->tnode_size];
-+	curr->internal[0] = allocator->freeTnodes;
-+	allocator->freeTnodes = (yaffs_tnode_t *)mem;
-+
-+	allocator->nFreeTnodes += n_tnodes;
-+	allocator->n_tnodesCreated += n_tnodes;
-+
-+	/* Now add this bunch of tnodes to a list for freeing up.
-+	 * NB If we can't add this to the management list it isn't fatal
-+	 * but it just means we can't free this bunch of tnodes later.
-+	 */
-+
-+	tnl = YMALLOC(sizeof(yaffs_tnodelist_t));
-+	if (!tnl) {
-+		T(YAFFS_TRACE_ERROR,
-+		  (TSTR
-+		   ("yaffs: Could not add tnodes to management list" TENDSTR)));
-+		   return YAFFS_FAIL;
-+	} else {
-+		tnl->tnodes = newTnodes;
-+		tnl->next = allocator->allocatedTnodeList;
-+		allocator->allocatedTnodeList = tnl;
-+	}
-+
-+	T(YAFFS_TRACE_ALLOCATE, (TSTR("yaffs: Tnodes added" TENDSTR)));
-+
-+	return YAFFS_OK;
-+}
-+
-+
-+yaffs_tnode_t *yaffs_alloc_raw_tnode(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator = (yaffs_Allocator *)dev->allocator;
-+	yaffs_tnode_t *tn = NULL;
-+
-+	if(!allocator){
-+		YBUG();
-+		return NULL;
-+	}
-+
-+	/* If there are none left make more */
-+	if (!allocator->freeTnodes)
-+		yaffs_create_tnodes(dev, YAFFS_ALLOCATION_NTNODES);
-+
-+	if (allocator->freeTnodes) {
-+		tn = allocator->freeTnodes;
-+		allocator->freeTnodes = allocator->freeTnodes->internal[0];
-+		allocator->nFreeTnodes--;
-+	}
-+
-+	return tn;
-+}
-+
-+/* FreeTnode frees up a tnode and puts it back on the free list */
-+void yaffs_free_raw_tnode(yaffs_dev_t *dev, yaffs_tnode_t *tn)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+
-+	if(!allocator){
-+		YBUG();
-+		return;
-+	}
-+
-+	if (tn) {
-+		tn->internal[0] = allocator->freeTnodes;
-+		allocator->freeTnodes = tn;
-+		allocator->nFreeTnodes++;
-+	}
-+	dev->checkpoint_blocks_required = 0; /* force recalculation*/
-+}
-+
-+
-+
-+static void yaffs_init_raw_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+
-+	if(allocator) {
-+		allocator->allocatedObjectList = NULL;
-+		allocator->freeObjects = NULL;
-+		allocator->nFreeObjects = 0;
-+	} else
-+		YBUG();
-+}
-+
-+static void yaffs_deinit_raw_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+	yaffs_obj_tList *tmp;
-+
-+	if(!allocator){
-+		YBUG();
-+		return;
-+	}
-+
-+	while (allocator->allocatedObjectList) {
-+		tmp = allocator->allocatedObjectList->next;
-+		YFREE(allocator->allocatedObjectList->objects);
-+		YFREE(allocator->allocatedObjectList);
-+
-+		allocator->allocatedObjectList = tmp;
-+	}
-+
-+	allocator->freeObjects = NULL;
-+	allocator->nFreeObjects = 0;
-+	allocator->n_objCreated = 0;
-+}
-+
-+
-+static int yaffs_create_free_objs(yaffs_dev_t *dev, int n_obj)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+
-+	int i;
-+	yaffs_obj_t *newObjects;
-+	yaffs_obj_tList *list;
-+
-+	if(!allocator){
-+		YBUG();
-+		return YAFFS_FAIL;
-+	}
-+
-+	if (n_obj < 1)
-+		return YAFFS_OK;
-+
-+	/* make these things */
-+	newObjects = YMALLOC(n_obj * sizeof(yaffs_obj_t));
-+	list = YMALLOC(sizeof(yaffs_obj_tList));
-+
-+	if (!newObjects || !list) {
-+		if (newObjects){
-+			YFREE(newObjects);
-+			newObjects = NULL;
-+		}
-+		if (list){
-+			YFREE(list);
-+			list = NULL;
-+		}
-+		T(YAFFS_TRACE_ALLOCATE,
-+		  (TSTR("yaffs: Could not allocate more objects" TENDSTR)));
-+		return YAFFS_FAIL;
-+	}
-+
-+	/* Hook them into the free list */
-+	for (i = 0; i < n_obj - 1; i++) {
-+		newObjects[i].siblings.next =
-+				(struct ylist_head *)(&newObjects[i + 1]);
-+	}
-+
-+	newObjects[n_obj - 1].siblings.next = (void *)allocator->freeObjects;
-+	allocator->freeObjects = newObjects;
-+	allocator->nFreeObjects += n_obj;
-+	allocator->n_objCreated += n_obj;
-+
-+	/* Now add this bunch of Objects to a list for freeing up. */
-+
-+	list->objects = newObjects;
-+	list->next = allocator->allocatedObjectList;
-+	allocator->allocatedObjectList = list;
-+
-+	return YAFFS_OK;
-+}
-+
-+yaffs_obj_t *yaffs_alloc_raw_obj(yaffs_dev_t *dev)
-+{
-+	yaffs_obj_t *obj = NULL;
-+	yaffs_Allocator *allocator = dev->allocator;
-+
-+	if(!allocator) {
-+		YBUG();
-+		return obj;
-+	}
-+
-+	/* If there are none left make more */
-+	if (!allocator->freeObjects)
-+		yaffs_create_free_objs(dev, YAFFS_ALLOCATION_NOBJECTS);
-+
-+	if (allocator->freeObjects) {
-+		obj = allocator->freeObjects;
-+		allocator->freeObjects =
-+			(yaffs_obj_t *) (allocator->freeObjects->siblings.next);
-+		allocator->nFreeObjects--;
-+	}
-+
-+	return obj;
-+}
-+
-+
-+void yaffs_free_raw_obj(yaffs_dev_t *dev, yaffs_obj_t *obj)
-+{
-+
-+	yaffs_Allocator *allocator = dev->allocator;
-+
-+	if(!allocator)
-+		YBUG();
-+	else {
-+		/* Link into the free list. */
-+		obj->siblings.next = (struct ylist_head *)(allocator->freeObjects);
-+		allocator->freeObjects = obj;
-+		allocator->nFreeObjects++;
-+	}
-+}
-+
-+void yaffs_deinit_raw_tnodes_and_objs(yaffs_dev_t *dev)
-+{
-+	if(dev->allocator){
-+		yaffs_deinit_raw_tnodes(dev);
-+		yaffs_deinit_raw_objs(dev);
-+
-+		YFREE(dev->allocator);
-+		dev->allocator=NULL;
-+	} else
-+		YBUG();
-+}
-+
-+void yaffs_init_raw_tnodes_and_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator;
-+
-+	if(!dev->allocator){
-+		allocator = YMALLOC(sizeof(yaffs_Allocator));
-+		if(allocator){
-+			dev->allocator = allocator;
-+			yaffs_init_raw_tnodes(dev);
-+			yaffs_init_raw_objs(dev);
-+		}
-+	} else
-+		YBUG();
-+}
-+
-+
-+#endif
---- /dev/null
-+++ b/fs/yaffs2/yaffs_allocator.h
-@@ -0,0 +1,30 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+#ifndef __YAFFS_ALLOCATOR_H__
-+#define __YAFFS_ALLOCATOR_H__
-+
-+#include "yaffs_guts.h"
-+
-+void yaffs_init_raw_tnodes_and_objs(yaffs_dev_t *dev);
-+void yaffs_deinit_raw_tnodes_and_objs(yaffs_dev_t *dev);
-+
-+yaffs_tnode_t *yaffs_alloc_raw_tnode(yaffs_dev_t *dev);
-+void yaffs_free_raw_tnode(yaffs_dev_t *dev, yaffs_tnode_t *tn);
-+
-+yaffs_obj_t *yaffs_alloc_raw_obj(yaffs_dev_t *dev);
-+void yaffs_free_raw_obj(yaffs_dev_t *dev, yaffs_obj_t *obj);
-+
-+#endif
---- /dev/null
-+++ b/fs/yaffs2/yaffs_bitmap.c
-@@ -0,0 +1,105 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include "yaffs_bitmap.h"
-+#include "yaffs_trace.h"
-+/*
-+ * Chunk bitmap manipulations
-+ */
-+
-+static Y_INLINE __u8 *yaffs_BlockBits(yaffs_dev_t *dev, int blk)
-+{
-+	if (blk < dev->internal_start_block || blk > dev->internal_end_block) {
-+		T(YAFFS_TRACE_ERROR,
-+			(TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),
-+			blk));
-+		YBUG();
-+	}
-+	return dev->chunk_bits +
-+		(dev->chunk_bit_stride * (blk - dev->internal_start_block));
-+}
-+
-+void yaffs_verify_chunk_bit_id(yaffs_dev_t *dev, int blk, int chunk)
-+{
-+	if (blk < dev->internal_start_block || blk > dev->internal_end_block ||
-+			chunk < 0 || chunk >= dev->param.chunks_per_block) {
-+		T(YAFFS_TRACE_ERROR,
-+		(TSTR("**>> yaffs: Chunk Id (%d:%d) invalid"TENDSTR),
-+			blk, chunk));
-+		YBUG();
-+	}
-+}
-+
-+void yaffs_clear_chunk_bits(yaffs_dev_t *dev, int blk)
-+{
-+	__u8 *blkBits = yaffs_BlockBits(dev, blk);
-+
-+	memset(blkBits, 0, dev->chunk_bit_stride);
-+}
-+
-+void yaffs_clear_chunk_bit(yaffs_dev_t *dev, int blk, int chunk)
-+{
-+	__u8 *blkBits = yaffs_BlockBits(dev, blk);
-+
-+	yaffs_verify_chunk_bit_id(dev, blk, chunk);
-+
-+	blkBits[chunk / 8] &= ~(1 << (chunk & 7));
-+}
-+
-+void yaffs_set_chunk_bit(yaffs_dev_t *dev, int blk, int chunk)
-+{
-+	__u8 *blkBits = yaffs_BlockBits(dev, blk);
-+
-+	yaffs_verify_chunk_bit_id(dev, blk, chunk);
-+
-+	blkBits[chunk / 8] |= (1 << (chunk & 7));
-+}
-+
-+int yaffs_check_chunk_bit(yaffs_dev_t *dev, int blk, int chunk)
-+{
-+	__u8 *blkBits = yaffs_BlockBits(dev, blk);
-+	yaffs_verify_chunk_bit_id(dev, blk, chunk);
-+
-+	return (blkBits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0;
-+}
-+
-+int yaffs_still_some_chunks(yaffs_dev_t *dev, int blk)
-+{
-+	__u8 *blkBits = yaffs_BlockBits(dev, blk);
-+	int i;
-+	for (i = 0; i < dev->chunk_bit_stride; i++) {
-+		if (*blkBits)
-+			return 1;
-+		blkBits++;
-+	}
-+	return 0;
-+}
-+
-+int yaffs_count_chunk_bits(yaffs_dev_t *dev, int blk)
-+{
-+	__u8 *blkBits = yaffs_BlockBits(dev, blk);
-+	int i;
-+	int n = 0;
-+	for (i = 0; i < dev->chunk_bit_stride; i++) {
-+		__u8 x = *blkBits;
-+		while (x) {
-+			if (x & 1)
-+				n++;
-+			x >>= 1;
-+		}
-+
-+		blkBits++;
-+	}
-+	return n;
-+}
-+
---- /dev/null
-+++ b/fs/yaffs2/yaffs_bitmap.h
-@@ -0,0 +1,31 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+/*
-+ * Chunk bitmap manipulations
-+ */
-+
-+#ifndef __YAFFS_BITMAP_H__
-+#define __YAFFS_BITMAP_H__
-+
-+#include "yaffs_guts.h"
-+
-+void yaffs_verify_chunk_bit_id(yaffs_dev_t *dev, int blk, int chunk);
-+void yaffs_clear_chunk_bits(yaffs_dev_t *dev, int blk);
-+void yaffs_clear_chunk_bit(yaffs_dev_t *dev, int blk, int chunk);
-+void yaffs_set_chunk_bit(yaffs_dev_t *dev, int blk, int chunk);
-+int yaffs_check_chunk_bit(yaffs_dev_t *dev, int blk, int chunk);
-+int yaffs_still_some_chunks(yaffs_dev_t *dev, int blk);
-+int yaffs_count_chunk_bits(yaffs_dev_t *dev, int blk);
-+
-+#endif
---- a/fs/yaffs2/yaffs_checkptrw.c
-+++ b/fs/yaffs2/yaffs_checkptrw.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -11,16 +11,12 @@
-  * published by the Free Software Foundation.
-  */
- 
--const char *yaffs_checkptrw_c_version =
--	"$Id: yaffs_checkptrw.c,v 1.18 2009-03-06 17:20:49 wookey Exp $";
--
--
- #include "yaffs_checkptrw.h"
- #include "yaffs_getblockinfo.h"
- 
--static int yaffs_CheckpointSpaceOk(yaffs_Device *dev)
-+static int yaffs2_checkpt_space_ok(yaffs_dev_t *dev)
- {
--	int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
-+	int blocksAvailable = dev->n_erased_blocks - dev->param.n_reserved_blocks;
- 
- 	T(YAFFS_TRACE_CHECKPOINT,
- 		(TSTR("checkpt blocks available = %d" TENDSTR),
-@@ -30,53 +26,56 @@ static int yaffs_CheckpointSpaceOk(yaffs
- }
- 
- 
--static int yaffs_CheckpointErase(yaffs_Device *dev)
-+static int yaffs_checkpt_erase(yaffs_dev_t *dev)
- {
- 	int i;
- 
--	if (!dev->eraseBlockInNAND)
-+	if (!dev->param.erase_fn)
- 		return 0;
- 	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checking blocks %d to %d"TENDSTR),
--		dev->internalStartBlock, dev->internalEndBlock));
-+		dev->internal_start_block, dev->internal_end_block));
- 
--	for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
--		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
--		if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) {
-+	for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
-+		yaffs_block_info_t *bi = yaffs_get_block_info(dev, i);
-+		if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) {
- 			T(YAFFS_TRACE_CHECKPOINT, (TSTR("erasing checkpt block %d"TENDSTR), i));
--			if (dev->eraseBlockInNAND(dev, i - dev->blockOffset /* realign */)) {
--				bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
--				dev->nErasedBlocks++;
--				dev->nFreeChunks += dev->nChunksPerBlock;
-+
-+			dev->n_erasures++;
-+
-+			if (dev->param.erase_fn(dev, i - dev->block_offset /* realign */)) {
-+				bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
-+				dev->n_erased_blocks++;
-+				dev->n_free_chunks += dev->param.chunks_per_block;
- 			} else {
--				dev->markNANDBlockBad(dev, i);
--				bi->blockState = YAFFS_BLOCK_STATE_DEAD;
-+				dev->param.bad_block_fn(dev, i);
-+				bi->block_state = YAFFS_BLOCK_STATE_DEAD;
- 			}
- 		}
- 	}
- 
--	dev->blocksInCheckpoint = 0;
-+	dev->blocks_in_checkpt = 0;
- 
- 	return 1;
- }
- 
- 
--static void yaffs_CheckpointFindNextErasedBlock(yaffs_Device *dev)
-+static void yaffs2_checkpt_find_erased_block(yaffs_dev_t *dev)
- {
- 	int  i;
--	int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
-+	int blocksAvailable = dev->n_erased_blocks - dev->param.n_reserved_blocks;
- 	T(YAFFS_TRACE_CHECKPOINT,
- 		(TSTR("allocating checkpt block: erased %d reserved %d avail %d next %d "TENDSTR),
--		dev->nErasedBlocks, dev->nReservedBlocks, blocksAvailable, dev->checkpointNextBlock));
-+		dev->n_erased_blocks, dev->param.n_reserved_blocks, blocksAvailable, dev->checkpt_next_block));
- 
--	if (dev->checkpointNextBlock >= 0 &&
--			dev->checkpointNextBlock <= dev->internalEndBlock &&
-+	if (dev->checkpt_next_block >= 0 &&
-+			dev->checkpt_next_block <= dev->internal_end_block &&
- 			blocksAvailable > 0) {
- 
--		for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
--			yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
--			if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY) {
--				dev->checkpointNextBlock = i + 1;
--				dev->checkpointCurrentBlock = i;
-+		for (i = dev->checkpt_next_block; i <= dev->internal_end_block; i++) {
-+			yaffs_block_info_t *bi = yaffs_get_block_info(dev, i);
-+			if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) {
-+				dev->checkpt_next_block = i + 1;
-+				dev->checkpt_cur_block = i;
- 				T(YAFFS_TRACE_CHECKPOINT, (TSTR("allocating checkpt block %d"TENDSTR), i));
- 				return;
- 			}
-@@ -84,34 +83,34 @@ static void yaffs_CheckpointFindNextEras
- 	}
- 	T(YAFFS_TRACE_CHECKPOINT, (TSTR("out of checkpt blocks"TENDSTR)));
- 
--	dev->checkpointNextBlock = -1;
--	dev->checkpointCurrentBlock = -1;
-+	dev->checkpt_next_block = -1;
-+	dev->checkpt_cur_block = -1;
- }
- 
--static void yaffs_CheckpointFindNextCheckpointBlock(yaffs_Device *dev)
-+static void yaffs2_checkpt_find_block(yaffs_dev_t *dev)
- {
- 	int  i;
--	yaffs_ExtendedTags tags;
-+	yaffs_ext_tags tags;
- 
- 	T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: start:  blocks %d next %d" TENDSTR),
--		dev->blocksInCheckpoint, dev->checkpointNextBlock));
-+		dev->blocks_in_checkpt, dev->checkpt_next_block));
- 
--	if (dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
--		for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
--			int chunk = i * dev->nChunksPerBlock;
--			int realignedChunk = chunk - dev->chunkOffset;
-+	if (dev->blocks_in_checkpt < dev->checkpt_max_blocks)
-+		for (i = dev->checkpt_next_block; i <= dev->internal_end_block; i++) {
-+			int chunk = i * dev->param.chunks_per_block;
-+			int realignedChunk = chunk - dev->chunk_offset;
- 
--			dev->readChunkWithTagsFromNAND(dev, realignedChunk,
-+			dev->param.read_chunk_tags_fn(dev, realignedChunk,
- 					NULL, &tags);
- 			T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR),
--				i, tags.objectId, tags.sequenceNumber, tags.eccResult));
-+				i, tags.obj_id, tags.seq_number, tags.ecc_result));
- 
--			if (tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA) {
-+			if (tags.seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA) {
- 				/* Right kind of block */
--				dev->checkpointNextBlock = tags.objectId;
--				dev->checkpointCurrentBlock = i;
--				dev->checkpointBlockList[dev->blocksInCheckpoint] = i;
--				dev->blocksInCheckpoint++;
-+				dev->checkpt_next_block = tags.obj_id;
-+				dev->checkpt_cur_block = i;
-+				dev->checkpt_block_list[dev->blocks_in_checkpt] = i;
-+				dev->blocks_in_checkpt++;
- 				T(YAFFS_TRACE_CHECKPOINT, (TSTR("found checkpt block %d"TENDSTR), i));
- 				return;
- 			}
-@@ -119,122 +118,127 @@ static void yaffs_CheckpointFindNextChec
- 
- 	T(YAFFS_TRACE_CHECKPOINT, (TSTR("found no more checkpt blocks"TENDSTR)));
- 
--	dev->checkpointNextBlock = -1;
--	dev->checkpointCurrentBlock = -1;
-+	dev->checkpt_next_block = -1;
-+	dev->checkpt_cur_block = -1;
- }
- 
- 
--int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting)
-+int yaffs2_checkpt_open(yaffs_dev_t *dev, int forWriting)
- {
- 
-+
-+	dev->checkpt_open_write = forWriting;
-+
- 	/* Got the functions we need? */
--	if (!dev->writeChunkWithTagsToNAND ||
--			!dev->readChunkWithTagsFromNAND ||
--			!dev->eraseBlockInNAND ||
--			!dev->markNANDBlockBad)
-+	if (!dev->param.write_chunk_tags_fn ||
-+		!dev->param.read_chunk_tags_fn ||
-+		!dev->param.erase_fn ||
-+		!dev->param.bad_block_fn)
- 		return 0;
- 
--	if (forWriting && !yaffs_CheckpointSpaceOk(dev))
-+	if (forWriting && !yaffs2_checkpt_space_ok(dev))
- 		return 0;
- 
--	if (!dev->checkpointBuffer)
--		dev->checkpointBuffer = YMALLOC_DMA(dev->totalBytesPerChunk);
--	if (!dev->checkpointBuffer)
-+	if (!dev->checkpt_buffer)
-+		dev->checkpt_buffer = YMALLOC_DMA(dev->param.total_bytes_per_chunk);
-+	if (!dev->checkpt_buffer)
- 		return 0;
- 
- 
--	dev->checkpointPageSequence = 0;
--
--	dev->checkpointOpenForWrite = forWriting;
--
--	dev->checkpointByteCount = 0;
--	dev->checkpointSum = 0;
--	dev->checkpointXor = 0;
--	dev->checkpointCurrentBlock = -1;
--	dev->checkpointCurrentChunk = -1;
--	dev->checkpointNextBlock = dev->internalStartBlock;
-+	dev->checkpt_page_seq = 0;
-+	dev->checkpt_byte_count = 0;
-+	dev->checkpt_sum = 0;
-+	dev->checkpt_xor = 0;
-+	dev->checkpt_cur_block = -1;
-+	dev->checkpt_cur_chunk = -1;
-+	dev->checkpt_next_block = dev->internal_start_block;
- 
- 	/* Erase all the blocks in the checkpoint area */
- 	if (forWriting) {
--		memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
--		dev->checkpointByteOffset = 0;
--		return yaffs_CheckpointErase(dev);
-+		memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk);
-+		dev->checkpt_byte_offs = 0;
-+		return yaffs_checkpt_erase(dev);
- 	} else {
- 		int i;
- 		/* Set to a value that will kick off a read */
--		dev->checkpointByteOffset = dev->nDataBytesPerChunk;
-+		dev->checkpt_byte_offs = dev->data_bytes_per_chunk;
- 		/* A checkpoint block list of 1 checkpoint block per 16 block is (hopefully)
- 		 * going to be way more than we need */
--		dev->blocksInCheckpoint = 0;
--		dev->checkpointMaxBlocks = (dev->internalEndBlock - dev->internalStartBlock)/16 + 2;
--		dev->checkpointBlockList = YMALLOC(sizeof(int) * dev->checkpointMaxBlocks);
--		for (i = 0; i < dev->checkpointMaxBlocks; i++)
--			dev->checkpointBlockList[i] = -1;
-+		dev->blocks_in_checkpt = 0;
-+		dev->checkpt_max_blocks = (dev->internal_end_block - dev->internal_start_block)/16 + 2;
-+		dev->checkpt_block_list = YMALLOC(sizeof(int) * dev->checkpt_max_blocks);
-+		if(!dev->checkpt_block_list)
-+			return 0;
-+
-+		for (i = 0; i < dev->checkpt_max_blocks; i++)
-+			dev->checkpt_block_list[i] = -1;
- 	}
- 
- 	return 1;
- }
- 
--int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum)
-+int yaffs2_get_checkpt_sum(yaffs_dev_t *dev, __u32 *sum)
- {
- 	__u32 compositeSum;
--	compositeSum =  (dev->checkpointSum << 8) | (dev->checkpointXor & 0xFF);
-+	compositeSum =  (dev->checkpt_sum << 8) | (dev->checkpt_xor & 0xFF);
- 	*sum = compositeSum;
- 	return 1;
- }
- 
--static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
-+static int yaffs2_checkpt_flush_buffer(yaffs_dev_t *dev)
- {
- 	int chunk;
- 	int realignedChunk;
- 
--	yaffs_ExtendedTags tags;
-+	yaffs_ext_tags tags;
- 
--	if (dev->checkpointCurrentBlock < 0) {
--		yaffs_CheckpointFindNextErasedBlock(dev);
--		dev->checkpointCurrentChunk = 0;
-+	if (dev->checkpt_cur_block < 0) {
-+		yaffs2_checkpt_find_erased_block(dev);
-+		dev->checkpt_cur_chunk = 0;
- 	}
- 
--	if (dev->checkpointCurrentBlock < 0)
-+	if (dev->checkpt_cur_block < 0)
- 		return 0;
- 
--	tags.chunkDeleted = 0;
--	tags.objectId = dev->checkpointNextBlock; /* Hint to next place to look */
--	tags.chunkId = dev->checkpointPageSequence + 1;
--	tags.sequenceNumber =  YAFFS_SEQUENCE_CHECKPOINT_DATA;
--	tags.byteCount = dev->nDataBytesPerChunk;
--	if (dev->checkpointCurrentChunk == 0) {
-+	tags.is_deleted = 0;
-+	tags.obj_id = dev->checkpt_next_block; /* Hint to next place to look */
-+	tags.chunk_id = dev->checkpt_page_seq + 1;
-+	tags.seq_number =  YAFFS_SEQUENCE_CHECKPOINT_DATA;
-+	tags.n_bytes = dev->data_bytes_per_chunk;
-+	if (dev->checkpt_cur_chunk == 0) {
- 		/* First chunk we write for the block? Set block state to
- 		   checkpoint */
--		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointCurrentBlock);
--		bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
--		dev->blocksInCheckpoint++;
-+		yaffs_block_info_t *bi = yaffs_get_block_info(dev, dev->checkpt_cur_block);
-+		bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT;
-+		dev->blocks_in_checkpt++;
- 	}
- 
--	chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk;
-+	chunk = dev->checkpt_cur_block * dev->param.chunks_per_block + dev->checkpt_cur_chunk;
- 
- 
- 	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
--		chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk, tags.objectId, tags.chunkId));
-+		chunk, dev->checkpt_cur_block, dev->checkpt_cur_chunk, tags.obj_id, tags.chunk_id));
- 
--	realignedChunk = chunk - dev->chunkOffset;
-+	realignedChunk = chunk - dev->chunk_offset;
- 
--	dev->writeChunkWithTagsToNAND(dev, realignedChunk,
--			dev->checkpointBuffer, &tags);
--	dev->checkpointByteOffset = 0;
--	dev->checkpointPageSequence++;
--	dev->checkpointCurrentChunk++;
--	if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock) {
--		dev->checkpointCurrentChunk = 0;
--		dev->checkpointCurrentBlock = -1;
-+	dev->n_page_writes++;
-+
-+	dev->param.write_chunk_tags_fn(dev, realignedChunk,
-+			dev->checkpt_buffer, &tags);
-+	dev->checkpt_byte_offs = 0;
-+	dev->checkpt_page_seq++;
-+	dev->checkpt_cur_chunk++;
-+	if (dev->checkpt_cur_chunk >= dev->param.chunks_per_block) {
-+		dev->checkpt_cur_chunk = 0;
-+		dev->checkpt_cur_block = -1;
- 	}
--	memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
-+	memset(dev->checkpt_buffer, 0, dev->data_bytes_per_chunk);
- 
- 	return 1;
- }
- 
- 
--int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes)
-+int yaffs2_checkpt_wr(yaffs_dev_t *dev, const void *data, int n_bytes)
- {
- 	int i = 0;
- 	int ok = 1;
-@@ -244,36 +248,36 @@ int yaffs_CheckpointWrite(yaffs_Device *
- 
- 
- 
--	if (!dev->checkpointBuffer)
-+	if (!dev->checkpt_buffer)
- 		return 0;
- 
--	if (!dev->checkpointOpenForWrite)
-+	if (!dev->checkpt_open_write)
- 		return -1;
- 
--	while (i < nBytes && ok) {
--		dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes;
--		dev->checkpointSum += *dataBytes;
--		dev->checkpointXor ^= *dataBytes;
-+	while (i < n_bytes && ok) {
-+		dev->checkpt_buffer[dev->checkpt_byte_offs] = *dataBytes;
-+		dev->checkpt_sum += *dataBytes;
-+		dev->checkpt_xor ^= *dataBytes;
- 
--		dev->checkpointByteOffset++;
-+		dev->checkpt_byte_offs++;
- 		i++;
- 		dataBytes++;
--		dev->checkpointByteCount++;
-+		dev->checkpt_byte_count++;
- 
- 
--		if (dev->checkpointByteOffset < 0 ||
--		   dev->checkpointByteOffset >= dev->nDataBytesPerChunk)
--			ok = yaffs_CheckpointFlushBuffer(dev);
-+		if (dev->checkpt_byte_offs < 0 ||
-+		   dev->checkpt_byte_offs >= dev->data_bytes_per_chunk)
-+			ok = yaffs2_checkpt_flush_buffer(dev);
- 	}
- 
- 	return i;
- }
- 
--int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
-+int yaffs2_checkpt_rd(yaffs_dev_t *dev, void *data, int n_bytes)
- {
- 	int i = 0;
- 	int ok = 1;
--	yaffs_ExtendedTags tags;
-+	yaffs_ext_tags tags;
- 
- 
- 	int chunk;
-@@ -281,113 +285,116 @@ int yaffs_CheckpointRead(yaffs_Device *d
- 
- 	__u8 *dataBytes = (__u8 *)data;
- 
--	if (!dev->checkpointBuffer)
-+	if (!dev->checkpt_buffer)
- 		return 0;
- 
--	if (dev->checkpointOpenForWrite)
-+	if (dev->checkpt_open_write)
- 		return -1;
- 
--	while (i < nBytes && ok) {
-+	while (i < n_bytes && ok) {
- 
- 
--		if (dev->checkpointByteOffset < 0 ||
--			dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
-+		if (dev->checkpt_byte_offs < 0 ||
-+			dev->checkpt_byte_offs >= dev->data_bytes_per_chunk) {
- 
--			if (dev->checkpointCurrentBlock < 0) {
--				yaffs_CheckpointFindNextCheckpointBlock(dev);
--				dev->checkpointCurrentChunk = 0;
-+			if (dev->checkpt_cur_block < 0) {
-+				yaffs2_checkpt_find_block(dev);
-+				dev->checkpt_cur_chunk = 0;
- 			}
- 
--			if (dev->checkpointCurrentBlock < 0)
-+			if (dev->checkpt_cur_block < 0)
- 				ok = 0;
- 			else {
--				chunk = dev->checkpointCurrentBlock *
--					dev->nChunksPerBlock +
--					dev->checkpointCurrentChunk;
--
--				realignedChunk = chunk - dev->chunkOffset;
-+				chunk = dev->checkpt_cur_block *
-+					dev->param.chunks_per_block +
-+					dev->checkpt_cur_chunk;
-+
-+				realignedChunk = chunk - dev->chunk_offset;
-+				
-+				dev->n_page_reads++;
- 
- 				/* read in the next chunk */
- 				/* printf("read checkpoint page %d\n",dev->checkpointPage); */
--				dev->readChunkWithTagsFromNAND(dev,
-+				dev->param.read_chunk_tags_fn(dev,
- 						realignedChunk,
--						dev->checkpointBuffer,
-+						dev->checkpt_buffer,
- 						&tags);
- 
--				if (tags.chunkId != (dev->checkpointPageSequence + 1) ||
--					tags.eccResult > YAFFS_ECC_RESULT_FIXED ||
--					tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
-+				if (tags.chunk_id != (dev->checkpt_page_seq + 1) ||
-+					tags.ecc_result > YAFFS_ECC_RESULT_FIXED ||
-+					tags.seq_number != YAFFS_SEQUENCE_CHECKPOINT_DATA)
- 					ok = 0;
- 
--				dev->checkpointByteOffset = 0;
--				dev->checkpointPageSequence++;
--				dev->checkpointCurrentChunk++;
-+				dev->checkpt_byte_offs = 0;
-+				dev->checkpt_page_seq++;
-+				dev->checkpt_cur_chunk++;
- 
--				if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
--					dev->checkpointCurrentBlock = -1;
-+				if (dev->checkpt_cur_chunk >= dev->param.chunks_per_block)
-+					dev->checkpt_cur_block = -1;
- 			}
- 		}
- 
- 		if (ok) {
--			*dataBytes = dev->checkpointBuffer[dev->checkpointByteOffset];
--			dev->checkpointSum += *dataBytes;
--			dev->checkpointXor ^= *dataBytes;
--			dev->checkpointByteOffset++;
-+			*dataBytes = dev->checkpt_buffer[dev->checkpt_byte_offs];
-+			dev->checkpt_sum += *dataBytes;
-+			dev->checkpt_xor ^= *dataBytes;
-+			dev->checkpt_byte_offs++;
- 			i++;
- 			dataBytes++;
--			dev->checkpointByteCount++;
-+			dev->checkpt_byte_count++;
- 		}
- 	}
- 
- 	return 	i;
- }
- 
--int yaffs_CheckpointClose(yaffs_Device *dev)
-+int yaffs_checkpt_close(yaffs_dev_t *dev)
- {
- 
--	if (dev->checkpointOpenForWrite) {
--		if (dev->checkpointByteOffset != 0)
--			yaffs_CheckpointFlushBuffer(dev);
--	} else {
-+	if (dev->checkpt_open_write) {
-+		if (dev->checkpt_byte_offs != 0)
-+			yaffs2_checkpt_flush_buffer(dev);
-+	} else if(dev->checkpt_block_list){
- 		int i;
--		for (i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++) {
--			yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointBlockList[i]);
--			if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
--				bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
-+		for (i = 0; i < dev->blocks_in_checkpt && dev->checkpt_block_list[i] >= 0; i++) {
-+			int blk = dev->checkpt_block_list[i];
-+			yaffs_block_info_t *bi = NULL;
-+			if( dev->internal_start_block <= blk && blk <= dev->internal_end_block)
-+				bi = yaffs_get_block_info(dev, blk);
-+			if (bi && bi->block_state == YAFFS_BLOCK_STATE_EMPTY)
-+				bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT;
- 			else {
- 				/* Todo this looks odd... */
- 			}
- 		}
--		YFREE(dev->checkpointBlockList);
--		dev->checkpointBlockList = NULL;
-+		YFREE(dev->checkpt_block_list);
-+		dev->checkpt_block_list = NULL;
- 	}
- 
--	dev->nFreeChunks -= dev->blocksInCheckpoint * dev->nChunksPerBlock;
--	dev->nErasedBlocks -= dev->blocksInCheckpoint;
-+	dev->n_free_chunks -= dev->blocks_in_checkpt * dev->param.chunks_per_block;
-+	dev->n_erased_blocks -= dev->blocks_in_checkpt;
- 
- 
- 	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint byte count %d" TENDSTR),
--			dev->checkpointByteCount));
-+			dev->checkpt_byte_count));
- 
--	if (dev->checkpointBuffer) {
-+	if (dev->checkpt_buffer) {
- 		/* free the buffer */
--		YFREE(dev->checkpointBuffer);
--		dev->checkpointBuffer = NULL;
-+		YFREE(dev->checkpt_buffer);
-+		dev->checkpt_buffer = NULL;
- 		return 1;
- 	} else
- 		return 0;
- }
- 
--int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
-+int yaffs2_checkpt_invalidate_stream(yaffs_dev_t *dev)
- {
--	/* Erase the first checksum block */
--
--	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate"TENDSTR)));
-+	/* Erase the checkpoint data */
- 
--	if (!yaffs_CheckpointSpaceOk(dev))
--		return 0;
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate of %d blocks"TENDSTR),
-+		dev->blocks_in_checkpt));
- 
--	return yaffs_CheckpointErase(dev);
-+	return yaffs_checkpt_erase(dev);
- }
- 
- 
---- a/fs/yaffs2/yaffs_checkptrw.h
-+++ b/fs/yaffs2/yaffs_checkptrw.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -18,18 +18,17 @@
- 
- #include "yaffs_guts.h"
- 
--int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting);
-+int yaffs2_checkpt_open(yaffs_dev_t *dev, int forWriting);
- 
--int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes);
-+int yaffs2_checkpt_wr(yaffs_dev_t *dev, const void *data, int n_bytes);
- 
--int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes);
-+int yaffs2_checkpt_rd(yaffs_dev_t *dev, void *data, int n_bytes);
- 
--int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum);
-+int yaffs2_get_checkpt_sum(yaffs_dev_t *dev, __u32 *sum);
- 
--int yaffs_CheckpointClose(yaffs_Device *dev);
-+int yaffs_checkpt_close(yaffs_dev_t *dev);
- 
--int yaffs_CheckpointInvalidateStream(yaffs_Device *dev);
-+int yaffs2_checkpt_invalidate_stream(yaffs_dev_t *dev);
- 
- 
- #endif
--
---- a/fs/yaffs2/yaffs_ecc.c
-+++ b/fs/yaffs2/yaffs_ecc.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -28,9 +28,6 @@
-  * this bytes influence on the line parity.
-  */
- 
--const char *yaffs_ecc_c_version =
--	"$Id: yaffs_ecc.c,v 1.11 2009-03-06 17:20:50 wookey Exp $";
--
- #include "yportenv.h"
- 
- #include "yaffs_ecc.h"
-@@ -72,7 +69,7 @@ static const unsigned char column_parity
- 
- /* Count the bits in an unsigned char or a U32 */
- 
--static int yaffs_CountBits(unsigned char x)
-+static int yaffs_count_bits(unsigned char x)
- {
- 	int r = 0;
- 	while (x) {
-@@ -83,7 +80,7 @@ static int yaffs_CountBits(unsigned char
- 	return r;
- }
- 
--static int yaffs_CountBits32(unsigned x)
-+static int yaffs_count_bits32(unsigned x)
- {
- 	int r = 0;
- 	while (x) {
-@@ -95,7 +92,7 @@ static int yaffs_CountBits32(unsigned x)
- }
- 
- /* Calculate the ECC for a 256-byte block of data */
--void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc)
-+void yaffs_ecc_cacl(const unsigned char *data, unsigned char *ecc)
- {
- 	unsigned int i;
- 
-@@ -166,7 +163,7 @@ void yaffs_ECCCalculate(const unsigned c
- 
- /* Correct the ECC on a 256 byte block of data */
- 
--int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
-+int yaffs_ecc_correct(unsigned char *data, unsigned char *read_ecc,
- 		     const unsigned char *test_ecc)
- {
- 	unsigned char d0, d1, d2;	/* deltas */
-@@ -226,9 +223,9 @@ int yaffs_ECCCorrect(unsigned char *data
- 		return 1; /* Corrected the error */
- 	}
- 
--	if ((yaffs_CountBits(d0) +
--	     yaffs_CountBits(d1) +
--	     yaffs_CountBits(d2)) ==  1) {
-+	if ((yaffs_count_bits(d0) +
-+	     yaffs_count_bits(d1) +
-+	     yaffs_count_bits(d2)) ==  1) {
- 		/* Reccoverable error in ecc */
- 
- 		read_ecc[0] = test_ecc[0];
-@@ -248,7 +245,7 @@ int yaffs_ECCCorrect(unsigned char *data
- /*
-  * ECCxxxOther does ECC calcs on arbitrary n bytes of data
-  */
--void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
-+void yaffs_ecc_calc_other(const unsigned char *data, unsigned n_bytes,
- 				yaffs_ECCOther *eccOther)
- {
- 	unsigned int i;
-@@ -258,7 +255,7 @@ void yaffs_ECCCalculateOther(const unsig
- 	unsigned line_parity_prime = 0;
- 	unsigned char b;
- 
--	for (i = 0; i < nBytes; i++) {
-+	for (i = 0; i < n_bytes; i++) {
- 		b = column_parity_table[*data++];
- 		col_parity ^= b;
- 
-@@ -275,7 +272,7 @@ void yaffs_ECCCalculateOther(const unsig
- 	eccOther->lineParityPrime = line_parity_prime;
- }
- 
--int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
-+int yaffs_ecc_correct_other(unsigned char *data, unsigned n_bytes,
- 			yaffs_ECCOther *read_ecc,
- 			const yaffs_ECCOther *test_ecc)
- {
-@@ -304,7 +301,7 @@ int yaffs_ECCCorrectOther(unsigned char
- 		if (cDelta & 0x02)
- 			bit |= 0x01;
- 
--		if (lDelta >= nBytes)
-+		if (lDelta >= n_bytes)
- 			return -1;
- 
- 		data[lDelta] ^= (1 << bit);
-@@ -312,8 +309,8 @@ int yaffs_ECCCorrectOther(unsigned char
- 		return 1; /* corrected */
- 	}
- 
--	if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
--			yaffs_CountBits(cDelta)) == 1) {
-+	if ((yaffs_count_bits32(lDelta) + yaffs_count_bits32(lDeltaPrime) +
-+			yaffs_count_bits(cDelta)) == 1) {
- 		/* Reccoverable error in ecc */
- 
- 		*read_ecc = *test_ecc;
---- a/fs/yaffs2/yaffs_ecc.h
-+++ b/fs/yaffs2/yaffs_ecc.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -32,13 +32,13 @@ typedef struct {
- 	unsigned lineParityPrime;
- } yaffs_ECCOther;
- 
--void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc);
--int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
-+void yaffs_ecc_cacl(const unsigned char *data, unsigned char *ecc);
-+int yaffs_ecc_correct(unsigned char *data, unsigned char *read_ecc,
- 		const unsigned char *test_ecc);
- 
--void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
-+void yaffs_ecc_calc_other(const unsigned char *data, unsigned n_bytes,
- 			yaffs_ECCOther *ecc);
--int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
-+int yaffs_ecc_correct_other(unsigned char *data, unsigned n_bytes,
- 			yaffs_ECCOther *read_ecc,
- 			const yaffs_ECCOther *test_ecc);
- #endif
---- a/fs/yaffs2/yaffs_fs.c
-+++ /dev/null
-@@ -1,2529 +0,0 @@
--/*
-- * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-- *
-- * Copyright (C) 2002-2009 Aleph One Ltd.
-- *   for Toby Churchill Ltd and Brightstar Engineering
-- *
-- * Created by Charles Manning <charles@aleph1.co.uk>
-- * Acknowledgements:
-- * Luc van OostenRyck for numerous patches.
-- * Nick Bane for numerous patches.
-- * Nick Bane for 2.5/2.6 integration.
-- * Andras Toth for mknod rdev issue.
-- * Michael Fischer for finding the problem with inode inconsistency.
-- * Some code bodily lifted from JFFS
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- */
--
--/*
-- *
-- * This is the file system front-end to YAFFS that hooks it up to
-- * the VFS.
-- *
-- * Special notes:
-- * >> 2.4: sb->u.generic_sbp points to the yaffs_Device associated with
-- *         this superblock
-- * >> 2.6: sb->s_fs_info  points to the yaffs_Device associated with this
-- *         superblock
-- * >> inode->u.generic_ip points to the associated yaffs_Object.
-- */
--
--const char *yaffs_fs_c_version =
--    "$Id: yaffs_fs.c,v 1.79 2009-03-17 01:12:00 wookey Exp $";
--extern const char *yaffs_guts_c_version;
--
--#include <linux/version.h>
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
--#include <linux/config.h>
--#endif
--#include <linux/kernel.h>
--#include <linux/module.h>
--#include <linux/slab.h>
--#include <linux/init.h>
--#include <linux/fs.h>
--#include <linux/proc_fs.h>
--#include <linux/smp_lock.h>
--#include <linux/pagemap.h>
--#include <linux/mtd/mtd.h>
--#include <linux/interrupt.h>
--#include <linux/string.h>
--#include <linux/ctype.h>
--
--#include "asm/div64.h"
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--
--#include <linux/statfs.h>	/* Added NCB 15-8-2003 */
--#include <linux/statfs.h>
--#define UnlockPage(p) unlock_page(p)
--#define Page_Uptodate(page)	test_bit(PG_uptodate, &(page)->flags)
--
--/* FIXME: use sb->s_id instead ? */
--#define yaffs_devname(sb, buf)	bdevname(sb->s_bdev, buf)
--
--#else
--
--#include <linux/locks.h>
--#define	BDEVNAME_SIZE		0
--#define	yaffs_devname(sb, buf)	kdevname(sb->s_dev)
--
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
--/* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */
--#define __user
--#endif
--
--#endif
--
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
--#define YPROC_ROOT  (&proc_root)
--#else
--#define YPROC_ROOT  NULL
--#endif
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--#define WRITE_SIZE_STR "writesize"
--#define WRITE_SIZE(mtd) ((mtd)->writesize)
--#else
--#define WRITE_SIZE_STR "oobblock"
--#define WRITE_SIZE(mtd) ((mtd)->oobblock)
--#endif
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
--#define YAFFS_USE_WRITE_BEGIN_END 1
--#else
--#define YAFFS_USE_WRITE_BEGIN_END 0
--#endif
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
--static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
--{
--	uint64_t result = partition_size;
--	do_div(result, block_size);
--	return (uint32_t)result;
--}
--#else
--#define YCALCBLOCKS(s, b) ((s)/(b))
--#endif
--
--#include <linux/uaccess.h>
--
--#include "yportenv.h"
--#include "yaffs_guts.h"
--
--#include <linux/mtd/mtd.h>
--#include "yaffs_mtdif.h"
--#include "yaffs_mtdif1.h"
--#include "yaffs_mtdif2.h"
--
--unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS;
--unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
--unsigned int yaffs_auto_checkpoint = 1;
--
--/* Module Parameters */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--module_param(yaffs_traceMask, uint, 0644);
--module_param(yaffs_wr_attempts, uint, 0644);
--module_param(yaffs_auto_checkpoint, uint, 0644);
--#else
--MODULE_PARM(yaffs_traceMask, "i");
--MODULE_PARM(yaffs_wr_attempts, "i");
--MODULE_PARM(yaffs_auto_checkpoint, "i");
--#endif
--
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
--/* use iget and read_inode */
--#define Y_IGET(sb, inum) iget((sb), (inum))
--static void yaffs_read_inode(struct inode *inode);
--
--#else
--/* Call local equivalent */
--#define YAFFS_USE_OWN_IGET
--#define Y_IGET(sb, inum) yaffs_iget((sb), (inum))
--
--static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino);
--#endif
--
--/*#define T(x) printk x */
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
--#define yaffs_InodeToObjectLV(iptr) ((iptr)->i_private)
--#else
--#define yaffs_InodeToObjectLV(iptr) ((iptr)->u.generic_ip)
--#endif
--
--#define yaffs_InodeToObject(iptr) ((yaffs_Object *)(yaffs_InodeToObjectLV(iptr)))
--#define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode)
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--#define yaffs_SuperToDevice(sb)	((yaffs_Device *)sb->s_fs_info)
--#else
--#define yaffs_SuperToDevice(sb)	((yaffs_Device *)sb->u.generic_sbp)
--#endif
--
--static void yaffs_put_super(struct super_block *sb);
--
--static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
--				loff_t *pos);
--static ssize_t yaffs_hold_space(struct file *f);
--static void yaffs_release_space(struct file *f);
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static int yaffs_file_flush(struct file *file, fl_owner_t id);
--#else
--static int yaffs_file_flush(struct file *file);
--#endif
--
--static int yaffs_sync_object(struct file *file, struct dentry *dentry,
--				int datasync);
--
--static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir);
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
--			struct nameidata *n);
--static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
--					struct nameidata *n);
--#else
--static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode);
--static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry);
--#endif
--static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
--			struct dentry *dentry);
--static int yaffs_unlink(struct inode *dir, struct dentry *dentry);
--static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
--			const char *symname);
--static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
--			dev_t dev);
--#else
--static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
--			int dev);
--#endif
--static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
--			struct inode *new_dir, struct dentry *new_dentry);
--static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static int yaffs_sync_fs(struct super_block *sb, int wait);
--static void yaffs_write_super(struct super_block *sb);
--#else
--static int yaffs_sync_fs(struct super_block *sb);
--static int yaffs_write_super(struct super_block *sb);
--#endif
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf);
--#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
--#else
--static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
--#endif
--
--#ifdef YAFFS_HAS_PUT_INODE
--static void yaffs_put_inode(struct inode *inode);
--#endif
--
--static void yaffs_delete_inode(struct inode *);
--static void yaffs_clear_inode(struct inode *);
--
--static int yaffs_readpage(struct file *file, struct page *page);
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_writepage(struct page *page, struct writeback_control *wbc);
--#else
--static int yaffs_writepage(struct page *page);
--#endif
--
--
--#if (YAFFS_USE_WRITE_BEGIN_END != 0)
--static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
--				loff_t pos, unsigned len, unsigned flags,
--				struct page **pagep, void **fsdata);
--static int yaffs_write_end(struct file *filp, struct address_space *mapping,
--				loff_t pos, unsigned len, unsigned copied,
--				struct page *pg, void *fsdadata);
--#else
--static int yaffs_prepare_write(struct file *f, struct page *pg,
--				unsigned offset, unsigned to);
--static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
--				unsigned to);
--
--#endif
--
--static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
--				int buflen);
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
--static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
--#else
--static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
--#endif
--
--static struct address_space_operations yaffs_file_address_operations = {
--	.readpage = yaffs_readpage,
--	.writepage = yaffs_writepage,
--#if (YAFFS_USE_WRITE_BEGIN_END > 0)
--	.write_begin = yaffs_write_begin,
--	.write_end = yaffs_write_end,
--#else
--	.prepare_write = yaffs_prepare_write,
--	.commit_write = yaffs_commit_write,
--#endif
--};
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
--static const struct file_operations yaffs_file_operations = {
--	.read = do_sync_read,
--	.write = do_sync_write,
--	.aio_read = generic_file_aio_read,
--	.aio_write = generic_file_aio_write,
--	.mmap = generic_file_mmap,
--	.flush = yaffs_file_flush,
--	.fsync = yaffs_sync_object,
--	.splice_read = generic_file_splice_read,
--	.splice_write = generic_file_splice_write,
--	.llseek = generic_file_llseek,
--};
--
--#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
--
--static const struct file_operations yaffs_file_operations = {
--	.read = do_sync_read,
--	.write = do_sync_write,
--	.aio_read = generic_file_aio_read,
--	.aio_write = generic_file_aio_write,
--	.mmap = generic_file_mmap,
--	.flush = yaffs_file_flush,
--	.fsync = yaffs_sync_object,
--	.sendfile = generic_file_sendfile,
--};
--
--#else
--
--static const struct file_operations yaffs_file_operations = {
--	.read = generic_file_read,
--	.write = generic_file_write,
--	.mmap = generic_file_mmap,
--	.flush = yaffs_file_flush,
--	.fsync = yaffs_sync_object,
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--	.sendfile = generic_file_sendfile,
--#endif
--};
--#endif
--
--static const struct inode_operations yaffs_file_inode_operations = {
--	.setattr = yaffs_setattr,
--};
--
--static const struct inode_operations yaffs_symlink_inode_operations = {
--	.readlink = yaffs_readlink,
--	.follow_link = yaffs_follow_link,
--	.setattr = yaffs_setattr,
--};
--
--static const struct inode_operations yaffs_dir_inode_operations = {
--	.create = yaffs_create,
--	.lookup = yaffs_lookup,
--	.link = yaffs_link,
--	.unlink = yaffs_unlink,
--	.symlink = yaffs_symlink,
--	.mkdir = yaffs_mkdir,
--	.rmdir = yaffs_unlink,
--	.mknod = yaffs_mknod,
--	.rename = yaffs_rename,
--	.setattr = yaffs_setattr,
--};
--
--static const struct file_operations yaffs_dir_operations = {
--	.read = generic_read_dir,
--	.readdir = yaffs_readdir,
--	.fsync = yaffs_sync_object,
--};
--
--static const struct super_operations yaffs_super_ops = {
--	.statfs = yaffs_statfs,
--
--#ifndef YAFFS_USE_OWN_IGET
--	.read_inode = yaffs_read_inode,
--#endif
--#ifdef YAFFS_HAS_PUT_INODE
--	.put_inode = yaffs_put_inode,
--#endif
--	.put_super = yaffs_put_super,
--	.delete_inode = yaffs_delete_inode,
--	.clear_inode = yaffs_clear_inode,
--	.sync_fs = yaffs_sync_fs,
--	.write_super = yaffs_write_super,
--};
--
--static void yaffs_GrossLock(yaffs_Device *dev)
--{
--	T(YAFFS_TRACE_OS, ("yaffs locking %p\n", current));
--	down(&dev->grossLock);
--	T(YAFFS_TRACE_OS, ("yaffs locked %p\n", current));
--}
--
--static void yaffs_GrossUnlock(yaffs_Device *dev)
--{
--	T(YAFFS_TRACE_OS, ("yaffs unlocking %p\n", current));
--	up(&dev->grossLock);
--}
--
--static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
--			int buflen)
--{
--	unsigned char *alias;
--	int ret;
--
--	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
--
--	yaffs_GrossLock(dev);
--
--	alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
--
--	yaffs_GrossUnlock(dev);
--
--	if (!alias)
--		return -ENOMEM;
--
--	ret = vfs_readlink(dentry, buffer, buflen, alias);
--	kfree(alias);
--	return ret;
--}
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
--static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
--#else
--static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
--#endif
--{
--	unsigned char *alias;
--	int ret;
--	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
--
--	yaffs_GrossLock(dev);
--
--	alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry));
--
--	yaffs_GrossUnlock(dev);
--
--	if (!alias) {
--		ret = -ENOMEM;
--		goto out;
--	}
--
--	ret = vfs_follow_link(nd, alias);
--	kfree(alias);
--out:
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
--	return ERR_PTR(ret);
--#else
--	return ret;
--#endif
--}
--
--struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
--				yaffs_Object *obj);
--
--/*
-- * Lookup is used to find objects in the fs
-- */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--
--static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
--				struct nameidata *n)
--#else
--static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
--#endif
--{
--	yaffs_Object *obj;
--	struct inode *inode = NULL;	/* NCB 2.5/2.6 needs NULL here */
--
--	yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev;
--
--	yaffs_GrossLock(dev);
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_lookup for %d:%s\n",
--		yaffs_InodeToObject(dir)->objectId, dentry->d_name.name));
--
--	obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),
--					dentry->d_name.name);
--
--	obj = yaffs_GetEquivalentObject(obj);	/* in case it was a hardlink */
--
--	/* Can't hold gross lock when calling yaffs_get_inode() */
--	yaffs_GrossUnlock(dev);
--
--	if (obj) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_lookup found %d\n", obj->objectId));
--
--		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
--
--		if (inode) {
--			T(YAFFS_TRACE_OS,
--				("yaffs_loookup dentry \n"));
--/* #if 0 asserted by NCB for 2.5/6 compatability - falls through to
-- * d_add even if NULL inode */
--#if 0
--			/*dget(dentry); // try to solve directory bug */
--			d_add(dentry, inode);
--
--			/* return dentry; */
--			return NULL;
--#endif
--		}
--
--	} else {
--		T(YAFFS_TRACE_OS, ("yaffs_lookup not found\n"));
--
--	}
--
--/* added NCB for 2.5/6 compatability - forces add even if inode is
-- * NULL which creates dentry hash */
--	d_add(dentry, inode);
--
--	return NULL;
--}
--
--
--#ifdef YAFFS_HAS_PUT_INODE
--
--/* For now put inode is just for debugging
-- * Put inode is called when the inode **structure** is put.
-- */
--static void yaffs_put_inode(struct inode *inode)
--{
--	T(YAFFS_TRACE_OS,
--		("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino,
--		atomic_read(&inode->i_count)));
--
--}
--#endif
--
--/* clear is called to tell the fs to release any per-inode data it holds */
--static void yaffs_clear_inode(struct inode *inode)
--{
--	yaffs_Object *obj;
--	yaffs_Device *dev;
--
--	obj = yaffs_InodeToObject(inode);
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino,
--		atomic_read(&inode->i_count),
--		obj ? "object exists" : "null object"));
--
--	if (obj) {
--		dev = obj->myDev;
--		yaffs_GrossLock(dev);
--
--		/* Clear the association between the inode and
--		 * the yaffs_Object.
--		 */
--		obj->myInode = NULL;
--		yaffs_InodeToObjectLV(inode) = NULL;
--
--		/* If the object freeing was deferred, then the real
--		 * free happens now.
--		 * This should fix the inode inconsistency problem.
--		 */
--
--		yaffs_HandleDeferedFree(obj);
--
--		yaffs_GrossUnlock(dev);
--	}
--
--}
--
--/* delete is called when the link count is zero and the inode
-- * is put (ie. nobody wants to know about it anymore, time to
-- * delete the file).
-- * NB Must call clear_inode()
-- */
--static void yaffs_delete_inode(struct inode *inode)
--{
--	yaffs_Object *obj = yaffs_InodeToObject(inode);
--	yaffs_Device *dev;
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino,
--		atomic_read(&inode->i_count),
--		obj ? "object exists" : "null object"));
--
--	if (obj) {
--		dev = obj->myDev;
--		yaffs_GrossLock(dev);
--		yaffs_DeleteObject(obj);
--		yaffs_GrossUnlock(dev);
--	}
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
--	truncate_inode_pages(&inode->i_data, 0);
--#endif
--	clear_inode(inode);
--}
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static int yaffs_file_flush(struct file *file, fl_owner_t id)
--#else
--static int yaffs_file_flush(struct file *file)
--#endif
--{
--	yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry);
--
--	yaffs_Device *dev = obj->myDev;
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_file_flush object %d (%s)\n", obj->objectId,
--		obj->dirty ? "dirty" : "clean"));
--
--	yaffs_GrossLock(dev);
--
--	yaffs_FlushFile(obj, 1);
--
--	yaffs_GrossUnlock(dev);
--
--	return 0;
--}
--
--static int yaffs_readpage_nolock(struct file *f, struct page *pg)
--{
--	/* Lifted from jffs2 */
--
--	yaffs_Object *obj;
--	unsigned char *pg_buf;
--	int ret;
--
--	yaffs_Device *dev;
--
--	T(YAFFS_TRACE_OS, ("yaffs_readpage at %08x, size %08x\n",
--			(unsigned)(pg->index << PAGE_CACHE_SHIFT),
--			(unsigned)PAGE_CACHE_SIZE));
--
--	obj = yaffs_DentryToObject(f->f_dentry);
--
--	dev = obj->myDev;
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--	BUG_ON(!PageLocked(pg));
--#else
--	if (!PageLocked(pg))
--		PAGE_BUG(pg);
--#endif
--
--	pg_buf = kmap(pg);
--	/* FIXME: Can kmap fail? */
--
--	yaffs_GrossLock(dev);
--
--	ret = yaffs_ReadDataFromFile(obj, pg_buf,
--				pg->index << PAGE_CACHE_SHIFT,
--				PAGE_CACHE_SIZE);
--
--	yaffs_GrossUnlock(dev);
--
--	if (ret >= 0)
--		ret = 0;
--
--	if (ret) {
--		ClearPageUptodate(pg);
--		SetPageError(pg);
--	} else {
--		SetPageUptodate(pg);
--		ClearPageError(pg);
--	}
--
--	flush_dcache_page(pg);
--	kunmap(pg);
--
--	T(YAFFS_TRACE_OS, ("yaffs_readpage done\n"));
--	return ret;
--}
--
--static int yaffs_readpage_unlock(struct file *f, struct page *pg)
--{
--	int ret = yaffs_readpage_nolock(f, pg);
--	UnlockPage(pg);
--	return ret;
--}
--
--static int yaffs_readpage(struct file *f, struct page *pg)
--{
--	return yaffs_readpage_unlock(f, pg);
--}
--
--/* writepage inspired by/stolen from smbfs */
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_writepage(struct page *page, struct writeback_control *wbc)
--#else
--static int yaffs_writepage(struct page *page)
--#endif
--{
--	struct address_space *mapping = page->mapping;
--	loff_t offset = (loff_t) page->index << PAGE_CACHE_SHIFT;
--	struct inode *inode;
--	unsigned long end_index;
--	char *buffer;
--	yaffs_Object *obj;
--	int nWritten = 0;
--	unsigned nBytes;
--
--	if (!mapping)
--		BUG();
--	inode = mapping->host;
--	if (!inode)
--		BUG();
--
--	if (offset > inode->i_size) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_writepage at %08x, inode size = %08x!!!\n",
--			(unsigned)(page->index << PAGE_CACHE_SHIFT),
--			(unsigned)inode->i_size));
--		T(YAFFS_TRACE_OS,
--			("                -> don't care!!\n"));
--		unlock_page(page);
--		return 0;
--	}
--
--	end_index = inode->i_size >> PAGE_CACHE_SHIFT;
--
--	/* easy case */
--	if (page->index < end_index)
--		nBytes = PAGE_CACHE_SIZE;
--	else
--		nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1);
--
--	get_page(page);
--
--	buffer = kmap(page);
--
--	obj = yaffs_InodeToObject(inode);
--	yaffs_GrossLock(obj->myDev);
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_writepage at %08x, size %08x\n",
--		(unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes));
--	T(YAFFS_TRACE_OS,
--		("writepag0: obj = %05x, ino = %05x\n",
--		(int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
--
--	nWritten = yaffs_WriteDataToFile(obj, buffer,
--			page->index << PAGE_CACHE_SHIFT, nBytes, 0);
--
--	T(YAFFS_TRACE_OS,
--		("writepag1: obj = %05x, ino = %05x\n",
--		(int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
--
--	yaffs_GrossUnlock(obj->myDev);
--
--	kunmap(page);
--	SetPageUptodate(page);
--	UnlockPage(page);
--	put_page(page);
--
--	return (nWritten == nBytes) ? 0 : -ENOSPC;
--}
--
--
--#if (YAFFS_USE_WRITE_BEGIN_END > 0)
--static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
--				loff_t pos, unsigned len, unsigned flags,
--				struct page **pagep, void **fsdata)
--{
--	struct page *pg = NULL;
--	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
--	uint32_t offset = pos & (PAGE_CACHE_SIZE - 1);
--	uint32_t to = offset + len;
--
--	int ret = 0;
--	int space_held = 0;
--
--	T(YAFFS_TRACE_OS, ("start yaffs_write_begin\n"));
--	/* Get a page */
--#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28)
--	pg = grab_cache_page_write_begin(mapping, index, flags);
--#else
--	pg = __grab_cache_page(mapping, index);
--#endif
--
--	*pagep = pg;
--	if (!pg) {
--		ret =  -ENOMEM;
--		goto out;
--	}
--	/* Get fs space */
--	space_held = yaffs_hold_space(filp);
--
--	if (!space_held) {
--		ret = -ENOSPC;
--		goto out;
--	}
--
--	/* Update page if required */
--
--	if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
--		ret = yaffs_readpage_nolock(filp, pg);
--
--	if (ret)
--		goto out;
--
--	/* Happy path return */
--	T(YAFFS_TRACE_OS, ("end yaffs_write_begin - ok\n"));
--
--	return 0;
--
--out:
--	T(YAFFS_TRACE_OS, ("end yaffs_write_begin fail returning %d\n", ret));
--	if (space_held)
--		yaffs_release_space(filp);
--	if (pg) {
--		unlock_page(pg);
--		page_cache_release(pg);
--	}
--	return ret;
--}
--
--#else
--
--static int yaffs_prepare_write(struct file *f, struct page *pg,
--				unsigned offset, unsigned to)
--{
--	T(YAFFS_TRACE_OS, ("yaffs_prepair_write\n"));
--
--	if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
--		return yaffs_readpage_nolock(f, pg);
--	return 0;
--}
--#endif
--
--#if (YAFFS_USE_WRITE_BEGIN_END > 0)
--static int yaffs_write_end(struct file *filp, struct address_space *mapping,
--				loff_t pos, unsigned len, unsigned copied,
--				struct page *pg, void *fsdadata)
--{
--	int ret = 0;
--	void *addr, *kva;
--	uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);
--
--	kva = kmap(pg);
--	addr = kva + offset_into_page;
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_write_end addr %x pos %x nBytes %d\n",
--		(unsigned) addr,
--		(int)pos, copied));
--
--	ret = yaffs_file_write(filp, addr, copied, &pos);
--
--	if (ret != copied) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_write_end not same size ret %d  copied %d\n",
--			ret, copied));
--		SetPageError(pg);
--		ClearPageUptodate(pg);
--	} else {
--		SetPageUptodate(pg);
--	}
--
--	kunmap(pg);
--
--	yaffs_release_space(filp);
--	unlock_page(pg);
--	page_cache_release(pg);
--	return ret;
--}
--#else
--
--static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
--				unsigned to)
--{
--	void *addr, *kva;
--
--	loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;
--	int nBytes = to - offset;
--	int nWritten;
--
--	unsigned spos = pos;
--	unsigned saddr;
--
--	kva = kmap(pg);
--	addr = kva + offset;
--
--	saddr = (unsigned) addr;
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_commit_write addr %x pos %x nBytes %d\n",
--		saddr, spos, nBytes));
--
--	nWritten = yaffs_file_write(f, addr, nBytes, &pos);
--
--	if (nWritten != nBytes) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_commit_write not same size nWritten %d  nBytes %d\n",
--			nWritten, nBytes));
--		SetPageError(pg);
--		ClearPageUptodate(pg);
--	} else {
--		SetPageUptodate(pg);
--	}
--
--	kunmap(pg);
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_commit_write returning %d\n",
--		nWritten == nBytes ? 0 : nWritten));
--
--	return nWritten == nBytes ? 0 : nWritten;
--}
--#endif
--
--
--static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
--{
--	if (inode && obj) {
--
--
--		/* Check mode against the variant type and attempt to repair if broken. */
--		__u32 mode = obj->yst_mode;
--		switch (obj->variantType) {
--		case YAFFS_OBJECT_TYPE_FILE:
--			if (!S_ISREG(mode)) {
--				obj->yst_mode &= ~S_IFMT;
--				obj->yst_mode |= S_IFREG;
--			}
--
--			break;
--		case YAFFS_OBJECT_TYPE_SYMLINK:
--			if (!S_ISLNK(mode)) {
--				obj->yst_mode &= ~S_IFMT;
--				obj->yst_mode |= S_IFLNK;
--			}
--
--			break;
--		case YAFFS_OBJECT_TYPE_DIRECTORY:
--			if (!S_ISDIR(mode)) {
--				obj->yst_mode &= ~S_IFMT;
--				obj->yst_mode |= S_IFDIR;
--			}
--
--			break;
--		case YAFFS_OBJECT_TYPE_UNKNOWN:
--		case YAFFS_OBJECT_TYPE_HARDLINK:
--		case YAFFS_OBJECT_TYPE_SPECIAL:
--		default:
--			/* TODO? */
--			break;
--		}
--
--		inode->i_flags |= S_NOATIME;
--
--		inode->i_ino = obj->objectId;
--		inode->i_mode = obj->yst_mode;
--		inode->i_uid = obj->yst_uid;
--		inode->i_gid = obj->yst_gid;
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
--		inode->i_blksize = inode->i_sb->s_blocksize;
--#endif
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--
--		inode->i_rdev = old_decode_dev(obj->yst_rdev);
--		inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
--		inode->i_atime.tv_nsec = 0;
--		inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;
--		inode->i_mtime.tv_nsec = 0;
--		inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;
--		inode->i_ctime.tv_nsec = 0;
--#else
--		inode->i_rdev = obj->yst_rdev;
--		inode->i_atime = obj->yst_atime;
--		inode->i_mtime = obj->yst_mtime;
--		inode->i_ctime = obj->yst_ctime;
--#endif
--		inode->i_size = yaffs_GetObjectFileLength(obj);
--		inode->i_blocks = (inode->i_size + 511) >> 9;
--
--		inode->i_nlink = yaffs_GetObjectLinkCount(obj);
--
--		T(YAFFS_TRACE_OS,
--			("yaffs_FillInode mode %x uid %d gid %d size %d count %d\n",
--			inode->i_mode, inode->i_uid, inode->i_gid,
--			(int)inode->i_size, atomic_read(&inode->i_count)));
--
--		switch (obj->yst_mode & S_IFMT) {
--		default:	/* fifo, device or socket */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--			init_special_inode(inode, obj->yst_mode,
--					old_decode_dev(obj->yst_rdev));
--#else
--			init_special_inode(inode, obj->yst_mode,
--					(dev_t) (obj->yst_rdev));
--#endif
--			break;
--		case S_IFREG:	/* file */
--			inode->i_op = &yaffs_file_inode_operations;
--			inode->i_fop = &yaffs_file_operations;
--			inode->i_mapping->a_ops =
--				&yaffs_file_address_operations;
--			break;
--		case S_IFDIR:	/* directory */
--			inode->i_op = &yaffs_dir_inode_operations;
--			inode->i_fop = &yaffs_dir_operations;
--			break;
--		case S_IFLNK:	/* symlink */
--			inode->i_op = &yaffs_symlink_inode_operations;
--			break;
--		}
--
--		yaffs_InodeToObjectLV(inode) = obj;
--
--		obj->myInode = inode;
--
--	} else {
--		T(YAFFS_TRACE_OS,
--			("yaffs_FileInode invalid parameters\n"));
--	}
--
--}
--
--struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
--				yaffs_Object *obj)
--{
--	struct inode *inode;
--
--	if (!sb) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_get_inode for NULL super_block!!\n"));
--		return NULL;
--
--	}
--
--	if (!obj) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_get_inode for NULL object!!\n"));
--		return NULL;
--
--	}
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_get_inode for object %d\n", obj->objectId));
--
--	inode = Y_IGET(sb, obj->objectId);
--	if (IS_ERR(inode))
--		return NULL;
--
--	/* NB Side effect: iget calls back to yaffs_read_inode(). */
--	/* iget also increments the inode's i_count */
--	/* NB You can't be holding grossLock or deadlock will happen! */
--
--	return inode;
--}
--
--static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
--				loff_t *pos)
--{
--	yaffs_Object *obj;
--	int nWritten, ipos;
--	struct inode *inode;
--	yaffs_Device *dev;
--
--	obj = yaffs_DentryToObject(f->f_dentry);
--
--	dev = obj->myDev;
--
--	yaffs_GrossLock(dev);
--
--	inode = f->f_dentry->d_inode;
--
--	if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
--		ipos = inode->i_size;
--	else
--		ipos = *pos;
--
--	if (!obj)
--		T(YAFFS_TRACE_OS,
--			("yaffs_file_write: hey obj is null!\n"));
--	else
--		T(YAFFS_TRACE_OS,
--			("yaffs_file_write about to write writing %zu bytes"
--			"to object %d at %d\n",
--			n, obj->objectId, ipos));
--
--	nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0);
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_file_write writing %zu bytes, %d written at %d\n",
--		n, nWritten, ipos));
--
--	if (nWritten > 0) {
--		ipos += nWritten;
--		*pos = ipos;
--		if (ipos > inode->i_size) {
--			inode->i_size = ipos;
--			inode->i_blocks = (ipos + 511) >> 9;
--
--			T(YAFFS_TRACE_OS,
--				("yaffs_file_write size updated to %d bytes, "
--				"%d blocks\n",
--				ipos, (int)(inode->i_blocks)));
--		}
--
--	}
--	yaffs_GrossUnlock(dev);
--	return nWritten == 0 ? -ENOSPC : nWritten;
--}
--
--/* Space holding and freeing is done to ensure we have space available for write_begin/end */
--/* For now we just assume few parallel writes and check against a small number. */
--/* Todo: need to do this with a counter to handle parallel reads better */
--
--static ssize_t yaffs_hold_space(struct file *f)
--{
--	yaffs_Object *obj;
--	yaffs_Device *dev;
--
--	int nFreeChunks;
--
--
--	obj = yaffs_DentryToObject(f->f_dentry);
--
--	dev = obj->myDev;
--
--	yaffs_GrossLock(dev);
--
--	nFreeChunks = yaffs_GetNumberOfFreeChunks(dev);
--
--	yaffs_GrossUnlock(dev);
--
--	return (nFreeChunks > 20) ? 1 : 0;
--}
--
--static void yaffs_release_space(struct file *f)
--{
--	yaffs_Object *obj;
--	yaffs_Device *dev;
--
--
--	obj = yaffs_DentryToObject(f->f_dentry);
--
--	dev = obj->myDev;
--
--	yaffs_GrossLock(dev);
--
--
--	yaffs_GrossUnlock(dev);
--}
--
--static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
--{
--	yaffs_Object *obj;
--	yaffs_Device *dev;
--	struct inode *inode = f->f_dentry->d_inode;
--	unsigned long offset, curoffs;
--	struct ylist_head *i;
--	yaffs_Object *l;
--
--	char name[YAFFS_MAX_NAME_LENGTH + 1];
--
--	obj = yaffs_DentryToObject(f->f_dentry);
--	dev = obj->myDev;
--
--	yaffs_GrossLock(dev);
--
--	offset = f->f_pos;
--
--	T(YAFFS_TRACE_OS, ("yaffs_readdir: starting at %d\n", (int)offset));
--
--	if (offset == 0) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_readdir: entry . ino %d \n",
--			(int)inode->i_ino));
--		if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0)
--			goto out;
--		offset++;
--		f->f_pos++;
--	}
--	if (offset == 1) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_readdir: entry .. ino %d \n",
--			(int)f->f_dentry->d_parent->d_inode->i_ino));
--		if (filldir(dirent, "..", 2, offset,
--			f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
--			goto out;
--		offset++;
--		f->f_pos++;
--	}
--
--	curoffs = 1;
--
--	/* If the directory has changed since the open or last call to
--	   readdir, rewind to after the 2 canned entries. */
--
--	if (f->f_version != inode->i_version) {
--		offset = 2;
--		f->f_pos = offset;
--		f->f_version = inode->i_version;
--	}
--
--	ylist_for_each(i, &obj->variant.directoryVariant.children) {
--		curoffs++;
--		if (curoffs >= offset) {
--			l = ylist_entry(i, yaffs_Object, siblings);
--
--			yaffs_GetObjectName(l, name,
--					    YAFFS_MAX_NAME_LENGTH + 1);
--			T(YAFFS_TRACE_OS,
--			  ("yaffs_readdir: %s inode %d\n", name,
--			   yaffs_GetObjectInode(l)));
--
--			if (filldir(dirent,
--					name,
--					strlen(name),
--					offset,
--					yaffs_GetObjectInode(l),
--					yaffs_GetObjectType(l)) < 0)
--				goto up_and_out;
--
--			offset++;
--			f->f_pos++;
--		}
--	}
--
--up_and_out:
--out:
--	yaffs_GrossUnlock(dev);
--
--	return 0;
--}
--
--/*
-- * File creation. Allocate an inode, and we're done..
-- */
--
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
--#define YCRED(x) x
--#else
--#define YCRED(x) (x->cred)
--#endif
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
--			dev_t rdev)
--#else
--static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
--			int rdev)
--#endif
--{
--	struct inode *inode;
--
--	yaffs_Object *obj = NULL;
--	yaffs_Device *dev;
--
--	yaffs_Object *parent = yaffs_InodeToObject(dir);
--
--	int error = -ENOSPC;
--	uid_t uid = YCRED(current)->fsuid;
--	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
--
--	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
--		mode |= S_ISGID;
--
--	if (parent) {
--		T(YAFFS_TRACE_OS,
--			("yaffs_mknod: parent object %d type %d\n",
--			parent->objectId, parent->variantType));
--	} else {
--		T(YAFFS_TRACE_OS,
--			("yaffs_mknod: could not get parent object\n"));
--		return -EPERM;
--	}
--
--	T(YAFFS_TRACE_OS, ("yaffs_mknod: making oject for %s, "
--			"mode %x dev %x\n",
--			dentry->d_name.name, mode, rdev));
--
--	dev = parent->myDev;
--
--	yaffs_GrossLock(dev);
--
--	switch (mode & S_IFMT) {
--	default:
--		/* Special (socket, fifo, device...) */
--		T(YAFFS_TRACE_OS, ("yaffs_mknod: making special\n"));
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--		obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
--				gid, old_encode_dev(rdev));
--#else
--		obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
--				gid, rdev);
--#endif
--		break;
--	case S_IFREG:		/* file          */
--		T(YAFFS_TRACE_OS, ("yaffs_mknod: making file\n"));
--		obj = yaffs_MknodFile(parent, dentry->d_name.name, mode, uid,
--				gid);
--		break;
--	case S_IFDIR:		/* directory */
--		T(YAFFS_TRACE_OS,
--			("yaffs_mknod: making directory\n"));
--		obj = yaffs_MknodDirectory(parent, dentry->d_name.name, mode,
--					uid, gid);
--		break;
--	case S_IFLNK:		/* symlink */
--		T(YAFFS_TRACE_OS, ("yaffs_mknod: making symlink\n"));
--		obj = NULL;	/* Do we ever get here? */
--		break;
--	}
--
--	/* Can not call yaffs_get_inode() with gross lock held */
--	yaffs_GrossUnlock(dev);
--
--	if (obj) {
--		inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
--		d_instantiate(dentry, inode);
--		T(YAFFS_TRACE_OS,
--			("yaffs_mknod created object %d count = %d\n",
--			obj->objectId, atomic_read(&inode->i_count)));
--		error = 0;
--	} else {
--		T(YAFFS_TRACE_OS,
--			("yaffs_mknod failed making object\n"));
--		error = -ENOMEM;
--	}
--
--	return error;
--}
--
--static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
--{
--	int retVal;
--	T(YAFFS_TRACE_OS, ("yaffs_mkdir\n"));
--	retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
--	return retVal;
--}
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
--			struct nameidata *n)
--#else
--static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
--#endif
--{
--	T(YAFFS_TRACE_OS, ("yaffs_create\n"));
--	return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
--}
--
--static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
--{
--	int retVal;
--
--	yaffs_Device *dev;
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_unlink %d:%s\n", (int)(dir->i_ino),
--		dentry->d_name.name));
--
--	dev = yaffs_InodeToObject(dir)->myDev;
--
--	yaffs_GrossLock(dev);
--
--	retVal = yaffs_Unlink(yaffs_InodeToObject(dir), dentry->d_name.name);
--
--	if (retVal == YAFFS_OK) {
--		dentry->d_inode->i_nlink--;
--		dir->i_version++;
--		yaffs_GrossUnlock(dev);
--		mark_inode_dirty(dentry->d_inode);
--		return 0;
--	}
--	yaffs_GrossUnlock(dev);
--	return -ENOTEMPTY;
--}
--
--/*
-- * Create a link...
-- */
--static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
--			struct dentry *dentry)
--{
--	struct inode *inode = old_dentry->d_inode;
--	yaffs_Object *obj = NULL;
--	yaffs_Object *link = NULL;
--	yaffs_Device *dev;
--
--	T(YAFFS_TRACE_OS, ("yaffs_link\n"));
--
--	obj = yaffs_InodeToObject(inode);
--	dev = obj->myDev;
--
--	yaffs_GrossLock(dev);
--
--	if (!S_ISDIR(inode->i_mode))		/* Don't link directories */
--		link = yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name,
--			obj);
--
--	if (link) {
--		old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj);
--		d_instantiate(dentry, old_dentry->d_inode);
--		atomic_inc(&old_dentry->d_inode->i_count);
--		T(YAFFS_TRACE_OS,
--			("yaffs_link link count %d i_count %d\n",
--			old_dentry->d_inode->i_nlink,
--			atomic_read(&old_dentry->d_inode->i_count)));
--	}
--
--	yaffs_GrossUnlock(dev);
--
--	if (link)
--		return 0;
--
--	return -EPERM;
--}
--
--static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
--				const char *symname)
--{
--	yaffs_Object *obj;
--	yaffs_Device *dev;
--	uid_t uid = YCRED(current)->fsuid;
--	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
--
--	T(YAFFS_TRACE_OS, ("yaffs_symlink\n"));
--
--	dev = yaffs_InodeToObject(dir)->myDev;
--	yaffs_GrossLock(dev);
--	obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name,
--				S_IFLNK | S_IRWXUGO, uid, gid, symname);
--	yaffs_GrossUnlock(dev);
--
--	if (obj) {
--		struct inode *inode;
--
--		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
--		d_instantiate(dentry, inode);
--		T(YAFFS_TRACE_OS, ("symlink created OK\n"));
--		return 0;
--	} else {
--		T(YAFFS_TRACE_OS, ("symlink not created\n"));
--	}
--
--	return -ENOMEM;
--}
--
--static int yaffs_sync_object(struct file *file, struct dentry *dentry,
--				int datasync)
--{
--
--	yaffs_Object *obj;
--	yaffs_Device *dev;
--
--	obj = yaffs_DentryToObject(dentry);
--
--	dev = obj->myDev;
--
--	T(YAFFS_TRACE_OS, ("yaffs_sync_object\n"));
--	yaffs_GrossLock(dev);
--	yaffs_FlushFile(obj, 1);
--	yaffs_GrossUnlock(dev);
--	return 0;
--}
--
--/*
-- * The VFS layer already does all the dentry stuff for rename.
-- *
-- * NB: POSIX says you can rename an object over an old object of the same name
-- */
--static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
--			struct inode *new_dir, struct dentry *new_dentry)
--{
--	yaffs_Device *dev;
--	int retVal = YAFFS_FAIL;
--	yaffs_Object *target;
--
--	T(YAFFS_TRACE_OS, ("yaffs_rename\n"));
--	dev = yaffs_InodeToObject(old_dir)->myDev;
--
--	yaffs_GrossLock(dev);
--
--	/* Check if the target is an existing directory that is not empty. */
--	target = yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),
--				new_dentry->d_name.name);
--
--
--
--	if (target && target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
--		!ylist_empty(&target->variant.directoryVariant.children)) {
--
--		T(YAFFS_TRACE_OS, ("target is non-empty dir\n"));
--
--		retVal = YAFFS_FAIL;
--	} else {
--		/* Now does unlinking internally using shadowing mechanism */
--		T(YAFFS_TRACE_OS, ("calling yaffs_RenameObject\n"));
--
--		retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),
--				old_dentry->d_name.name,
--				yaffs_InodeToObject(new_dir),
--				new_dentry->d_name.name);
--	}
--	yaffs_GrossUnlock(dev);
--
--	if (retVal == YAFFS_OK) {
--		if (target) {
--			new_dentry->d_inode->i_nlink--;
--			mark_inode_dirty(new_dentry->d_inode);
--		}
--
--		return 0;
--	} else {
--		return -ENOTEMPTY;
--	}
--}
--
--static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
--{
--	struct inode *inode = dentry->d_inode;
--	int error;
--	yaffs_Device *dev;
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_setattr of object %d\n",
--		yaffs_InodeToObject(inode)->objectId));
--
--	error = inode_change_ok(inode, attr);
--	if (error == 0) {
--		dev = yaffs_InodeToObject(inode)->myDev;
--		yaffs_GrossLock(dev);
--		if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) ==
--				YAFFS_OK) {
--			error = 0;
--		} else {
--			error = -EPERM;
--		}
--		yaffs_GrossUnlock(dev);
--		if (!error)
--			error = inode_setattr(inode, attr);
--	}
--	return error;
--}
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
--{
--	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
--	struct super_block *sb = dentry->d_sb;
--#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
--{
--	yaffs_Device *dev = yaffs_SuperToDevice(sb);
--#else
--static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
--{
--	yaffs_Device *dev = yaffs_SuperToDevice(sb);
--#endif
--
--	T(YAFFS_TRACE_OS, ("yaffs_statfs\n"));
--
--	yaffs_GrossLock(dev);
--
--	buf->f_type = YAFFS_MAGIC;
--	buf->f_bsize = sb->s_blocksize;
--	buf->f_namelen = 255;
--
--	if (dev->nDataBytesPerChunk & (dev->nDataBytesPerChunk - 1)) {
--		/* Do this if chunk size is not a power of 2 */
--
--		uint64_t bytesInDev;
--		uint64_t bytesFree;
--
--		bytesInDev = ((uint64_t)((dev->endBlock - dev->startBlock + 1))) *
--			((uint64_t)(dev->nChunksPerBlock * dev->nDataBytesPerChunk));
--
--		do_div(bytesInDev, sb->s_blocksize); /* bytesInDev becomes the number of blocks */
--		buf->f_blocks = bytesInDev;
--
--		bytesFree  = ((uint64_t)(yaffs_GetNumberOfFreeChunks(dev))) *
--			((uint64_t)(dev->nDataBytesPerChunk));
--
--		do_div(bytesFree, sb->s_blocksize);
--
--		buf->f_bfree = bytesFree;
--
--	} else if (sb->s_blocksize > dev->nDataBytesPerChunk) {
--
--		buf->f_blocks =
--			(dev->endBlock - dev->startBlock + 1) *
--			dev->nChunksPerBlock /
--			(sb->s_blocksize / dev->nDataBytesPerChunk);
--		buf->f_bfree =
--			yaffs_GetNumberOfFreeChunks(dev) /
--			(sb->s_blocksize / dev->nDataBytesPerChunk);
--	} else {
--		buf->f_blocks =
--			(dev->endBlock - dev->startBlock + 1) *
--			dev->nChunksPerBlock *
--			(dev->nDataBytesPerChunk / sb->s_blocksize);
--
--		buf->f_bfree =
--			yaffs_GetNumberOfFreeChunks(dev) *
--			(dev->nDataBytesPerChunk / sb->s_blocksize);
--	}
--
--	buf->f_files = 0;
--	buf->f_ffree = 0;
--	buf->f_bavail = buf->f_bfree;
--
--	yaffs_GrossUnlock(dev);
--	return 0;
--}
--
--
--static int yaffs_do_sync_fs(struct super_block *sb)
--{
--
--	yaffs_Device *dev = yaffs_SuperToDevice(sb);
--	T(YAFFS_TRACE_OS, ("yaffs_do_sync_fs\n"));
--
--	if (sb->s_dirt) {
--		yaffs_GrossLock(dev);
--
--		if (dev) {
--			yaffs_FlushEntireDeviceCache(dev);
--			yaffs_CheckpointSave(dev);
--		}
--
--		yaffs_GrossUnlock(dev);
--
--		sb->s_dirt = 0;
--	}
--	return 0;
--}
--
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static void yaffs_write_super(struct super_block *sb)
--#else
--static int yaffs_write_super(struct super_block *sb)
--#endif
--{
--
--	T(YAFFS_TRACE_OS, ("yaffs_write_super\n"));
--	if (yaffs_auto_checkpoint >= 2)
--		yaffs_do_sync_fs(sb);
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
--	return 0;
--#endif
--}
--
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static int yaffs_sync_fs(struct super_block *sb, int wait)
--#else
--static int yaffs_sync_fs(struct super_block *sb)
--#endif
--{
--	T(YAFFS_TRACE_OS, ("yaffs_sync_fs\n"));
--
--	if (yaffs_auto_checkpoint >= 1)
--		yaffs_do_sync_fs(sb);
--
--	return 0;
--}
--
--#ifdef YAFFS_USE_OWN_IGET
--
--static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino)
--{
--	struct inode *inode;
--	yaffs_Object *obj;
--	yaffs_Device *dev = yaffs_SuperToDevice(sb);
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_iget for %lu\n", ino));
--
--	inode = iget_locked(sb, ino);
--	if (!inode)
--		return ERR_PTR(-ENOMEM);
--	if (!(inode->i_state & I_NEW))
--		return inode;
--
--	/* NB This is called as a side effect of other functions, but
--	 * we had to release the lock to prevent deadlocks, so
--	 * need to lock again.
--	 */
--
--	yaffs_GrossLock(dev);
--
--	obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
--
--	yaffs_FillInodeFromObject(inode, obj);
--
--	yaffs_GrossUnlock(dev);
--
--	unlock_new_inode(inode);
--	return inode;
--}
--
--#else
--
--static void yaffs_read_inode(struct inode *inode)
--{
--	/* NB This is called as a side effect of other functions, but
--	 * we had to release the lock to prevent deadlocks, so
--	 * need to lock again.
--	 */
--
--	yaffs_Object *obj;
--	yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb);
--
--	T(YAFFS_TRACE_OS,
--		("yaffs_read_inode for %d\n", (int)inode->i_ino));
--
--	yaffs_GrossLock(dev);
--
--	obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
--
--	yaffs_FillInodeFromObject(inode, obj);
--
--	yaffs_GrossUnlock(dev);
--}
--
--#endif
--
--static YLIST_HEAD(yaffs_dev_list);
--
--#if 0 /* not used */
--static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
--{
--	yaffs_Device    *dev = yaffs_SuperToDevice(sb);
--
--	if (*flags & MS_RDONLY) {
--		struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
--
--		T(YAFFS_TRACE_OS,
--			("yaffs_remount_fs: %s: RO\n", dev->name));
--
--		yaffs_GrossLock(dev);
--
--		yaffs_FlushEntireDeviceCache(dev);
--
--		yaffs_CheckpointSave(dev);
--
--		if (mtd->sync)
--			mtd->sync(mtd);
--
--		yaffs_GrossUnlock(dev);
--	} else {
--		T(YAFFS_TRACE_OS,
--			("yaffs_remount_fs: %s: RW\n", dev->name));
--	}
--
--	return 0;
--}
--#endif
--
--static void yaffs_put_super(struct super_block *sb)
--{
--	yaffs_Device *dev = yaffs_SuperToDevice(sb);
--
--	T(YAFFS_TRACE_OS, ("yaffs_put_super\n"));
--
--	yaffs_GrossLock(dev);
--
--	yaffs_FlushEntireDeviceCache(dev);
--
--	yaffs_CheckpointSave(dev);
--
--	if (dev->putSuperFunc)
--		dev->putSuperFunc(sb);
--
--	yaffs_Deinitialise(dev);
--
--	yaffs_GrossUnlock(dev);
--
--	/* we assume this is protected by lock_kernel() in mount/umount */
--	ylist_del(&dev->devList);
--
--	if (dev->spareBuffer) {
--		YFREE(dev->spareBuffer);
--		dev->spareBuffer = NULL;
--	}
--
--	kfree(dev);
--}
--
--
--static void yaffs_MTDPutSuper(struct super_block *sb)
--{
--	struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
--
--	if (mtd->sync)
--		mtd->sync(mtd);
--
--	put_mtd_device(mtd);
--}
--
--
--static void yaffs_MarkSuperBlockDirty(void *vsb)
--{
--	struct super_block *sb = (struct super_block *)vsb;
--
--	T(YAFFS_TRACE_OS, ("yaffs_MarkSuperBlockDirty() sb = %p\n", sb));
--	if (sb)
--		sb->s_dirt = 1;
--}
--
--typedef struct {
--	int inband_tags;
--	int skip_checkpoint_read;
--	int skip_checkpoint_write;
--	int no_cache;
--} yaffs_options;
--
--#define MAX_OPT_LEN 20
--static int yaffs_parse_options(yaffs_options *options, const char *options_str)
--{
--	char cur_opt[MAX_OPT_LEN + 1];
--	int p;
--	int error = 0;
--
--	/* Parse through the options which is a comma seperated list */
--
--	while (options_str && *options_str && !error) {
--		memset(cur_opt, 0, MAX_OPT_LEN + 1);
--		p = 0;
--
--		while (*options_str && *options_str != ',') {
--			if (p < MAX_OPT_LEN) {
--				cur_opt[p] = *options_str;
--				p++;
--			}
--			options_str++;
--		}
--
--		if (!strcmp(cur_opt, "inband-tags"))
--			options->inband_tags = 1;
--		else if (!strcmp(cur_opt, "no-cache"))
--			options->no_cache = 1;
--		else if (!strcmp(cur_opt, "no-checkpoint-read"))
--			options->skip_checkpoint_read = 1;
--		else if (!strcmp(cur_opt, "no-checkpoint-write"))
--			options->skip_checkpoint_write = 1;
--		else if (!strcmp(cur_opt, "no-checkpoint")) {
--			options->skip_checkpoint_read = 1;
--			options->skip_checkpoint_write = 1;
--		} else {
--			printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
--					cur_opt);
--			error = 1;
--		}
--	}
--
--	return error;
--}
--
--static struct super_block *yaffs_internal_read_super(int yaffsVersion,
--						struct super_block *sb,
--						void *data, int silent)
--{
--	int nBlocks;
--	struct inode *inode = NULL;
--	struct dentry *root;
--	yaffs_Device *dev = 0;
--	char devname_buf[BDEVNAME_SIZE + 1];
--	struct mtd_info *mtd;
--	int err;
--	char *data_str = (char *)data;
--
--	yaffs_options options;
--
--	sb->s_magic = YAFFS_MAGIC;
--	sb->s_op = &yaffs_super_ops;
--	sb->s_flags |= MS_NOATIME;
--
--	if (!sb)
--		printk(KERN_INFO "yaffs: sb is NULL\n");
--	else if (!sb->s_dev)
--		printk(KERN_INFO "yaffs: sb->s_dev is NULL\n");
--	else if (!yaffs_devname(sb, devname_buf))
--		printk(KERN_INFO "yaffs: devname is NULL\n");
--	else
--		printk(KERN_INFO "yaffs: dev is %d name is \"%s\"\n",
--		       sb->s_dev,
--		       yaffs_devname(sb, devname_buf));
--
--	if (!data_str)
--		data_str = "";
--
--	printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
--
--	memset(&options, 0, sizeof(options));
--
--	if (yaffs_parse_options(&options, data_str)) {
--		/* Option parsing failed */
--		return NULL;
--	}
--
--
--	sb->s_blocksize = PAGE_CACHE_SIZE;
--	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
--	T(YAFFS_TRACE_OS, ("yaffs_read_super: Using yaffs%d\n", yaffsVersion));
--	T(YAFFS_TRACE_OS,
--	  ("yaffs_read_super: block size %d\n", (int)(sb->s_blocksize)));
--
--#ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY
--	T(YAFFS_TRACE_OS,
--	  ("yaffs: Write verification disabled. All guarantees "
--	   "null and void\n"));
--#endif
--
--	T(YAFFS_TRACE_ALWAYS, ("yaffs: Attempting MTD mount on %u.%u, "
--			       "\"%s\"\n",
--			       MAJOR(sb->s_dev), MINOR(sb->s_dev),
--			       yaffs_devname(sb, devname_buf)));
--
--	/* Check it's an mtd device..... */
--	if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR)
--		return NULL;	/* This isn't an mtd device */
--
--	/* Get the device */
--	mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
--	if (!mtd) {
--		T(YAFFS_TRACE_ALWAYS,
--		  ("yaffs: MTD device #%u doesn't appear to exist\n",
--		   MINOR(sb->s_dev)));
--		return NULL;
--	}
--	/* Check it's NAND */
--	if (mtd->type != MTD_NANDFLASH) {
--		T(YAFFS_TRACE_ALWAYS,
--		  ("yaffs: MTD device is not NAND it's type %d\n", mtd->type));
--		return NULL;
--	}
--
--	T(YAFFS_TRACE_OS, (" erase %p\n", mtd->erase));
--	T(YAFFS_TRACE_OS, (" read %p\n", mtd->read));
--	T(YAFFS_TRACE_OS, (" write %p\n", mtd->write));
--	T(YAFFS_TRACE_OS, (" readoob %p\n", mtd->read_oob));
--	T(YAFFS_TRACE_OS, (" writeoob %p\n", mtd->write_oob));
--	T(YAFFS_TRACE_OS, (" block_isbad %p\n", mtd->block_isbad));
--	T(YAFFS_TRACE_OS, (" block_markbad %p\n", mtd->block_markbad));
--	T(YAFFS_TRACE_OS, (" %s %d\n", WRITE_SIZE_STR, WRITE_SIZE(mtd)));
--	T(YAFFS_TRACE_OS, (" oobsize %d\n", mtd->oobsize));
--	T(YAFFS_TRACE_OS, (" erasesize %d\n", mtd->erasesize));
--#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
--	T(YAFFS_TRACE_OS, (" size %u\n", mtd->size));
--#else
--	T(YAFFS_TRACE_OS, (" size %lld\n", mtd->size));
--#endif
--
--#ifdef CONFIG_YAFFS_AUTO_YAFFS2
--
--	if (yaffsVersion == 1 && WRITE_SIZE(mtd) >= 2048) {
--		T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs2\n"));
--		yaffsVersion = 2;
--	}
--
--	/* Added NCB 26/5/2006 for completeness */
--	if (yaffsVersion == 2 && !options.inband_tags && WRITE_SIZE(mtd) == 512) {
--		T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs1\n"));
--		yaffsVersion = 1;
--	}
--
--#endif
--
--	if (yaffsVersion == 2) {
--		/* Check for version 2 style functions */
--		if (!mtd->erase ||
--		    !mtd->block_isbad ||
--		    !mtd->block_markbad ||
--		    !mtd->read ||
--		    !mtd->write ||
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--		    !mtd->read_oob || !mtd->write_oob) {
--#else
--		    !mtd->write_ecc ||
--		    !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {
--#endif
--			T(YAFFS_TRACE_ALWAYS,
--			  ("yaffs: MTD device does not support required "
--			   "functions\n"));;
--			return NULL;
--		}
--
--		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
--		    mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&
--		    !options.inband_tags) {
--			T(YAFFS_TRACE_ALWAYS,
--			  ("yaffs: MTD device does not have the "
--			   "right page sizes\n"));
--			return NULL;
--		}
--	} else {
--		/* Check for V1 style functions */
--		if (!mtd->erase ||
--		    !mtd->read ||
--		    !mtd->write ||
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--		    !mtd->read_oob || !mtd->write_oob) {
--#else
--		    !mtd->write_ecc ||
--		    !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {
--#endif
--			T(YAFFS_TRACE_ALWAYS,
--			  ("yaffs: MTD device does not support required "
--			   "functions\n"));;
--			return NULL;
--		}
--
--		if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK ||
--		    mtd->oobsize != YAFFS_BYTES_PER_SPARE) {
--			T(YAFFS_TRACE_ALWAYS,
--			  ("yaffs: MTD device does not support have the "
--			   "right page sizes\n"));
--			return NULL;
--		}
--	}
--
--	/* OK, so if we got here, we have an MTD that's NAND and looks
--	 * like it has the right capabilities
--	 * Set the yaffs_Device up for mtd
--	 */
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--	sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
--#else
--	sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
--#endif
--	if (!dev) {
--		/* Deep shit could not allocate device structure */
--		T(YAFFS_TRACE_ALWAYS,
--		  ("yaffs_read_super: Failed trying to allocate "
--		   "yaffs_Device. \n"));
--		return NULL;
--	}
--
--	memset(dev, 0, sizeof(yaffs_Device));
--	dev->genericDevice = mtd;
--	dev->name = mtd->name;
--
--	/* Set up the memory size parameters.... */
--
--	nBlocks = YCALCBLOCKS(mtd->size, (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK));
--
--	dev->startBlock = 0;
--	dev->endBlock = nBlocks - 1;
--	dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
--	dev->totalBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
--	dev->nReservedBlocks = 5;
--	dev->nShortOpCaches = (options.no_cache) ? 0 : 10;
--	dev->inbandTags = options.inband_tags;
--
--	/* ... and the functions. */
--	if (yaffsVersion == 2) {
--		dev->writeChunkWithTagsToNAND =
--		    nandmtd2_WriteChunkWithTagsToNAND;
--		dev->readChunkWithTagsFromNAND =
--		    nandmtd2_ReadChunkWithTagsFromNAND;
--		dev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad;
--		dev->queryNANDBlock = nandmtd2_QueryNANDBlock;
--		dev->spareBuffer = YMALLOC(mtd->oobsize);
--		dev->isYaffs2 = 1;
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--		dev->totalBytesPerChunk = mtd->writesize;
--		dev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
--#else
--		dev->totalBytesPerChunk = mtd->oobblock;
--		dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
--#endif
--		nBlocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
--
--		dev->startBlock = 0;
--		dev->endBlock = nBlocks - 1;
--	} else {
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--		/* use the MTD interface in yaffs_mtdif1.c */
--		dev->writeChunkWithTagsToNAND =
--			nandmtd1_WriteChunkWithTagsToNAND;
--		dev->readChunkWithTagsFromNAND =
--			nandmtd1_ReadChunkWithTagsFromNAND;
--		dev->markNANDBlockBad = nandmtd1_MarkNANDBlockBad;
--		dev->queryNANDBlock = nandmtd1_QueryNANDBlock;
--#else
--		dev->writeChunkToNAND = nandmtd_WriteChunkToNAND;
--		dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND;
--#endif
--		dev->isYaffs2 = 0;
--	}
--	/* ... and common functions */
--	dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND;
--	dev->initialiseNAND = nandmtd_InitialiseNAND;
--
--	dev->putSuperFunc = yaffs_MTDPutSuper;
--
--	dev->superBlock = (void *)sb;
--	dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty;
--
--
--#ifndef CONFIG_YAFFS_DOES_ECC
--	dev->useNANDECC = 1;
--#endif
--
--#ifdef CONFIG_YAFFS_DISABLE_WIDE_TNODES
--	dev->wideTnodesDisabled = 1;
--#endif
--
--	dev->skipCheckpointRead = options.skip_checkpoint_read;
--	dev->skipCheckpointWrite = options.skip_checkpoint_write;
--
--	/* we assume this is protected by lock_kernel() in mount/umount */
--	ylist_add_tail(&dev->devList, &yaffs_dev_list);
--
--	init_MUTEX(&dev->grossLock);
--
--	yaffs_GrossLock(dev);
--
--	err = yaffs_GutsInitialise(dev);
--
--	T(YAFFS_TRACE_OS,
--	  ("yaffs_read_super: guts initialised %s\n",
--	   (err == YAFFS_OK) ? "OK" : "FAILED"));
--
--	/* Release lock before yaffs_get_inode() */
--	yaffs_GrossUnlock(dev);
--
--	/* Create root inode */
--	if (err == YAFFS_OK)
--		inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,
--					yaffs_Root(dev));
--
--	if (!inode)
--		return NULL;
--
--	inode->i_op = &yaffs_dir_inode_operations;
--	inode->i_fop = &yaffs_dir_operations;
--
--	T(YAFFS_TRACE_OS, ("yaffs_read_super: got root inode\n"));
--
--	root = d_alloc_root(inode);
--
--	T(YAFFS_TRACE_OS, ("yaffs_read_super: d_alloc_root done\n"));
--
--	if (!root) {
--		iput(inode);
--		return NULL;
--	}
--	sb->s_root = root;
--	sb->s_dirt = !dev->isCheckpointed;
--	T(YAFFS_TRACE_ALWAYS,
--	  ("yaffs_read_super: isCheckpointed %d\n", dev->isCheckpointed));
--
--	T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n"));
--	return sb;
--}
--
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
--					 int silent)
--{
--	return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
--}
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static int yaffs_read_super(struct file_system_type *fs,
--			    int flags, const char *dev_name,
--			    void *data, struct vfsmount *mnt)
--{
--
--	return get_sb_bdev(fs, flags, dev_name, data,
--			   yaffs_internal_read_super_mtd, mnt);
--}
--#else
--static struct super_block *yaffs_read_super(struct file_system_type *fs,
--					    int flags, const char *dev_name,
--					    void *data)
--{
--
--	return get_sb_bdev(fs, flags, dev_name, data,
--			   yaffs_internal_read_super_mtd);
--}
--#endif
--
--static struct file_system_type yaffs_fs_type = {
--	.owner = THIS_MODULE,
--	.name = "yaffs",
--	.get_sb = yaffs_read_super,
--	.kill_sb = kill_block_super,
--	.fs_flags = FS_REQUIRES_DEV,
--};
--#else
--static struct super_block *yaffs_read_super(struct super_block *sb, void *data,
--					    int silent)
--{
--	return yaffs_internal_read_super(1, sb, data, silent);
--}
--
--static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,
--		      FS_REQUIRES_DEV);
--#endif
--
--
--#ifdef CONFIG_YAFFS_YAFFS2
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
--static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
--					  int silent)
--{
--	return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
--}
--
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--static int yaffs2_read_super(struct file_system_type *fs,
--			int flags, const char *dev_name, void *data,
--			struct vfsmount *mnt)
--{
--	return get_sb_bdev(fs, flags, dev_name, data,
--			yaffs2_internal_read_super_mtd, mnt);
--}
--#else
--static struct super_block *yaffs2_read_super(struct file_system_type *fs,
--					     int flags, const char *dev_name,
--					     void *data)
--{
--
--	return get_sb_bdev(fs, flags, dev_name, data,
--			   yaffs2_internal_read_super_mtd);
--}
--#endif
--
--static struct file_system_type yaffs2_fs_type = {
--	.owner = THIS_MODULE,
--	.name = "yaffs2",
--	.get_sb = yaffs2_read_super,
--	.kill_sb = kill_block_super,
--	.fs_flags = FS_REQUIRES_DEV,
--};
--#else
--static struct super_block *yaffs2_read_super(struct super_block *sb,
--					     void *data, int silent)
--{
--	return yaffs_internal_read_super(2, sb, data, silent);
--}
--
--static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
--		      FS_REQUIRES_DEV);
--#endif
--
--#endif				/* CONFIG_YAFFS_YAFFS2 */
--
--static struct proc_dir_entry *my_proc_entry;
--
--static char *yaffs_dump_dev(char *buf, yaffs_Device * dev)
--{
--	buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock);
--	buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock);
--	buf += sprintf(buf, "totalBytesPerChunk. %d\n", dev->totalBytesPerChunk);
--	buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk);
--	buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits);
--	buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize);
--	buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks);
--	buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks);
--	buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint);
--	buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated);
--	buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes);
--	buf += sprintf(buf, "nObjectsCreated.... %d\n", dev->nObjectsCreated);
--	buf += sprintf(buf, "nFreeObjects....... %d\n", dev->nFreeObjects);
--	buf += sprintf(buf, "nFreeChunks........ %d\n", dev->nFreeChunks);
--	buf += sprintf(buf, "nPageWrites........ %d\n", dev->nPageWrites);
--	buf += sprintf(buf, "nPageReads......... %d\n", dev->nPageReads);
--	buf += sprintf(buf, "nBlockErasures..... %d\n", dev->nBlockErasures);
--	buf += sprintf(buf, "nGCCopies.......... %d\n", dev->nGCCopies);
--	buf += sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);
--	buf += sprintf(buf, "passiveGCs......... %d\n",
--		    dev->passiveGarbageCollections);
--	buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites);
--	buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches);
--	buf += sprintf(buf, "nRetireBlocks...... %d\n", dev->nRetiredBlocks);
--	buf += sprintf(buf, "eccFixed........... %d\n", dev->eccFixed);
--	buf += sprintf(buf, "eccUnfixed......... %d\n", dev->eccUnfixed);
--	buf += sprintf(buf, "tagsEccFixed....... %d\n", dev->tagsEccFixed);
--	buf += sprintf(buf, "tagsEccUnfixed..... %d\n", dev->tagsEccUnfixed);
--	buf += sprintf(buf, "cacheHits.......... %d\n", dev->cacheHits);
--	buf += sprintf(buf, "nDeletedFiles...... %d\n", dev->nDeletedFiles);
--	buf += sprintf(buf, "nUnlinkedFiles..... %d\n", dev->nUnlinkedFiles);
--	buf +=
--	    sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions);
--	buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC);
--	buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2);
--	buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags);
--
--	return buf;
--}
--
--static int yaffs_proc_read(char *page,
--			   char **start,
--			   off_t offset, int count, int *eof, void *data)
--{
--	struct ylist_head *item;
--	char *buf = page;
--	int step = offset;
--	int n = 0;
--
--	/* Get proc_file_read() to step 'offset' by one on each sucessive call.
--	 * We use 'offset' (*ppos) to indicate where we are in devList.
--	 * This also assumes the user has posted a read buffer large
--	 * enough to hold the complete output; but that's life in /proc.
--	 */
--
--	*(int *)start = 1;
--
--	/* Print header first */
--	if (step == 0) {
--		buf += sprintf(buf, "YAFFS built:" __DATE__ " " __TIME__
--			       "\n%s\n%s\n", yaffs_fs_c_version,
--			       yaffs_guts_c_version);
--	}
--
--	/* hold lock_kernel while traversing yaffs_dev_list */
--	lock_kernel();
--
--	/* Locate and print the Nth entry.  Order N-squared but N is small. */
--	ylist_for_each(item, &yaffs_dev_list) {
--		yaffs_Device *dev = ylist_entry(item, yaffs_Device, devList);
--		if (n < step) {
--			n++;
--			continue;
--		}
--		buf += sprintf(buf, "\nDevice %d \"%s\"\n", n, dev->name);
--		buf = yaffs_dump_dev(buf, dev);
--		break;
--	}
--	unlock_kernel();
--
--	return buf - page < count ? buf - page : count;
--}
--
--/**
-- * Set the verbosity of the warnings and error messages.
-- *
-- * Note that the names can only be a..z or _ with the current code.
-- */
--
--static struct {
--	char *mask_name;
--	unsigned mask_bitfield;
--} mask_flags[] = {
--	{"allocate", YAFFS_TRACE_ALLOCATE},
--	{"always", YAFFS_TRACE_ALWAYS},
--	{"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},
--	{"buffers", YAFFS_TRACE_BUFFERS},
--	{"bug", YAFFS_TRACE_BUG},
--	{"checkpt", YAFFS_TRACE_CHECKPOINT},
--	{"deletion", YAFFS_TRACE_DELETION},
--	{"erase", YAFFS_TRACE_ERASE},
--	{"error", YAFFS_TRACE_ERROR},
--	{"gc_detail", YAFFS_TRACE_GC_DETAIL},
--	{"gc", YAFFS_TRACE_GC},
--	{"mtd", YAFFS_TRACE_MTD},
--	{"nandaccess", YAFFS_TRACE_NANDACCESS},
--	{"os", YAFFS_TRACE_OS},
--	{"scan_debug", YAFFS_TRACE_SCAN_DEBUG},
--	{"scan", YAFFS_TRACE_SCAN},
--	{"tracing", YAFFS_TRACE_TRACING},
--
--	{"verify", YAFFS_TRACE_VERIFY},
--	{"verify_nand", YAFFS_TRACE_VERIFY_NAND},
--	{"verify_full", YAFFS_TRACE_VERIFY_FULL},
--	{"verify_all", YAFFS_TRACE_VERIFY_ALL},
--
--	{"write", YAFFS_TRACE_WRITE},
--	{"all", 0xffffffff},
--	{"none", 0},
--	{NULL, 0},
--};
--
--#define MAX_MASK_NAME_LENGTH 40
--static int yaffs_proc_write(struct file *file, const char *buf,
--					 unsigned long count, void *data)
--{
--	unsigned rg = 0, mask_bitfield;
--	char *end;
--	char *mask_name;
--	const char *x;
--	char substring[MAX_MASK_NAME_LENGTH + 1];
--	int i;
--	int done = 0;
--	int add, len = 0;
--	int pos = 0;
--
--	rg = yaffs_traceMask;
--
--	while (!done && (pos < count)) {
--		done = 1;
--		while ((pos < count) && isspace(buf[pos]))
--			pos++;
--
--		switch (buf[pos]) {
--		case '+':
--		case '-':
--		case '=':
--			add = buf[pos];
--			pos++;
--			break;
--
--		default:
--			add = ' ';
--			break;
--		}
--		mask_name = NULL;
--
--		mask_bitfield = simple_strtoul(buf + pos, &end, 0);
--
--		if (end > buf + pos) {
--			mask_name = "numeral";
--			len = end - (buf + pos);
--			pos += len;
--			done = 0;
--		} else {
--			for (x = buf + pos, i = 0;
--			    (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
--			    i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
--				substring[i] = *x;
--			substring[i] = '\0';
--
--			for (i = 0; mask_flags[i].mask_name != NULL; i++) {
--				if (strcmp(substring, mask_flags[i].mask_name) == 0) {
--					mask_name = mask_flags[i].mask_name;
--					mask_bitfield = mask_flags[i].mask_bitfield;
--					done = 0;
--					break;
--				}
--			}
--		}
--
--		if (mask_name != NULL) {
--			done = 0;
--			switch (add) {
--			case '-':
--				rg &= ~mask_bitfield;
--				break;
--			case '+':
--				rg |= mask_bitfield;
--				break;
--			case '=':
--				rg = mask_bitfield;
--				break;
--			default:
--				rg |= mask_bitfield;
--				break;
--			}
--		}
--	}
--
--	yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
--
--	printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_traceMask);
--
--	if (rg & YAFFS_TRACE_ALWAYS) {
--		for (i = 0; mask_flags[i].mask_name != NULL; i++) {
--			char flag;
--			flag = ((rg & mask_flags[i].mask_bitfield) == mask_flags[i].mask_bitfield) ? '+' : '-';
--			printk(KERN_DEBUG "%c%s\n", flag, mask_flags[i].mask_name);
--		}
--	}
--
--	return count;
--}
--
--/* Stuff to handle installation of file systems */
--struct file_system_to_install {
--	struct file_system_type *fst;
--	int installed;
--};
--
--static struct file_system_to_install fs_to_install[] = {
--	{&yaffs_fs_type, 0},
--	{&yaffs2_fs_type, 0},
--	{NULL, 0}
--};
--
--static int __init init_yaffs_fs(void)
--{
--	int error = 0;
--	struct file_system_to_install *fsinst;
--
--	T(YAFFS_TRACE_ALWAYS,
--	  ("yaffs " __DATE__ " " __TIME__ " Installing. \n"));
--
--	/* Install the proc_fs entry */
--	my_proc_entry = create_proc_entry("yaffs",
--					       S_IRUGO | S_IFREG,
--					       YPROC_ROOT);
--
--	if (my_proc_entry) {
--		my_proc_entry->write_proc = yaffs_proc_write;
--		my_proc_entry->read_proc = yaffs_proc_read;
--		my_proc_entry->data = NULL;
--	} else
--		return -ENOMEM;
--
--	/* Now add the file system entries */
--
--	fsinst = fs_to_install;
--
--	while (fsinst->fst && !error) {
--		error = register_filesystem(fsinst->fst);
--		if (!error)
--			fsinst->installed = 1;
--		fsinst++;
--	}
--
--	/* Any errors? uninstall  */
--	if (error) {
--		fsinst = fs_to_install;
--
--		while (fsinst->fst) {
--			if (fsinst->installed) {
--				unregister_filesystem(fsinst->fst);
--				fsinst->installed = 0;
--			}
--			fsinst++;
--		}
--	}
--
--	return error;
--}
--
--static void __exit exit_yaffs_fs(void)
--{
--
--	struct file_system_to_install *fsinst;
--
--	T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__
--			       " removing. \n"));
--
--	remove_proc_entry("yaffs", YPROC_ROOT);
--
--	fsinst = fs_to_install;
--
--	while (fsinst->fst) {
--		if (fsinst->installed) {
--			unregister_filesystem(fsinst->fst);
--			fsinst->installed = 0;
--		}
--		fsinst++;
--	}
--}
--
--module_init(init_yaffs_fs)
--module_exit(exit_yaffs_fs)
--
--MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
--MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2006");
--MODULE_LICENSE("GPL");
---- a/fs/yaffs2/yaffs_getblockinfo.h
-+++ b/fs/yaffs2/yaffs_getblockinfo.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -17,18 +17,19 @@
- #define __YAFFS_GETBLOCKINFO_H__
- 
- #include "yaffs_guts.h"
-+#include "yaffs_trace.h"
- 
- /* Function to manipulate block info */
--static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
-+static Y_INLINE yaffs_block_info_t *yaffs_get_block_info(yaffs_dev_t * dev, int blk)
- {
--	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
-+	if (blk < dev->internal_start_block || blk > dev->internal_end_block) {
- 		T(YAFFS_TRACE_ERROR,
- 		  (TSTR
- 		   ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
- 		   blk));
- 		YBUG();
- 	}
--	return &dev->blockInfo[blk - dev->internalStartBlock];
-+	return &dev->block_info[blk - dev->internal_start_block];
- }
- 
- #endif
---- a/fs/yaffs2/yaffs_guts.c
-+++ b/fs/yaffs2/yaffs_guts.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -10,11 +10,8 @@
-  * it under the terms of the GNU General Public License version 2 as
-  * published by the Free Software Foundation.
-  */
--
--const char *yaffs_guts_c_version =
--    "$Id: yaffs_guts.c,v 1.82 2009-03-09 04:24:17 charles Exp $";
--
- #include "yportenv.h"
-+#include "yaffs_trace.h"
- 
- #include "yaffsinterface.h"
- #include "yaffs_guts.h"
-@@ -22,118 +19,109 @@ const char *yaffs_guts_c_version =
- #include "yaffs_getblockinfo.h"
- 
- #include "yaffs_tagscompat.h"
--#ifndef CONFIG_YAFFS_USE_OWN_SORT
--#include "yaffs_qsort.h"
--#endif
-+
- #include "yaffs_nand.h"
- 
--#include "yaffs_checkptrw.h"
-+#include "yaffs_yaffs1.h"
-+#include "yaffs_yaffs2.h"
-+#include "yaffs_bitmap.h"
-+#include "yaffs_verify.h"
- 
- #include "yaffs_nand.h"
- #include "yaffs_packedtags2.h"
- 
-+#include "yaffs_nameval.h"
-+#include "yaffs_allocator.h"
- 
--#define YAFFS_PASSIVE_GC_CHUNKS 2
-+/* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */
-+#define YAFFS_GC_GOOD_ENOUGH 2
-+#define YAFFS_GC_PASSIVE_THRESHOLD 4
- 
- #include "yaffs_ecc.h"
- 
- 
-+
- /* Robustification (if it ever comes about...) */
--static void yaffs_RetireBlock(yaffs_Device *dev, int blockInNAND);
--static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND,
-+static void yaffs_retire_block(yaffs_dev_t *dev, int flash_block);
-+static void yaffs_handle_chunk_wr_error(yaffs_dev_t *dev, int nand_chunk,
- 		int erasedOk);
--static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
-+static void yaffs_handle_chunk_wr_ok(yaffs_dev_t *dev, int nand_chunk,
- 				const __u8 *data,
--				const yaffs_ExtendedTags *tags);
--static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
--				const yaffs_ExtendedTags *tags);
-+				const yaffs_ext_tags *tags);
-+static void yaffs_handle_chunk_update(yaffs_dev_t *dev, int nand_chunk,
-+				const yaffs_ext_tags *tags);
- 
- /* Other local prototypes */
--static int yaffs_UnlinkObject(yaffs_Object *obj);
--static int yaffs_ObjectHasCachedWriteData(yaffs_Object *obj);
--
--static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList);
-+static void yaffs_update_parent(yaffs_obj_t *obj);
-+static int yaffs_unlink_obj(yaffs_obj_t *obj);
-+static int yaffs_obj_cache_dirty(yaffs_obj_t *obj);
- 
--static int yaffs_WriteNewChunkWithTagsToNAND(yaffs_Device *dev,
-+static int yaffs_write_new_chunk(yaffs_dev_t *dev,
- 					const __u8 *buffer,
--					yaffs_ExtendedTags *tags,
-+					yaffs_ext_tags *tags,
- 					int useReserve);
--static int yaffs_PutChunkIntoFile(yaffs_Object *in, int chunkInInode,
--				int chunkInNAND, int inScan);
- 
--static yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number,
--					yaffs_ObjectType type);
--static void yaffs_AddObjectToDirectory(yaffs_Object *directory,
--				yaffs_Object *obj);
--static int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name,
--				int force, int isShrink, int shadows);
--static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj);
--static int yaffs_CheckStructures(void);
--static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level,
--			int chunkOffset, int *limit);
--static int yaffs_DoGenericObjectDeletion(yaffs_Object *in);
--
--static yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device *dev, int blockNo);
- 
-+static yaffs_obj_t *yaffs_new_obj(yaffs_dev_t *dev, int number,
-+					yaffs_obj_type type);
- 
--static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
--				int chunkInNAND);
- 
--static int yaffs_UnlinkWorker(yaffs_Object *obj);
-+static int yaffs_apply_xattrib_mod(yaffs_obj_t *obj, char *buffer, yaffs_xattr_mod *xmod);
- 
--static int yaffs_TagsMatch(const yaffs_ExtendedTags *tags, int objectId,
--			int chunkInObject);
-+static void yaffs_remove_obj_from_dir(yaffs_obj_t *obj);
-+static int yaffs_check_structures(void);
-+static int yaffs_generic_obj_del(yaffs_obj_t *in);
-+
-+static int yaffs_check_chunk_erased(struct yaffs_dev_s *dev,
-+				int nand_chunk);
- 
--static int yaffs_AllocateChunk(yaffs_Device *dev, int useReserve,
--				yaffs_BlockInfo **blockUsedPtr);
-+static int yaffs_unlink_worker(yaffs_obj_t *obj);
- 
--static void yaffs_VerifyFreeChunks(yaffs_Device *dev);
-+static int yaffs_tags_match(const yaffs_ext_tags *tags, int obj_id,
-+			int chunkInObject);
- 
--static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in);
-+static int yaffs_alloc_chunk(yaffs_dev_t *dev, int useReserve,
-+				yaffs_block_info_t **blockUsedPtr);
- 
--static void yaffs_VerifyDirectory(yaffs_Object *directory);
--#ifdef YAFFS_PARANOID
--static int yaffs_CheckFileSanity(yaffs_Object *in);
--#else
--#define yaffs_CheckFileSanity(in)
--#endif
-+static void yaffs_check_obj_details_loaded(yaffs_obj_t *in);
-+
-+static void yaffs_invalidate_whole_cache(yaffs_obj_t *in);
-+static void yaffs_invalidate_chunk_cache(yaffs_obj_t *object, int chunk_id);
- 
--static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in);
--static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId);
-+static int yaffs_find_chunk_in_file(yaffs_obj_t *in, int inode_chunk,
-+				yaffs_ext_tags *tags);
- 
--static void yaffs_InvalidateCheckpoint(yaffs_Device *dev);
-+static int yaffs_verify_chunk_written(yaffs_dev_t *dev,
-+					int nand_chunk,
-+					const __u8 *data,
-+					yaffs_ext_tags *tags);
- 
--static int yaffs_FindChunkInFile(yaffs_Object *in, int chunkInInode,
--				yaffs_ExtendedTags *tags);
- 
--static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn,
--		unsigned pos);
--static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device *dev,
--					yaffs_FileStructure *fStruct,
--					__u32 chunkId);
-+static void yaffs_load_name_from_oh(yaffs_dev_t *dev,YCHAR *name, const YCHAR *ohName, int bufferSize);
-+static void yaffs_load_oh_from_name(yaffs_dev_t *dev,YCHAR *ohName, const YCHAR *name);
- 
- 
- /* Function to calculate chunk and offset */
- 
--static void yaffs_AddrToChunk(yaffs_Device *dev, loff_t addr, int *chunkOut,
-+static void yaffs_addr_to_chunk(yaffs_dev_t *dev, loff_t addr, int *chunkOut,
- 		__u32 *offsetOut)
- {
- 	int chunk;
- 	__u32 offset;
- 
--	chunk  = (__u32)(addr >> dev->chunkShift);
-+	chunk  = (__u32)(addr >> dev->chunk_shift);
- 
--	if (dev->chunkDiv == 1) {
-+	if (dev->chunk_div == 1) {
- 		/* easy power of 2 case */
--		offset = (__u32)(addr & dev->chunkMask);
-+		offset = (__u32)(addr & dev->chunk_mask);
- 	} else {
- 		/* Non power-of-2 case */
- 
- 		loff_t chunkBase;
- 
--		chunk /= dev->chunkDiv;
-+		chunk /= dev->chunk_div;
- 
--		chunkBase = ((loff_t)chunk) * dev->nDataBytesPerChunk;
-+		chunkBase = ((loff_t)chunk) * dev->data_bytes_per_chunk;
- 		offset = (__u32)(addr - chunkBase);
- 	}
- 
-@@ -172,7 +160,7 @@ static __u32 ShiftsGE(__u32 x)
- 
- static __u32 Shifts(__u32 x)
- {
--	int nShifts;
-+	__u32 nShifts;
- 
- 	nShifts =  0;
- 
-@@ -193,49 +181,49 @@ static __u32 Shifts(__u32 x)
-  * Temporary buffer manipulations.
-  */
- 
--static int yaffs_InitialiseTempBuffers(yaffs_Device *dev)
-+static int yaffs_init_tmp_buffers(yaffs_dev_t *dev)
- {
- 	int i;
- 	__u8 *buf = (__u8 *)1;
- 
--	memset(dev->tempBuffer, 0, sizeof(dev->tempBuffer));
-+	memset(dev->temp_buffer, 0, sizeof(dev->temp_buffer));
- 
- 	for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) {
--		dev->tempBuffer[i].line = 0;	/* not in use */
--		dev->tempBuffer[i].buffer = buf =
--		    YMALLOC_DMA(dev->totalBytesPerChunk);
-+		dev->temp_buffer[i].line = 0;	/* not in use */
-+		dev->temp_buffer[i].buffer = buf =
-+		    YMALLOC_DMA(dev->param.total_bytes_per_chunk);
- 	}
- 
- 	return buf ? YAFFS_OK : YAFFS_FAIL;
- }
- 
--__u8 *yaffs_GetTempBuffer(yaffs_Device *dev, int lineNo)
-+__u8 *yaffs_get_temp_buffer(yaffs_dev_t *dev, int line_no)
- {
- 	int i, j;
- 
--	dev->tempInUse++;
--	if (dev->tempInUse > dev->maxTemp)
--		dev->maxTemp = dev->tempInUse;
-+	dev->temp_in_use++;
-+	if (dev->temp_in_use > dev->max_temp)
-+		dev->max_temp = dev->temp_in_use;
- 
- 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
--		if (dev->tempBuffer[i].line == 0) {
--			dev->tempBuffer[i].line = lineNo;
--			if ((i + 1) > dev->maxTemp) {
--				dev->maxTemp = i + 1;
-+		if (dev->temp_buffer[i].line == 0) {
-+			dev->temp_buffer[i].line = line_no;
-+			if ((i + 1) > dev->max_temp) {
-+				dev->max_temp = i + 1;
- 				for (j = 0; j <= i; j++)
--					dev->tempBuffer[j].maxLine =
--					    dev->tempBuffer[j].line;
-+					dev->temp_buffer[j].max_line =
-+					    dev->temp_buffer[j].line;
- 			}
- 
--			return dev->tempBuffer[i].buffer;
-+			return dev->temp_buffer[i].buffer;
- 		}
- 	}
- 
- 	T(YAFFS_TRACE_BUFFERS,
- 	  (TSTR("Out of temp buffers at line %d, other held by lines:"),
--	   lineNo));
-+	   line_no));
- 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
--		T(YAFFS_TRACE_BUFFERS, (TSTR(" %d "), dev->tempBuffer[i].line));
-+		T(YAFFS_TRACE_BUFFERS, (TSTR(" %d "), dev->temp_buffer[i].line));
- 
- 	T(YAFFS_TRACE_BUFFERS, (TSTR(" " TENDSTR)));
- 
-@@ -244,21 +232,21 @@ __u8 *yaffs_GetTempBuffer(yaffs_Device *
- 	 * This is not good.
- 	 */
- 
--	dev->unmanagedTempAllocations++;
--	return YMALLOC(dev->nDataBytesPerChunk);
-+	dev->unmanaged_buffer_allocs++;
-+	return YMALLOC(dev->data_bytes_per_chunk);
- 
- }
- 
--void yaffs_ReleaseTempBuffer(yaffs_Device *dev, __u8 *buffer,
--				    int lineNo)
-+void yaffs_release_temp_buffer(yaffs_dev_t *dev, __u8 *buffer,
-+				    int line_no)
- {
- 	int i;
- 
--	dev->tempInUse--;
-+	dev->temp_in_use--;
- 
- 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
--		if (dev->tempBuffer[i].buffer == buffer) {
--			dev->tempBuffer[i].line = 0;
-+		if (dev->temp_buffer[i].buffer == buffer) {
-+			dev->temp_buffer[i].line = 0;
- 			return;
- 		}
- 	}
-@@ -267,9 +255,9 @@ void yaffs_ReleaseTempBuffer(yaffs_Devic
- 		/* assume it is an unmanaged one. */
- 		T(YAFFS_TRACE_BUFFERS,
- 		  (TSTR("Releasing unmanaged temp buffer in line %d" TENDSTR),
--		   lineNo));
-+		   line_no));
- 		YFREE(buffer);
--		dev->unmanagedTempDeallocations++;
-+		dev->unmanaged_buffer_deallocs++;
- 	}
- 
- }
-@@ -277,21 +265,21 @@ void yaffs_ReleaseTempBuffer(yaffs_Devic
- /*
-  * Determine if we have a managed buffer.
-  */
--int yaffs_IsManagedTempBuffer(yaffs_Device *dev, const __u8 *buffer)
-+int yaffs_is_managed_tmp_buffer(yaffs_dev_t *dev, const __u8 *buffer)
- {
- 	int i;
- 
- 	for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
--		if (dev->tempBuffer[i].buffer == buffer)
-+		if (dev->temp_buffer[i].buffer == buffer)
- 			return 1;
- 	}
- 
--	for (i = 0; i < dev->nShortOpCaches; i++) {
--		if (dev->srCache[i].data == buffer)
-+	for (i = 0; i < dev->param.n_caches; i++) {
-+		if (dev->cache[i].data == buffer)
- 			return 1;
- 	}
- 
--	if (buffer == dev->checkpointBuffer)
-+	if (buffer == dev->checkpt_buffer)
- 		return 1;
- 
- 	T(YAFFS_TRACE_ALWAYS,
-@@ -299,6397 +287,4205 @@ int yaffs_IsManagedTempBuffer(yaffs_Devi
- 	return 0;
- }
- 
--
--
- /*
-- * Chunk bitmap manipulations
-+ * Verification code
-  */
- 
--static Y_INLINE __u8 *yaffs_BlockBits(yaffs_Device *dev, int blk)
--{
--	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
--		T(YAFFS_TRACE_ERROR,
--			(TSTR("**>> yaffs: BlockBits block %d is not valid" TENDSTR),
--			blk));
--		YBUG();
--	}
--	return dev->chunkBits +
--		(dev->chunkBitmapStride * (blk - dev->internalStartBlock));
--}
- 
--static Y_INLINE void yaffs_VerifyChunkBitId(yaffs_Device *dev, int blk, int chunk)
--{
--	if (blk < dev->internalStartBlock || blk > dev->internalEndBlock ||
--			chunk < 0 || chunk >= dev->nChunksPerBlock) {
--		T(YAFFS_TRACE_ERROR,
--		(TSTR("**>> yaffs: Chunk Id (%d:%d) invalid"TENDSTR),
--			blk, chunk));
--		YBUG();
--	}
--}
- 
--static Y_INLINE void yaffs_ClearChunkBits(yaffs_Device *dev, int blk)
--{
--	__u8 *blkBits = yaffs_BlockBits(dev, blk);
- 
--	memset(blkBits, 0, dev->chunkBitmapStride);
--}
-+/*
-+ *  Simple hash function. Needs to have a reasonable spread
-+ */
- 
--static Y_INLINE void yaffs_ClearChunkBit(yaffs_Device *dev, int blk, int chunk)
-+static Y_INLINE int yaffs_hash_fn(int n)
- {
--	__u8 *blkBits = yaffs_BlockBits(dev, blk);
--
--	yaffs_VerifyChunkBitId(dev, blk, chunk);
--
--	blkBits[chunk / 8] &= ~(1 << (chunk & 7));
-+	n = abs(n);
-+	return n % YAFFS_NOBJECT_BUCKETS;
- }
- 
--static Y_INLINE void yaffs_SetChunkBit(yaffs_Device *dev, int blk, int chunk)
--{
--	__u8 *blkBits = yaffs_BlockBits(dev, blk);
--
--	yaffs_VerifyChunkBitId(dev, blk, chunk);
--
--	blkBits[chunk / 8] |= (1 << (chunk & 7));
--}
-+/*
-+ * Access functions to useful fake objects.
-+ * Note that root might have a presence in NAND if permissions are set.
-+ */
- 
--static Y_INLINE int yaffs_CheckChunkBit(yaffs_Device *dev, int blk, int chunk)
-+yaffs_obj_t *yaffs_root(yaffs_dev_t *dev)
- {
--	__u8 *blkBits = yaffs_BlockBits(dev, blk);
--	yaffs_VerifyChunkBitId(dev, blk, chunk);
--
--	return (blkBits[chunk / 8] & (1 << (chunk & 7))) ? 1 : 0;
-+	return dev->root_dir;
- }
- 
--static Y_INLINE int yaffs_StillSomeChunkBits(yaffs_Device *dev, int blk)
-+yaffs_obj_t *yaffs_lost_n_found(yaffs_dev_t *dev)
- {
--	__u8 *blkBits = yaffs_BlockBits(dev, blk);
--	int i;
--	for (i = 0; i < dev->chunkBitmapStride; i++) {
--		if (*blkBits)
--			return 1;
--		blkBits++;
--	}
--	return 0;
-+	return dev->lost_n_found;
- }
- 
--static int yaffs_CountChunkBits(yaffs_Device *dev, int blk)
--{
--	__u8 *blkBits = yaffs_BlockBits(dev, blk);
--	int i;
--	int n = 0;
--	for (i = 0; i < dev->chunkBitmapStride; i++) {
--		__u8 x = *blkBits;
--		while (x) {
--			if (x & 1)
--				n++;
--			x >>= 1;
--		}
--
--		blkBits++;
--	}
--	return n;
--}
- 
- /*
-- * Verification code
-+ *  Erased NAND checking functions
-  */
- 
--static int yaffs_SkipVerification(yaffs_Device *dev)
--{
--	return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY | YAFFS_TRACE_VERIFY_FULL));
--}
--
--static int yaffs_SkipFullVerification(yaffs_Device *dev)
--{
--	return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY_FULL));
--}
--
--static int yaffs_SkipNANDVerification(yaffs_Device *dev)
-+int yaffs_check_ff(__u8 *buffer, int n_bytes)
- {
--	return !(yaffs_traceMask & (YAFFS_TRACE_VERIFY_NAND));
-+	/* Horrible, slow implementation */
-+	while (n_bytes--) {
-+		if (*buffer != 0xFF)
-+			return 0;
-+		buffer++;
-+	}
-+	return 1;
- }
- 
--static const char *blockStateName[] = {
--"Unknown",
--"Needs scanning",
--"Scanning",
--"Empty",
--"Allocating",
--"Full",
--"Dirty",
--"Checkpoint",
--"Collecting",
--"Dead"
--};
--
--static void yaffs_VerifyBlock(yaffs_Device *dev, yaffs_BlockInfo *bi, int n)
-+static int yaffs_check_chunk_erased(struct yaffs_dev_s *dev,
-+				int nand_chunk)
- {
--	int actuallyUsed;
--	int inUse;
-+	int retval = YAFFS_OK;
-+	__u8 *data = yaffs_get_temp_buffer(dev, __LINE__);
-+	yaffs_ext_tags tags;
-+	int result;
- 
--	if (yaffs_SkipVerification(dev))
--		return;
-+	result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, data, &tags);
- 
--	/* Report illegal runtime states */
--	if (bi->blockState >= YAFFS_NUMBER_OF_BLOCK_STATES)
--		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has undefined state %d"TENDSTR), n, bi->blockState));
-+	if (tags.ecc_result > YAFFS_ECC_RESULT_NO_ERROR)
-+		retval = YAFFS_FAIL;
- 
--	switch (bi->blockState) {
--	case YAFFS_BLOCK_STATE_UNKNOWN:
--	case YAFFS_BLOCK_STATE_SCANNING:
--	case YAFFS_BLOCK_STATE_NEEDS_SCANNING:
--		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has bad run-state %s"TENDSTR),
--		n, blockStateName[bi->blockState]));
-+	if (!yaffs_check_ff(data, dev->data_bytes_per_chunk) || tags.chunk_used) {
-+		T(YAFFS_TRACE_NANDACCESS,
-+		  (TSTR("Chunk %d not erased" TENDSTR), nand_chunk));
-+		retval = YAFFS_FAIL;
- 	}
- 
--	/* Check pages in use and soft deletions are legal */
--
--	actuallyUsed = bi->pagesInUse - bi->softDeletions;
--
--	if (bi->pagesInUse < 0 || bi->pagesInUse > dev->nChunksPerBlock ||
--	   bi->softDeletions < 0 || bi->softDeletions > dev->nChunksPerBlock ||
--	   actuallyUsed < 0 || actuallyUsed > dev->nChunksPerBlock)
--		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has illegal values pagesInUsed %d softDeletions %d"TENDSTR),
--		n, bi->pagesInUse, bi->softDeletions));
--
-+	yaffs_release_temp_buffer(dev, data, __LINE__);
- 
--	/* Check chunk bitmap legal */
--	inUse = yaffs_CountChunkBits(dev, n);
--	if (inUse != bi->pagesInUse)
--		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has inconsistent values pagesInUse %d counted chunk bits %d"TENDSTR),
--			n, bi->pagesInUse, inUse));
-+	return retval;
- 
--	/* Check that the sequence number is valid.
--	 * Ten million is legal, but is very unlikely
--	 */
--	if (dev->isYaffs2 &&
--	   (bi->blockState == YAFFS_BLOCK_STATE_ALLOCATING || bi->blockState == YAFFS_BLOCK_STATE_FULL) &&
--	   (bi->sequenceNumber < YAFFS_LOWEST_SEQUENCE_NUMBER || bi->sequenceNumber > 10000000))
--		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has suspect sequence number of %d"TENDSTR),
--		n, bi->sequenceNumber));
- }
- 
--static void yaffs_VerifyCollectedBlock(yaffs_Device *dev, yaffs_BlockInfo *bi,
--		int n)
-+
-+static int yaffs_verify_chunk_written(yaffs_dev_t *dev,
-+					int nand_chunk,
-+					const __u8 *data,
-+					yaffs_ext_tags *tags)
- {
--	yaffs_VerifyBlock(dev, bi, n);
-+	int retval = YAFFS_OK;
-+	yaffs_ext_tags tempTags;
-+	__u8 *buffer = yaffs_get_temp_buffer(dev,__LINE__);
-+	int result;
-+	
-+	result = yaffs_rd_chunk_tags_nand(dev,nand_chunk,buffer,&tempTags);
-+	if(memcmp(buffer,data,dev->data_bytes_per_chunk) ||
-+		tempTags.obj_id != tags->obj_id ||
-+		tempTags.chunk_id  != tags->chunk_id ||
-+		tempTags.n_bytes != tags->n_bytes)
-+		retval = YAFFS_FAIL;
- 
--	/* After collection the block should be in the erased state */
--	/* This will need to change if we do partial gc */
-+	yaffs_release_temp_buffer(dev, buffer, __LINE__);
- 
--	if (bi->blockState != YAFFS_BLOCK_STATE_COLLECTING &&
--			bi->blockState != YAFFS_BLOCK_STATE_EMPTY) {
--		T(YAFFS_TRACE_ERROR, (TSTR("Block %d is in state %d after gc, should be erased"TENDSTR),
--			n, bi->blockState));
--	}
-+	return retval;
- }
- 
--static void yaffs_VerifyBlocks(yaffs_Device *dev)
-+static int yaffs_write_new_chunk(struct yaffs_dev_s *dev,
-+					const __u8 *data,
-+					yaffs_ext_tags *tags,
-+					int useReserve)
- {
--	int i;
--	int nBlocksPerState[YAFFS_NUMBER_OF_BLOCK_STATES];
--	int nIllegalBlockStates = 0;
--
--	if (yaffs_SkipVerification(dev))
--		return;
--
--	memset(nBlocksPerState, 0, sizeof(nBlocksPerState));
--
--	for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
--		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
--		yaffs_VerifyBlock(dev, bi, i);
--
--		if (bi->blockState < YAFFS_NUMBER_OF_BLOCK_STATES)
--			nBlocksPerState[bi->blockState]++;
--		else
--			nIllegalBlockStates++;
--	}
-+	int attempts = 0;
-+	int writeOk = 0;
-+	int chunk;
- 
--	T(YAFFS_TRACE_VERIFY, (TSTR(""TENDSTR)));
--	T(YAFFS_TRACE_VERIFY, (TSTR("Block summary"TENDSTR)));
-+	yaffs2_checkpt_invalidate(dev);
- 
--	T(YAFFS_TRACE_VERIFY, (TSTR("%d blocks have illegal states"TENDSTR), nIllegalBlockStates));
--	if (nBlocksPerState[YAFFS_BLOCK_STATE_ALLOCATING] > 1)
--		T(YAFFS_TRACE_VERIFY, (TSTR("Too many allocating blocks"TENDSTR)));
-+	do {
-+		yaffs_block_info_t *bi = 0;
-+		int erasedOk = 0;
- 
--	for (i = 0; i < YAFFS_NUMBER_OF_BLOCK_STATES; i++)
--		T(YAFFS_TRACE_VERIFY,
--		  (TSTR("%s %d blocks"TENDSTR),
--		  blockStateName[i], nBlocksPerState[i]));
-+		chunk = yaffs_alloc_chunk(dev, useReserve, &bi);
-+		if (chunk < 0) {
-+			/* no space */
-+			break;
-+		}
- 
--	if (dev->blocksInCheckpoint != nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT])
--		T(YAFFS_TRACE_VERIFY,
--		 (TSTR("Checkpoint block count wrong dev %d count %d"TENDSTR),
--		 dev->blocksInCheckpoint, nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT]));
-+		/* First check this chunk is erased, if it needs
-+		 * checking.  The checking policy (unless forced
-+		 * always on) is as follows:
-+		 *
-+		 * Check the first page we try to write in a block.
-+		 * If the check passes then we don't need to check any
-+		 * more.	If the check fails, we check again...
-+		 * If the block has been erased, we don't need to check.
-+		 *
-+		 * However, if the block has been prioritised for gc,
-+		 * then we think there might be something odd about
-+		 * this block and stop using it.
-+		 *
-+		 * Rationale: We should only ever see chunks that have
-+		 * not been erased if there was a partially written
-+		 * chunk due to power loss.  This checking policy should
-+		 * catch that case with very few checks and thus save a
-+		 * lot of checks that are most likely not needed.
-+		 *
-+		 * Mods to the above
-+		 * If an erase check fails or the write fails we skip the 
-+		 * rest of the block.
-+		 */
- 
--	if (dev->nErasedBlocks != nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY])
--		T(YAFFS_TRACE_VERIFY,
--		 (TSTR("Erased block count wrong dev %d count %d"TENDSTR),
--		 dev->nErasedBlocks, nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY]));
-+		/* let's give it a try */
-+		attempts++;
- 
--	if (nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING] > 1)
--		T(YAFFS_TRACE_VERIFY,
--		 (TSTR("Too many collecting blocks %d (max is 1)"TENDSTR),
--		 nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING]));
-+		if(dev->param.always_check_erased)
-+			bi->skip_erased_check = 0;
- 
--	T(YAFFS_TRACE_VERIFY, (TSTR(""TENDSTR)));
-+		if (!bi->skip_erased_check) {
-+			erasedOk = yaffs_check_chunk_erased(dev, chunk);
-+			if (erasedOk != YAFFS_OK) {
-+				T(YAFFS_TRACE_ERROR,
-+				(TSTR("**>> yaffs chunk %d was not erased"
-+				TENDSTR), chunk));
- 
--}
-+				/* If not erased, delete this one,
-+				 * skip rest of block and
-+				 * try another chunk */
-+				 yaffs_chunk_del(dev,chunk,1,__LINE__);
-+				 yaffs_skip_rest_of_block(dev);
-+				continue;
-+			}
-+		}
- 
--/*
-- * Verify the object header. oh must be valid, but obj and tags may be NULL in which
-- * case those tests will not be performed.
-- */
--static void yaffs_VerifyObjectHeader(yaffs_Object *obj, yaffs_ObjectHeader *oh, yaffs_ExtendedTags *tags, int parentCheck)
--{
--	if (obj && yaffs_SkipVerification(obj->myDev))
--		return;
-+		writeOk = yaffs_wr_chunk_tags_nand(dev, chunk,
-+				data, tags);
- 
--	if (!(tags && obj && oh)) {
--		T(YAFFS_TRACE_VERIFY,
--				(TSTR("Verifying object header tags %x obj %x oh %x"TENDSTR),
--				(__u32)tags, (__u32)obj, (__u32)oh));
--		return;
--	}
-+		if(!bi->skip_erased_check)
-+			writeOk = yaffs_verify_chunk_written(dev, chunk, data, tags);
- 
--	if (oh->type <= YAFFS_OBJECT_TYPE_UNKNOWN ||
--			oh->type > YAFFS_OBJECT_TYPE_MAX)
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d header type is illegal value 0x%x"TENDSTR),
--			tags->objectId, oh->type));
-+		if (writeOk != YAFFS_OK) {
-+			/* Clean up aborted write, skip to next block and
-+			 * try another chunk */
-+			yaffs_handle_chunk_wr_error(dev, chunk, erasedOk);
-+			continue;
-+		}
- 
--	if (tags->objectId != obj->objectId)
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d header mismatch objectId %d"TENDSTR),
--			tags->objectId, obj->objectId));
-+		bi->skip_erased_check = 1;
- 
-+		/* Copy the data into the robustification buffer */
-+		yaffs_handle_chunk_wr_ok(dev, chunk, data, tags);
- 
--	/*
--	 * Check that the object's parent ids match if parentCheck requested.
--	 *
--	 * Tests do not apply to the root object.
--	 */
-+	} while (writeOk != YAFFS_OK &&
-+		(yaffs_wr_attempts <= 0 || attempts <= yaffs_wr_attempts));
- 
--	if (parentCheck && tags->objectId > 1 && !obj->parent)
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d header mismatch parentId %d obj->parent is NULL"TENDSTR),
--			tags->objectId, oh->parentObjectId));
-+	if (!writeOk)
-+		chunk = -1;
- 
--	if (parentCheck && obj->parent &&
--			oh->parentObjectId != obj->parent->objectId &&
--			(oh->parentObjectId != YAFFS_OBJECTID_UNLINKED ||
--			obj->parent->objectId != YAFFS_OBJECTID_DELETED))
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d header mismatch parentId %d parentObjectId %d"TENDSTR),
--			tags->objectId, oh->parentObjectId, obj->parent->objectId));
-+	if (attempts > 1) {
-+		T(YAFFS_TRACE_ERROR,
-+			(TSTR("**>> yaffs write required %d attempts" TENDSTR),
-+			attempts));
- 
--	if (tags->objectId > 1 && oh->name[0] == 0) /* Null name */
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d header name is NULL"TENDSTR),
--			obj->objectId));
-+		dev->n_retired_writes += (attempts - 1);
-+	}
- 
--	if (tags->objectId > 1 && ((__u8)(oh->name[0])) == 0xff) /* Trashed name */
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d header name is 0xFF"TENDSTR),
--			obj->objectId));
-+	return chunk;
- }
- 
- 
-+ 
-+/*
-+ * Block retiring for handling a broken block.
-+ */
- 
--static int yaffs_VerifyTnodeWorker(yaffs_Object *obj, yaffs_Tnode *tn,
--					__u32 level, int chunkOffset)
-+static void yaffs_retire_block(yaffs_dev_t *dev, int flash_block)
- {
--	int i;
--	yaffs_Device *dev = obj->myDev;
--	int ok = 1;
-+	yaffs_block_info_t *bi = yaffs_get_block_info(dev, flash_block);
- 
--	if (tn) {
--		if (level > 0) {
-+	yaffs2_checkpt_invalidate(dev);
-+	
-+	yaffs2_clear_oldest_dirty_seq(dev,bi);
- 
--			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
--				if (tn->internal[i]) {
--					ok = yaffs_VerifyTnodeWorker(obj,
--							tn->internal[i],
--							level - 1,
--							(chunkOffset<<YAFFS_TNODES_INTERNAL_BITS) + i);
--				}
--			}
--		} else if (level == 0) {
--			yaffs_ExtendedTags tags;
--			__u32 objectId = obj->objectId;
-+	if (yaffs_mark_bad(dev, flash_block) != YAFFS_OK) {
-+		if (yaffs_erase_block(dev, flash_block) != YAFFS_OK) {
-+			T(YAFFS_TRACE_ALWAYS, (TSTR(
-+				"yaffs: Failed to mark bad and erase block %d"
-+				TENDSTR), flash_block));
-+		} else {
-+			yaffs_ext_tags tags;
-+			int chunk_id = flash_block * dev->param.chunks_per_block;
- 
--			chunkOffset <<=  YAFFS_TNODES_LEVEL0_BITS;
-+			__u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
- 
--			for (i = 0; i < YAFFS_NTNODES_LEVEL0; i++) {
--				__u32 theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
-+			memset(buffer, 0xff, dev->data_bytes_per_chunk);
-+			yaffs_init_tags(&tags);
-+			tags.seq_number = YAFFS_SEQUENCE_BAD_BLOCK;
-+			if (dev->param.write_chunk_tags_fn(dev, chunk_id -
-+				dev->chunk_offset, buffer, &tags) != YAFFS_OK)
-+				T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Failed to "
-+					TCONT("write bad block marker to block %d")
-+					TENDSTR), flash_block));
- 
--				if (theChunk > 0) {
--					/* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),tags.objectId,tags.chunkId,theChunk)); */
--					yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL, &tags);
--					if (tags.objectId != objectId || tags.chunkId != chunkOffset) {
--						T(~0, (TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
--							objectId, chunkOffset, theChunk,
--							tags.objectId, tags.chunkId));
--					}
--				}
--				chunkOffset++;
--			}
-+			yaffs_release_temp_buffer(dev, buffer, __LINE__);
- 		}
- 	}
- 
--	return ok;
-+	bi->block_state = YAFFS_BLOCK_STATE_DEAD;
-+	bi->gc_prioritise = 0;
-+	bi->needs_retiring = 0;
- 
-+	dev->n_retired_blocks++;
- }
- 
-+/*
-+ * Functions for robustisizing TODO
-+ *
-+ */
- 
--static void yaffs_VerifyFile(yaffs_Object *obj)
-+static void yaffs_handle_chunk_wr_ok(yaffs_dev_t *dev, int nand_chunk,
-+				const __u8 *data,
-+				const yaffs_ext_tags *tags)
- {
--	int requiredTallness;
--	int actualTallness;
--	__u32 lastChunk;
--	__u32 x;
--	__u32 i;
--	yaffs_Device *dev;
--	yaffs_ExtendedTags tags;
--	yaffs_Tnode *tn;
--	__u32 objectId;
-+	dev=dev;
-+	nand_chunk=nand_chunk;
-+	data=data;
-+	tags=tags;
-+}
- 
--	if (!obj)
--		return;
-+static void yaffs_handle_chunk_update(yaffs_dev_t *dev, int nand_chunk,
-+				const yaffs_ext_tags *tags)
-+{
-+	dev=dev;
-+	nand_chunk=nand_chunk;
-+	tags=tags;
-+}
- 
--	if (yaffs_SkipVerification(obj->myDev))
--		return;
-+void yaffs_handle_chunk_error(yaffs_dev_t *dev, yaffs_block_info_t *bi)
-+{
-+	if (!bi->gc_prioritise) {
-+		bi->gc_prioritise = 1;
-+		dev->has_pending_prioritised_gc = 1;
-+		bi->chunk_error_strikes++;
- 
--	dev = obj->myDev;
--	objectId = obj->objectId;
-+		if (bi->chunk_error_strikes > 3) {
-+			bi->needs_retiring = 1; /* Too many stikes, so retire this */
-+			T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Block struck out" TENDSTR)));
- 
--	/* Check file size is consistent with tnode depth */
--	lastChunk =  obj->variant.fileVariant.fileSize / dev->nDataBytesPerChunk + 1;
--	x = lastChunk >> YAFFS_TNODES_LEVEL0_BITS;
--	requiredTallness = 0;
--	while (x > 0) {
--		x >>= YAFFS_TNODES_INTERNAL_BITS;
--		requiredTallness++;
-+		}
- 	}
-+}
- 
--	actualTallness = obj->variant.fileVariant.topLevel;
-+static void yaffs_handle_chunk_wr_error(yaffs_dev_t *dev, int nand_chunk,
-+		int erasedOk)
-+{
-+	int flash_block = nand_chunk / dev->param.chunks_per_block;
-+	yaffs_block_info_t *bi = yaffs_get_block_info(dev, flash_block);
- 
--	if (requiredTallness > actualTallness)
--		T(YAFFS_TRACE_VERIFY,
--		(TSTR("Obj %d had tnode tallness %d, needs to be %d"TENDSTR),
--		 obj->objectId, actualTallness, requiredTallness));
-+	yaffs_handle_chunk_error(dev, bi);
- 
-+	if (erasedOk) {
-+		/* Was an actual write failure, so mark the block for retirement  */
-+		bi->needs_retiring = 1;
-+		T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
-+		  (TSTR("**>> Block %d needs retiring" TENDSTR), flash_block));
-+	}
- 
--	/* Check that the chunks in the tnode tree are all correct.
--	 * We do this by scanning through the tnode tree and
--	 * checking the tags for every chunk match.
--	 */
-+	/* Delete the chunk */
-+	yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
-+	yaffs_skip_rest_of_block(dev);
-+}
- 
--	if (yaffs_SkipNANDVerification(dev))
--		return;
- 
--	for (i = 1; i <= lastChunk; i++) {
--		tn = yaffs_FindLevel0Tnode(dev, &obj->variant.fileVariant, i);
-+/*---------------- Name handling functions ------------*/
- 
--		if (tn) {
--			__u32 theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
--			if (theChunk > 0) {
--				/* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),objectId,i,theChunk)); */
--				yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL, &tags);
--				if (tags.objectId != objectId || tags.chunkId != i) {
--					T(~0, (TSTR("Object %d chunkId %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
--						objectId, i, theChunk,
--						tags.objectId, tags.chunkId));
--				}
--			}
-+static __u16 yaffs_calc_name_sum(const YCHAR *name)
-+{
-+	__u16 sum = 0;
-+	__u16 i = 1;
-+
-+	const YUCHAR *bname = (const YUCHAR *) name;
-+	if (bname) {
-+		while ((*bname) && (i < (YAFFS_MAX_NAME_LENGTH/2))) {
-+
-+#ifdef CONFIG_YAFFS_CASE_INSENSITIVE
-+			sum += yaffs_toupper(*bname) * i;
-+#else
-+			sum += (*bname) * i;
-+#endif
-+			i++;
-+			bname++;
- 		}
- 	}
-+	return sum;
- }
- 
--
--static void yaffs_VerifyHardLink(yaffs_Object *obj)
-+void yaffs_set_obj_name(yaffs_obj_t *obj, const YCHAR *name)
- {
--	if (obj && yaffs_SkipVerification(obj->myDev))
--		return;
--
--	/* Verify sane equivalent object */
-+#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
-+	memset(obj->short_name, 0, sizeof(YCHAR) * (YAFFS_SHORT_NAME_LENGTH+1));
-+	if (name && yaffs_strnlen(name,YAFFS_SHORT_NAME_LENGTH+1) <= YAFFS_SHORT_NAME_LENGTH)
-+		yaffs_strcpy(obj->short_name, name);
-+	else
-+		obj->short_name[0] = _Y('\0');
-+#endif
-+	obj->sum = yaffs_calc_name_sum(name);
- }
- 
--static void yaffs_VerifySymlink(yaffs_Object *obj)
-+void yaffs_set_obj_name_from_oh(yaffs_obj_t *obj, const yaffs_obj_header *oh)
- {
--	if (obj && yaffs_SkipVerification(obj->myDev))
--		return;
--
--	/* Verify symlink string */
-+#ifdef CONFIG_YAFFS_AUTO_UNICODE
-+	YCHAR tmpName[YAFFS_MAX_NAME_LENGTH+1];
-+	memset(tmpName,0,sizeof(tmpName));
-+	yaffs_load_name_from_oh(obj->my_dev,tmpName,oh->name,YAFFS_MAX_NAME_LENGTH+1);
-+	yaffs_set_obj_name(obj,tmpName);
-+#else
-+	yaffs_set_obj_name(obj,oh->name);
-+#endif
- }
- 
--static void yaffs_VerifySpecial(yaffs_Object *obj)
--{
--	if (obj && yaffs_SkipVerification(obj->myDev))
--		return;
--}
--
--static void yaffs_VerifyObject(yaffs_Object *obj)
--{
--	yaffs_Device *dev;
--
--	__u32 chunkMin;
--	__u32 chunkMax;
--
--	__u32 chunkIdOk;
--	__u32 chunkInRange;
--	__u32 chunkShouldNotBeDeleted;
--	__u32 chunkValid;
--
--	if (!obj)
--		return;
--
--	if (obj->beingCreated)
--		return;
-+/*-------------------- TNODES -------------------
- 
--	dev = obj->myDev;
-+ * List of spare tnodes
-+ * The list is hooked together using the first pointer
-+ * in the tnode.
-+ */
- 
--	if (yaffs_SkipVerification(dev))
--		return;
- 
--	/* Check sane object header chunk */
-+yaffs_tnode_t *yaffs_get_tnode(yaffs_dev_t *dev)
-+{
-+	yaffs_tnode_t *tn = yaffs_alloc_raw_tnode(dev);
-+	if (tn){
-+		memset(tn, 0, dev->tnode_size);
-+		dev->n_tnodes++;
-+	}
- 
--	chunkMin = dev->internalStartBlock * dev->nChunksPerBlock;
--	chunkMax = (dev->internalEndBlock+1) * dev->nChunksPerBlock - 1;
-+	dev->checkpoint_blocks_required = 0; /* force recalculation*/
- 
--	chunkInRange = (((unsigned)(obj->hdrChunk)) >= chunkMin && ((unsigned)(obj->hdrChunk)) <= chunkMax);
--	chunkIdOk = chunkInRange || obj->hdrChunk == 0;
--	chunkValid = chunkInRange &&
--			yaffs_CheckChunkBit(dev,
--					obj->hdrChunk / dev->nChunksPerBlock,
--					obj->hdrChunk % dev->nChunksPerBlock);
--	chunkShouldNotBeDeleted = chunkInRange && !chunkValid;
-+	return tn;
-+}
- 
--	if (!obj->fake &&
--			(!chunkIdOk || chunkShouldNotBeDeleted)) {
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d has chunkId %d %s %s"TENDSTR),
--			obj->objectId, obj->hdrChunk,
--			chunkIdOk ? "" : ",out of range",
--			chunkShouldNotBeDeleted ? ",marked as deleted" : ""));
--	}
-+/* FreeTnode frees up a tnode and puts it back on the free list */
-+static void yaffs_free_tnode(yaffs_dev_t *dev, yaffs_tnode_t *tn)
-+{
-+	yaffs_free_raw_tnode(dev,tn);
-+	dev->n_tnodes--;
-+	dev->checkpoint_blocks_required = 0; /* force recalculation*/
-+}
- 
--	if (chunkValid && !yaffs_SkipNANDVerification(dev)) {
--		yaffs_ExtendedTags tags;
--		yaffs_ObjectHeader *oh;
--		__u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
-+static void yaffs_deinit_tnodes_and_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_deinit_raw_tnodes_and_objs(dev);
-+	dev->n_obj = 0;
-+	dev->n_tnodes = 0;
-+}
- 
--		oh = (yaffs_ObjectHeader *)buffer;
- 
--		yaffs_ReadChunkWithTagsFromNAND(dev, obj->hdrChunk, buffer,
--				&tags);
-+void yaffs_load_tnode_0(yaffs_dev_t *dev, yaffs_tnode_t *tn, unsigned pos,
-+		unsigned val)
-+{
-+	__u32 *map = (__u32 *)tn;
-+	__u32 bitInMap;
-+	__u32 bitInWord;
-+	__u32 wordInMap;
-+	__u32 mask;
- 
--		yaffs_VerifyObjectHeader(obj, oh, &tags, 1);
-+	pos &= YAFFS_TNODES_LEVEL0_MASK;
-+	val >>= dev->chunk_grp_bits;
- 
--		yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
--	}
-+	bitInMap = pos * dev->tnode_width;
-+	wordInMap = bitInMap / 32;
-+	bitInWord = bitInMap & (32 - 1);
- 
--	/* Verify it has a parent */
--	if (obj && !obj->fake &&
--			(!obj->parent || obj->parent->myDev != dev)) {
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d has parent pointer %p which does not look like an object"TENDSTR),
--			obj->objectId, obj->parent));
--	}
-+	mask = dev->tnode_mask << bitInWord;
- 
--	/* Verify parent is a directory */
--	if (obj->parent && obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Obj %d's parent is not a directory (type %d)"TENDSTR),
--			obj->objectId, obj->parent->variantType));
--	}
-+	map[wordInMap] &= ~mask;
-+	map[wordInMap] |= (mask & (val << bitInWord));
- 
--	switch (obj->variantType) {
--	case YAFFS_OBJECT_TYPE_FILE:
--		yaffs_VerifyFile(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_SYMLINK:
--		yaffs_VerifySymlink(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_DIRECTORY:
--		yaffs_VerifyDirectory(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_HARDLINK:
--		yaffs_VerifyHardLink(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_SPECIAL:
--		yaffs_VerifySpecial(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_UNKNOWN:
--	default:
--		T(YAFFS_TRACE_VERIFY,
--		(TSTR("Obj %d has illegaltype %d"TENDSTR),
--		obj->objectId, obj->variantType));
--		break;
-+	if (dev->tnode_width > (32 - bitInWord)) {
-+		bitInWord = (32 - bitInWord);
-+		wordInMap++;;
-+		mask = dev->tnode_mask >> (/*dev->tnode_width -*/ bitInWord);
-+		map[wordInMap] &= ~mask;
-+		map[wordInMap] |= (mask & (val >> bitInWord));
- 	}
- }
- 
--static void yaffs_VerifyObjects(yaffs_Device *dev)
-+__u32 yaffs_get_group_base(yaffs_dev_t *dev, yaffs_tnode_t *tn,
-+		unsigned pos)
- {
--	yaffs_Object *obj;
--	int i;
--	struct ylist_head *lh;
-+	__u32 *map = (__u32 *)tn;
-+	__u32 bitInMap;
-+	__u32 bitInWord;
-+	__u32 wordInMap;
-+	__u32 val;
- 
--	if (yaffs_SkipVerification(dev))
--		return;
-+	pos &= YAFFS_TNODES_LEVEL0_MASK;
- 
--	/* Iterate through the objects in each hash entry */
-+	bitInMap = pos * dev->tnode_width;
-+	wordInMap = bitInMap / 32;
-+	bitInWord = bitInMap & (32 - 1);
- 
--	for (i = 0; i <  YAFFS_NOBJECT_BUCKETS; i++) {
--		ylist_for_each(lh, &dev->objectBucket[i].list) {
--			if (lh) {
--				obj = ylist_entry(lh, yaffs_Object, hashLink);
--				yaffs_VerifyObject(obj);
--			}
--		}
--	}
--}
-+	val = map[wordInMap] >> bitInWord;
- 
-+	if	(dev->tnode_width > (32 - bitInWord)) {
-+		bitInWord = (32 - bitInWord);
-+		wordInMap++;;
-+		val |= (map[wordInMap] << bitInWord);
-+	}
- 
--/*
-- *  Simple hash function. Needs to have a reasonable spread
-- */
-+	val &= dev->tnode_mask;
-+	val <<= dev->chunk_grp_bits;
- 
--static Y_INLINE int yaffs_HashFunction(int n)
--{
--	n = abs(n);
--	return n % YAFFS_NOBJECT_BUCKETS;
-+	return val;
- }
- 
--/*
-- * Access functions to useful fake objects.
-- * Note that root might have a presence in NAND if permissions are set.
-+/* ------------------- End of individual tnode manipulation -----------------*/
-+
-+/* ---------Functions to manipulate the look-up tree (made up of tnodes) ------
-+ * The look up tree is represented by the top tnode and the number of top_level
-+ * in the tree. 0 means only the level 0 tnode is in the tree.
-  */
- 
--yaffs_Object *yaffs_Root(yaffs_Device *dev)
-+/* FindLevel0Tnode finds the level 0 tnode, if one exists. */
-+yaffs_tnode_t *yaffs_find_tnode_0(yaffs_dev_t *dev,
-+					yaffs_file_s *file_struct,
-+					__u32 chunk_id)
- {
--	return dev->rootDir;
--}
-+	yaffs_tnode_t *tn = file_struct->top;
-+	__u32 i;
-+	int requiredTallness;
-+	int level = file_struct->top_level;
- 
--yaffs_Object *yaffs_LostNFound(yaffs_Device *dev)
--{
--	return dev->lostNFoundDir;
--}
-+	dev=dev;
- 
-+	/* Check sane level and chunk Id */
-+	if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL)
-+		return NULL;
- 
--/*
-- *  Erased NAND checking functions
-- */
-+	if (chunk_id > YAFFS_MAX_CHUNK_ID)
-+		return NULL;
- 
--int yaffs_CheckFF(__u8 *buffer, int nBytes)
--{
--	/* Horrible, slow implementation */
--	while (nBytes--) {
--		if (*buffer != 0xFF)
--			return 0;
--		buffer++;
-+	/* First check we're tall enough (ie enough top_level) */
-+
-+	i = chunk_id >> YAFFS_TNODES_LEVEL0_BITS;
-+	requiredTallness = 0;
-+	while (i) {
-+		i >>= YAFFS_TNODES_INTERNAL_BITS;
-+		requiredTallness++;
- 	}
--	return 1;
--}
- 
--static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
--				int chunkInNAND)
--{
--	int retval = YAFFS_OK;
--	__u8 *data = yaffs_GetTempBuffer(dev, __LINE__);
--	yaffs_ExtendedTags tags;
--	int result;
-+	if (requiredTallness > file_struct->top_level)
-+		return NULL; /* Not tall enough, so we can't find it */
-+
-+	/* Traverse down to level 0 */
-+	while (level > 0 && tn) {
-+		tn = tn->internal[(chunk_id >>
-+			(YAFFS_TNODES_LEVEL0_BITS +
-+				(level - 1) *
-+				YAFFS_TNODES_INTERNAL_BITS)) &
-+			YAFFS_TNODES_INTERNAL_MASK];
-+		level--;
-+	}
- 
--	result = yaffs_ReadChunkWithTagsFromNAND(dev, chunkInNAND, data, &tags);
-+	return tn;
-+}
- 
--	if (tags.eccResult > YAFFS_ECC_RESULT_NO_ERROR)
--		retval = YAFFS_FAIL;
-+/* AddOrFindLevel0Tnode finds the level 0 tnode if it exists, otherwise first expands the tree.
-+ * This happens in two steps:
-+ *  1. If the tree isn't tall enough, then make it taller.
-+ *  2. Scan down the tree towards the level 0 tnode adding tnodes if required.
-+ *
-+ * Used when modifying the tree.
-+ *
-+ *  If the tn argument is NULL, then a fresh tnode will be added otherwise the specified tn will
-+ *  be plugged into the ttree.
-+ */
- 
--	if (!yaffs_CheckFF(data, dev->nDataBytesPerChunk) || tags.chunkUsed) {
--		T(YAFFS_TRACE_NANDACCESS,
--		  (TSTR("Chunk %d not erased" TENDSTR), chunkInNAND));
--		retval = YAFFS_FAIL;
--	}
-+yaffs_tnode_t *yaffs_add_find_tnode_0(yaffs_dev_t *dev,
-+					yaffs_file_s *file_struct,
-+					__u32 chunk_id,
-+					yaffs_tnode_t *passed_tn)
-+{
-+	int requiredTallness;
-+	int i;
-+	int l;
-+	yaffs_tnode_t *tn;
- 
--	yaffs_ReleaseTempBuffer(dev, data, __LINE__);
-+	__u32 x;
- 
--	return retval;
- 
--}
-+	/* Check sane level and page Id */
-+	if (file_struct->top_level < 0 || file_struct->top_level > YAFFS_TNODES_MAX_LEVEL)
-+		return NULL;
- 
--static int yaffs_WriteNewChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
--					const __u8 *data,
--					yaffs_ExtendedTags *tags,
--					int useReserve)
--{
--	int attempts = 0;
--	int writeOk = 0;
--	int chunk;
-+	if (chunk_id > YAFFS_MAX_CHUNK_ID)
-+		return NULL;
- 
--	yaffs_InvalidateCheckpoint(dev);
-+	/* First check we're tall enough (ie enough top_level) */
- 
--	do {
--		yaffs_BlockInfo *bi = 0;
--		int erasedOk = 0;
-+	x = chunk_id >> YAFFS_TNODES_LEVEL0_BITS;
-+	requiredTallness = 0;
-+	while (x) {
-+		x >>= YAFFS_TNODES_INTERNAL_BITS;
-+		requiredTallness++;
-+	}
- 
--		chunk = yaffs_AllocateChunk(dev, useReserve, &bi);
--		if (chunk < 0) {
--			/* no space */
--			break;
--		}
- 
--		/* First check this chunk is erased, if it needs
--		 * checking.  The checking policy (unless forced
--		 * always on) is as follows:
--		 *
--		 * Check the first page we try to write in a block.
--		 * If the check passes then we don't need to check any
--		 * more.	If the check fails, we check again...
--		 * If the block has been erased, we don't need to check.
--		 *
--		 * However, if the block has been prioritised for gc,
--		 * then we think there might be something odd about
--		 * this block and stop using it.
--		 *
--		 * Rationale: We should only ever see chunks that have
--		 * not been erased if there was a partially written
--		 * chunk due to power loss.  This checking policy should
--		 * catch that case with very few checks and thus save a
--		 * lot of checks that are most likely not needed.
--		 */
--		if (bi->gcPrioritise) {
--			yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
--			/* try another chunk */
--			continue;
--		}
-+	if (requiredTallness > file_struct->top_level) {
-+		/* Not tall enough, gotta make the tree taller */
-+		for (i = file_struct->top_level; i < requiredTallness; i++) {
- 
--		/* let's give it a try */
--		attempts++;
-+			tn = yaffs_get_tnode(dev);
- 
--#ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED
--		bi->skipErasedCheck = 0;
--#endif
--		if (!bi->skipErasedCheck) {
--			erasedOk = yaffs_CheckChunkErased(dev, chunk);
--			if (erasedOk != YAFFS_OK) {
-+			if (tn) {
-+				tn->internal[0] = file_struct->top;
-+				file_struct->top = tn;
-+				file_struct->top_level++;
-+			} else {
- 				T(YAFFS_TRACE_ERROR,
--				(TSTR("**>> yaffs chunk %d was not erased"
--				TENDSTR), chunk));
--
--				/* try another chunk */
--				continue;
-+					(TSTR("yaffs: no more tnodes" TENDSTR)));
-+				return NULL;
- 			}
--			bi->skipErasedCheck = 1;
- 		}
-+	}
- 
--		writeOk = yaffs_WriteChunkWithTagsToNAND(dev, chunk,
--				data, tags);
--		if (writeOk != YAFFS_OK) {
--			yaffs_HandleWriteChunkError(dev, chunk, erasedOk);
--			/* try another chunk */
--			continue;
--		}
-+	/* Traverse down to level 0, adding anything we need */
- 
--		/* Copy the data into the robustification buffer */
--		yaffs_HandleWriteChunkOk(dev, chunk, data, tags);
-+	l = file_struct->top_level;
-+	tn = file_struct->top;
- 
--	} while (writeOk != YAFFS_OK &&
--		(yaffs_wr_attempts <= 0 || attempts <= yaffs_wr_attempts));
-+	if (l > 0) {
-+		while (l > 0 && tn) {
-+			x = (chunk_id >>
-+			     (YAFFS_TNODES_LEVEL0_BITS +
-+			      (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) &
-+			    YAFFS_TNODES_INTERNAL_MASK;
- 
--	if (!writeOk)
--		chunk = -1;
- 
--	if (attempts > 1) {
--		T(YAFFS_TRACE_ERROR,
--			(TSTR("**>> yaffs write required %d attempts" TENDSTR),
--			attempts));
-+			if ((l > 1) && !tn->internal[x]) {
-+				/* Add missing non-level-zero tnode */
-+				tn->internal[x] = yaffs_get_tnode(dev);
-+				if(!tn->internal[x])
-+					return NULL;
-+			} else if (l == 1) {
-+				/* Looking from level 1 at level 0 */
-+				if (passed_tn) {
-+					/* If we already have one, then release it.*/
-+					if (tn->internal[x])
-+						yaffs_free_tnode(dev, tn->internal[x]);
-+					tn->internal[x] = passed_tn;
-+
-+				} else if (!tn->internal[x]) {
-+					/* Don't have one, none passed in */
-+					tn->internal[x] = yaffs_get_tnode(dev);
-+					if(!tn->internal[x])
-+						return NULL;
-+				}
-+			}
- 
--		dev->nRetriedWrites += (attempts - 1);
-+			tn = tn->internal[x];
-+			l--;
-+		}
-+	} else {
-+		/* top is level 0 */
-+		if (passed_tn) {
-+			memcpy(tn, passed_tn, (dev->tnode_width * YAFFS_NTNODES_LEVEL0)/8);
-+			yaffs_free_tnode(dev, passed_tn);
-+		}
- 	}
- 
--	return chunk;
-+	return tn;
- }
- 
--/*
-- * Block retiring for handling a broken block.
-- */
--
--static void yaffs_RetireBlock(yaffs_Device *dev, int blockInNAND)
-+static int yaffs_find_chunk_in_group(yaffs_dev_t *dev, int theChunk,
-+				yaffs_ext_tags *tags, int obj_id,
-+				int inode_chunk)
- {
--	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);
-+	int j;
- 
--	yaffs_InvalidateCheckpoint(dev);
-+	for (j = 0; theChunk && j < dev->chunk_grp_size; j++) {
-+		if (yaffs_check_chunk_bit(dev, theChunk / dev->param.chunks_per_block,
-+				theChunk % dev->param.chunks_per_block)) {
-+			
-+			if(dev->chunk_grp_size == 1)
-+				return theChunk;
-+			else {
-+				yaffs_rd_chunk_tags_nand(dev, theChunk, NULL,
-+								tags);
-+				if (yaffs_tags_match(tags, obj_id, inode_chunk)) {
-+					/* found it; */
-+					return theChunk;
-+				}
-+			}
-+		}
-+		theChunk++;
-+	}
-+	return -1;
-+}
- 
--	if (yaffs_MarkBlockBad(dev, blockInNAND) != YAFFS_OK) {
--		if (yaffs_EraseBlockInNAND(dev, blockInNAND) != YAFFS_OK) {
--			T(YAFFS_TRACE_ALWAYS, (TSTR(
--				"yaffs: Failed to mark bad and erase block %d"
--				TENDSTR), blockInNAND));
--		} else {
--			yaffs_ExtendedTags tags;
--			int chunkId = blockInNAND * dev->nChunksPerBlock;
-+#if 0
-+/* Experimental code not being used yet. Might speed up file deletion */
-+/* DeleteWorker scans backwards through the tnode tree and deletes all the
-+ * chunks and tnodes in the file.
-+ * Returns 1 if the tree was deleted.
-+ * Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.
-+ */
- 
--			__u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
-+static int yaffs_del_worker(yaffs_obj_t *in, yaffs_tnode_t *tn, __u32 level,
-+			      int chunk_offset, int *limit)
-+{
-+	int i;
-+	int inode_chunk;
-+	int theChunk;
-+	yaffs_ext_tags tags;
-+	int foundChunk;
-+	yaffs_dev_t *dev = in->my_dev;
- 
--			memset(buffer, 0xff, dev->nDataBytesPerChunk);
--			yaffs_InitialiseTags(&tags);
--			tags.sequenceNumber = YAFFS_SEQUENCE_BAD_BLOCK;
--			if (dev->writeChunkWithTagsToNAND(dev, chunkId -
--				dev->chunkOffset, buffer, &tags) != YAFFS_OK)
--				T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Failed to "
--					TCONT("write bad block marker to block %d")
--					TENDSTR), blockInNAND));
-+	int allDone = 1;
- 
--			yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
--		}
--	}
-+	if (tn) {
-+		if (level > 0) {
-+			for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0;
-+			     i--) {
-+				if (tn->internal[i]) {
-+					if (limit && (*limit) < 0) {
-+						allDone = 0;
-+					} else {
-+						allDone =
-+							yaffs_del_worker(in,
-+								tn->
-+								internal
-+								[i],
-+								level -
-+								1,
-+								(chunk_offset
-+									<<
-+									YAFFS_TNODES_INTERNAL_BITS)
-+								+ i,
-+								limit);
-+					}
-+					if (allDone) {
-+						yaffs_free_tnode(dev,
-+								tn->
-+								internal[i]);
-+						tn->internal[i] = NULL;
-+					}
-+				}
-+			}
-+			return (allDone) ? 1 : 0;
-+		} else if (level == 0) {
-+			int hitLimit = 0;
- 
--	bi->blockState = YAFFS_BLOCK_STATE_DEAD;
--	bi->gcPrioritise = 0;
--	bi->needsRetiring = 0;
-+			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0 && !hitLimit;
-+					i--) {
-+				theChunk = yaffs_get_group_base(dev, tn, i);
-+				if (theChunk) {
- 
--	dev->nRetiredBlocks++;
--}
-+					inode_chunk = (chunk_offset <<
-+						YAFFS_TNODES_LEVEL0_BITS) + i;
- 
--/*
-- * Functions for robustisizing TODO
-- *
-- */
-+					foundChunk =
-+						yaffs_find_chunk_in_group(dev,
-+								theChunk,
-+								&tags,
-+								in->obj_id,
-+								inode_chunk);
- 
--static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
--				const __u8 *data,
--				const yaffs_ExtendedTags *tags)
--{
--}
-+					if (foundChunk > 0) {
-+						yaffs_chunk_del(dev,
-+								  foundChunk, 1,
-+								  __LINE__);
-+						in->n_data_chunks--;
-+						if (limit) {
-+							*limit = *limit - 1;
-+							if (*limit <= 0)
-+								hitLimit = 1;
-+						}
- 
--static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
--				const yaffs_ExtendedTags *tags)
--{
--}
-+					}
- 
--void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi)
--{
--	if (!bi->gcPrioritise) {
--		bi->gcPrioritise = 1;
--		dev->hasPendingPrioritisedGCs = 1;
--		bi->chunkErrorStrikes++;
-+					yaffs_load_tnode_0(dev, tn, i, 0);
-+				}
- 
--		if (bi->chunkErrorStrikes > 3) {
--			bi->needsRetiring = 1; /* Too many stikes, so retire this */
--			T(YAFFS_TRACE_ALWAYS, (TSTR("yaffs: Block struck out" TENDSTR)));
-+			}
-+			return (i < 0) ? 1 : 0;
- 
- 		}
-+
- 	}
-+
-+	return 1;
-+
- }
- 
--static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND,
--		int erasedOk)
-+#endif
-+
-+static void yaffs_soft_del_chunk(yaffs_dev_t *dev, int chunk)
- {
--	int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
--	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockInNAND);
-+	yaffs_block_info_t *theBlock;
-+	unsigned block_no;
- 
--	yaffs_HandleChunkError(dev, bi);
-+	T(YAFFS_TRACE_DELETION, (TSTR("soft delete chunk %d" TENDSTR), chunk));
- 
--	if (erasedOk) {
--		/* Was an actual write failure, so mark the block for retirement  */
--		bi->needsRetiring = 1;
--		T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
--		  (TSTR("**>> Block %d needs retiring" TENDSTR), blockInNAND));
-+	block_no =  chunk / dev->param.chunks_per_block;
-+	theBlock = yaffs_get_block_info(dev, block_no);
-+	if (theBlock) {
-+		theBlock->soft_del_pages++;
-+		dev->n_free_chunks++;
-+		yaffs2_update_oldest_dirty_seq(dev, block_no, theBlock);
- 	}
--
--	/* Delete the chunk */
--	yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
- }
- 
-+/* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all the chunks in the file.
-+ * All soft deleting does is increment the block's softdelete count and pulls the chunk out
-+ * of the tnode.
-+ * Thus, essentially this is the same as DeleteWorker except that the chunks are soft deleted.
-+ */
- 
--/*---------------- Name handling functions ------------*/
--
--static __u16 yaffs_CalcNameSum(const YCHAR *name)
-+static int yaffs_soft_del_worker(yaffs_obj_t *in, yaffs_tnode_t *tn,
-+				  __u32 level, int chunk_offset)
- {
--	__u16 sum = 0;
--	__u16 i = 1;
-+	int i;
-+	int theChunk;
-+	int allDone = 1;
-+	yaffs_dev_t *dev = in->my_dev;
- 
--	const YUCHAR *bname = (const YUCHAR *) name;
--	if (bname) {
--		while ((*bname) && (i < (YAFFS_MAX_NAME_LENGTH/2))) {
-+	if (tn) {
-+		if (level > 0) {
-+
-+			for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0;
-+			     i--) {
-+				if (tn->internal[i]) {
-+					allDone =
-+					    yaffs_soft_del_worker(in,
-+								   tn->
-+								   internal[i],
-+								   level - 1,
-+								   (chunk_offset
-+								    <<
-+								    YAFFS_TNODES_INTERNAL_BITS)
-+								   + i);
-+					if (allDone) {
-+						yaffs_free_tnode(dev,
-+								tn->
-+								internal[i]);
-+						tn->internal[i] = NULL;
-+					} else {
-+						/* Hoosterman... how could this happen? */
-+					}
-+				}
-+			}
-+			return (allDone) ? 1 : 0;
-+		} else if (level == 0) {
-+
-+			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) {
-+				theChunk = yaffs_get_group_base(dev, tn, i);
-+				if (theChunk) {
-+					/* Note this does not find the real chunk, only the chunk group.
-+					 * We make an assumption that a chunk group is not larger than
-+					 * a block.
-+					 */
-+					yaffs_soft_del_chunk(dev, theChunk);
-+					yaffs_load_tnode_0(dev, tn, i, 0);
-+				}
-+
-+			}
-+			return 1;
- 
--#ifdef CONFIG_YAFFS_CASE_INSENSITIVE
--			sum += yaffs_toupper(*bname) * i;
--#else
--			sum += (*bname) * i;
--#endif
--			i++;
--			bname++;
- 		}
-+
- 	}
--	return sum;
-+
-+	return 1;
-+
- }
- 
--static void yaffs_SetObjectName(yaffs_Object *obj, const YCHAR *name)
-+static void yaffs_soft_del_file(yaffs_obj_t *obj)
- {
--#ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
--	memset(obj->shortName, 0, sizeof(YCHAR) * (YAFFS_SHORT_NAME_LENGTH+1));
--	if (name && yaffs_strlen(name) <= YAFFS_SHORT_NAME_LENGTH)
--		yaffs_strcpy(obj->shortName, name);
--	else
--		obj->shortName[0] = _Y('\0');
--#endif
--	obj->sum = yaffs_CalcNameSum(name);
-+	if (obj->deleted &&
-+	    obj->variant_type == YAFFS_OBJECT_TYPE_FILE && !obj->soft_del) {
-+		if (obj->n_data_chunks <= 0) {
-+			/* Empty file with no duplicate object headers, just delete it immediately */
-+			yaffs_free_tnode(obj->my_dev,
-+					obj->variant.file_variant.top);
-+			obj->variant.file_variant.top = NULL;
-+			T(YAFFS_TRACE_TRACING,
-+			  (TSTR("yaffs: Deleting empty file %d" TENDSTR),
-+			   obj->obj_id));
-+			yaffs_generic_obj_del(obj);
-+		} else {
-+			yaffs_soft_del_worker(obj,
-+					       obj->variant.file_variant.top,
-+					       obj->variant.file_variant.
-+					       top_level, 0);
-+			obj->soft_del = 1;
-+		}
-+	}
- }
- 
--/*-------------------- TNODES -------------------
--
-- * List of spare tnodes
-- * The list is hooked together using the first pointer
-- * in the tnode.
-- */
--
--/* yaffs_CreateTnodes creates a bunch more tnodes and
-- * adds them to the tnode free list.
-- * Don't use this function directly
-+/* Pruning removes any part of the file structure tree that is beyond the
-+ * bounds of the file (ie that does not point to chunks).
-+ *
-+ * A file should only get pruned when its size is reduced.
-+ *
-+ * Before pruning, the chunks must be pulled from the tree and the
-+ * level 0 tnode entries must be zeroed out.
-+ * Could also use this for file deletion, but that's probably better handled
-+ * by a special case.
-+ *
-+ * This function is recursive. For levels > 0 the function is called again on
-+ * any sub-tree. For level == 0 we just check if the sub-tree has data.
-+ * If there is no data in a subtree then it is pruned.
-  */
- 
--static int yaffs_CreateTnodes(yaffs_Device *dev, int nTnodes)
-+static yaffs_tnode_t *yaffs_prune_worker(yaffs_dev_t *dev, yaffs_tnode_t *tn,
-+				__u32 level, int del0)
- {
- 	int i;
--	int tnodeSize;
--	yaffs_Tnode *newTnodes;
--	__u8 *mem;
--	yaffs_Tnode *curr;
--	yaffs_Tnode *next;
--	yaffs_TnodeList *tnl;
-+	int hasData;
- 
--	if (nTnodes < 1)
--		return YAFFS_OK;
-+	if (tn) {
-+		hasData = 0;
- 
--	/* Calculate the tnode size in bytes for variable width tnode support.
--	 * Must be a multiple of 32-bits  */
--	tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
-+		if(level > 0){
-+			for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) {
-+				if (tn->internal[i]) {
-+					tn->internal[i] =
-+						yaffs_prune_worker(dev, tn->internal[i],
-+							level - 1,
-+							(i == 0) ? del0 : 1);
-+				}
- 
--	if (tnodeSize < sizeof(yaffs_Tnode))
--		tnodeSize = sizeof(yaffs_Tnode);
-+				if (tn->internal[i])
-+					hasData++;
-+			}
-+		} else {
-+			int tnode_size_u32 = dev->tnode_size/sizeof(__u32);
-+			__u32 *map = (__u32 *)tn;
- 
--	/* make these things */
-+                        for(i = 0; !hasData && i < tnode_size_u32; i++){
-+                                if(map[i])
-+                                        hasData++;
-+                        }
-+                }
- 
--	newTnodes = YMALLOC(nTnodes * tnodeSize);
--	mem = (__u8 *)newTnodes;
-+		if (hasData == 0 && del0) {
-+			/* Free and return NULL */
- 
--	if (!newTnodes) {
--		T(YAFFS_TRACE_ERROR,
--			(TSTR("yaffs: Could not allocate Tnodes" TENDSTR)));
--		return YAFFS_FAIL;
--	}
-+			yaffs_free_tnode(dev, tn);
-+			tn = NULL;
-+		}
- 
--	/* Hook them into the free list */
--#if 0
--	for (i = 0; i < nTnodes - 1; i++) {
--		newTnodes[i].internal[0] = &newTnodes[i + 1];
--#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
--		newTnodes[i].internal[YAFFS_NTNODES_INTERNAL] = (void *)1;
--#endif
- 	}
- 
--	newTnodes[nTnodes - 1].internal[0] = dev->freeTnodes;
--#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
--	newTnodes[nTnodes - 1].internal[YAFFS_NTNODES_INTERNAL] = (void *)1;
--#endif
--	dev->freeTnodes = newTnodes;
--#else
--	/* New hookup for wide tnodes */
--	for (i = 0; i < nTnodes - 1; i++) {
--		curr = (yaffs_Tnode *) &mem[i * tnodeSize];
--		next = (yaffs_Tnode *) &mem[(i+1) * tnodeSize];
--		curr->internal[0] = next;
--	}
-+	return tn;
- 
--	curr = (yaffs_Tnode *) &mem[(nTnodes - 1) * tnodeSize];
--	curr->internal[0] = dev->freeTnodes;
--	dev->freeTnodes = (yaffs_Tnode *)mem;
-+}
- 
--#endif
-+static int yaffs_prune_tree(yaffs_dev_t *dev,
-+				yaffs_file_s *file_struct)
-+{
-+	int i;
-+	int hasData;
-+	int done = 0;
-+	yaffs_tnode_t *tn;
- 
-+	if (file_struct->top_level > 0) {
-+		file_struct->top =
-+		    yaffs_prune_worker(dev, file_struct->top, file_struct->top_level, 0);
-+
-+		/* Now we have a tree with all the non-zero branches NULL but the height
-+		 * is the same as it was.
-+		 * Let's see if we can trim internal tnodes to shorten the tree.
-+		 * We can do this if only the 0th element in the tnode is in use
-+		 * (ie all the non-zero are NULL)
-+		 */
- 
--	dev->nFreeTnodes += nTnodes;
--	dev->nTnodesCreated += nTnodes;
-+		while (file_struct->top_level && !done) {
-+			tn = file_struct->top;
- 
--	/* Now add this bunch of tnodes to a list for freeing up.
--	 * NB If we can't add this to the management list it isn't fatal
--	 * but it just means we can't free this bunch of tnodes later.
--	 */
-+			hasData = 0;
-+			for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {
-+				if (tn->internal[i])
-+					hasData++;
-+			}
- 
--	tnl = YMALLOC(sizeof(yaffs_TnodeList));
--	if (!tnl) {
--		T(YAFFS_TRACE_ERROR,
--		  (TSTR
--		   ("yaffs: Could not add tnodes to management list" TENDSTR)));
--		   return YAFFS_FAIL;
--	} else {
--		tnl->tnodes = newTnodes;
--		tnl->next = dev->allocatedTnodeList;
--		dev->allocatedTnodeList = tnl;
-+			if (!hasData) {
-+				file_struct->top = tn->internal[0];
-+				file_struct->top_level--;
-+				yaffs_free_tnode(dev, tn);
-+			} else {
-+				done = 1;
-+			}
-+		}
- 	}
- 
--	T(YAFFS_TRACE_ALLOCATE, (TSTR("yaffs: Tnodes added" TENDSTR)));
--
- 	return YAFFS_OK;
- }
- 
--/* GetTnode gets us a clean tnode. Tries to make allocate more if we run out */
-+/*-------------------- End of File Structure functions.-------------------*/
-+
- 
--static yaffs_Tnode *yaffs_GetTnodeRaw(yaffs_Device *dev)
-+/* AllocateEmptyObject gets us a clean Object. Tries to make allocate more if we run out */
-+static yaffs_obj_t *yaffs_alloc_empty_obj(yaffs_dev_t *dev)
- {
--	yaffs_Tnode *tn = NULL;
-+	yaffs_obj_t *obj = yaffs_alloc_raw_obj(dev);
- 
--	/* If there are none left make more */
--	if (!dev->freeTnodes)
--		yaffs_CreateTnodes(dev, YAFFS_ALLOCATION_NTNODES);
--
--	if (dev->freeTnodes) {
--		tn = dev->freeTnodes;
--#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
--		if (tn->internal[YAFFS_NTNODES_INTERNAL] != (void *)1) {
--			/* Hoosterman, this thing looks like it isn't in the list */
--			T(YAFFS_TRACE_ALWAYS,
--			  (TSTR("yaffs: Tnode list bug 1" TENDSTR)));
--		}
--#endif
--		dev->freeTnodes = dev->freeTnodes->internal[0];
--		dev->nFreeTnodes--;
--	}
-+	if (obj) {
-+		dev->n_obj++;
- 
--	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
-+		/* Now sweeten it up... */
- 
--	return tn;
--}
-+		memset(obj, 0, sizeof(yaffs_obj_t));
-+		obj->being_created = 1;
- 
--static yaffs_Tnode *yaffs_GetTnode(yaffs_Device *dev)
--{
--	yaffs_Tnode *tn = yaffs_GetTnodeRaw(dev);
--	int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
-+		obj->my_dev = dev;
-+		obj->hdr_chunk = 0;
-+		obj->variant_type = YAFFS_OBJECT_TYPE_UNKNOWN;
-+		YINIT_LIST_HEAD(&(obj->hard_links));
-+		YINIT_LIST_HEAD(&(obj->hash_link));
-+		YINIT_LIST_HEAD(&obj->siblings);
- 
--	if (tnodeSize < sizeof(yaffs_Tnode))
--		tnodeSize = sizeof(yaffs_Tnode);
- 
--	if (tn)
--		memset(tn, 0, tnodeSize);
-+		/* Now make the directory sane */
-+		if (dev->root_dir) {
-+			obj->parent = dev->root_dir;
-+			ylist_add(&(obj->siblings), &dev->root_dir->variant.dir_variant.children);
-+		}
- 
--	return tn;
-+		/* Add it to the lost and found directory.
-+		 * NB Can't put root or lostNFound in lostNFound so
-+		 * check if lostNFound exists first
-+		 */
-+		if (dev->lost_n_found)
-+			yaffs_add_obj_to_dir(dev->lost_n_found, obj);
-+
-+		obj->being_created = 0;
-+	}
-+
-+	dev->checkpoint_blocks_required = 0; /* force recalculation*/
-+
-+	return obj;
- }
- 
--/* FreeTnode frees up a tnode and puts it back on the free list */
--static void yaffs_FreeTnode(yaffs_Device *dev, yaffs_Tnode *tn)
-+static yaffs_obj_t *yaffs_create_fake_dir(yaffs_dev_t *dev, int number,
-+					       __u32 mode)
- {
--	if (tn) {
--#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
--		if (tn->internal[YAFFS_NTNODES_INTERNAL] != 0) {
--			/* Hoosterman, this thing looks like it is already in the list */
--			T(YAFFS_TRACE_ALWAYS,
--			  (TSTR("yaffs: Tnode list bug 2" TENDSTR)));
--		}
--		tn->internal[YAFFS_NTNODES_INTERNAL] = (void *)1;
--#endif
--		tn->internal[0] = dev->freeTnodes;
--		dev->freeTnodes = tn;
--		dev->nFreeTnodes++;
-+
-+	yaffs_obj_t *obj =
-+	    yaffs_new_obj(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);
-+	if (obj) {
-+		obj->fake = 1;		/* it is fake so it might have no NAND presence... */
-+		obj->rename_allowed = 0;	/* ... and we're not allowed to rename it... */
-+		obj->unlink_allowed = 0;	/* ... or unlink it */
-+		obj->deleted = 0;
-+		obj->unlinked = 0;
-+		obj->yst_mode = mode;
-+		obj->my_dev = dev;
-+		obj->hdr_chunk = 0;	/* Not a valid chunk. */
-+	}
-+
-+	return obj;
-+
-+}
-+
-+static void yaffs_unhash_obj(yaffs_obj_t *obj)
-+{
-+	int bucket;
-+	yaffs_dev_t *dev = obj->my_dev;
-+
-+	/* If it is still linked into the bucket list, free from the list */
-+	if (!ylist_empty(&obj->hash_link)) {
-+		ylist_del_init(&obj->hash_link);
-+		bucket = yaffs_hash_fn(obj->obj_id);
-+		dev->obj_bucket[bucket].count--;
- 	}
--	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
- }
- 
--static void yaffs_DeinitialiseTnodes(yaffs_Device *dev)
-+/*  FreeObject frees up a Object and puts it back on the free list */
-+static void yaffs_free_obj(yaffs_obj_t *obj)
- {
--	/* Free the list of allocated tnodes */
--	yaffs_TnodeList *tmp;
-+	yaffs_dev_t *dev = obj->my_dev;
-+
-+	T(YAFFS_TRACE_OS, (TSTR("FreeObject %p inode %p"TENDSTR), obj, obj->my_inode));
- 
--	while (dev->allocatedTnodeList) {
--		tmp = dev->allocatedTnodeList->next;
-+	if (!obj)
-+		YBUG();
-+	if (obj->parent)
-+		YBUG();
-+	if (!ylist_empty(&obj->siblings))
-+		YBUG();
- 
--		YFREE(dev->allocatedTnodeList->tnodes);
--		YFREE(dev->allocatedTnodeList);
--		dev->allocatedTnodeList = tmp;
- 
-+	if (obj->my_inode) {
-+		/* We're still hooked up to a cached inode.
-+		 * Don't delete now, but mark for later deletion
-+		 */
-+		obj->defered_free = 1;
-+		return;
- 	}
- 
--	dev->freeTnodes = NULL;
--	dev->nFreeTnodes = 0;
--}
-+	yaffs_unhash_obj(obj);
- 
--static void yaffs_InitialiseTnodes(yaffs_Device *dev)
--{
--	dev->allocatedTnodeList = NULL;
--	dev->freeTnodes = NULL;
--	dev->nFreeTnodes = 0;
--	dev->nTnodesCreated = 0;
-+	yaffs_free_raw_obj(dev,obj);
-+	dev->n_obj--;
-+	dev->checkpoint_blocks_required = 0; /* force recalculation*/
- }
- 
- 
--void yaffs_PutLevel0Tnode(yaffs_Device *dev, yaffs_Tnode *tn, unsigned pos,
--		unsigned val)
-+void yaffs_handle_defered_free(yaffs_obj_t *obj)
- {
--	__u32 *map = (__u32 *)tn;
--	__u32 bitInMap;
--	__u32 bitInWord;
--	__u32 wordInMap;
--	__u32 mask;
--
--	pos &= YAFFS_TNODES_LEVEL0_MASK;
--	val >>= dev->chunkGroupBits;
-+	if (obj->defered_free)
-+		yaffs_free_obj(obj);
-+}
- 
--	bitInMap = pos * dev->tnodeWidth;
--	wordInMap = bitInMap / 32;
--	bitInWord = bitInMap & (32 - 1);
-+static void yaffs_init_tnodes_and_objs(yaffs_dev_t *dev)
-+{
-+	int i;
- 
--	mask = dev->tnodeMask << bitInWord;
-+	dev->n_obj = 0;
-+	dev->n_tnodes = 0;
- 
--	map[wordInMap] &= ~mask;
--	map[wordInMap] |= (mask & (val << bitInWord));
-+	yaffs_init_raw_tnodes_and_objs(dev);
- 
--	if (dev->tnodeWidth > (32 - bitInWord)) {
--		bitInWord = (32 - bitInWord);
--		wordInMap++;;
--		mask = dev->tnodeMask >> (/*dev->tnodeWidth -*/ bitInWord);
--		map[wordInMap] &= ~mask;
--		map[wordInMap] |= (mask & (val >> bitInWord));
-+	for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
-+		YINIT_LIST_HEAD(&dev->obj_bucket[i].list);
-+		dev->obj_bucket[i].count = 0;
- 	}
- }
- 
--static __u32 yaffs_GetChunkGroupBase(yaffs_Device *dev, yaffs_Tnode *tn,
--		unsigned pos)
-+static int yaffs_find_nice_bucket(yaffs_dev_t *dev)
- {
--	__u32 *map = (__u32 *)tn;
--	__u32 bitInMap;
--	__u32 bitInWord;
--	__u32 wordInMap;
--	__u32 val;
-+	int i;
-+	int l = 999;
-+	int lowest = 999999;
- 
--	pos &= YAFFS_TNODES_LEVEL0_MASK;
- 
--	bitInMap = pos * dev->tnodeWidth;
--	wordInMap = bitInMap / 32;
--	bitInWord = bitInMap & (32 - 1);
-+	/* Search for the shortest list or one that
-+	 * isn't too long.
-+	 */
- 
--	val = map[wordInMap] >> bitInWord;
-+	for (i = 0; i < 10 && lowest > 4; i++) {
-+		dev->bucket_finder++;
-+		dev->bucket_finder %= YAFFS_NOBJECT_BUCKETS;
-+		if (dev->obj_bucket[dev->bucket_finder].count < lowest) {
-+			lowest = dev->obj_bucket[dev->bucket_finder].count;
-+			l = dev->bucket_finder;
-+		}
- 
--	if	(dev->tnodeWidth > (32 - bitInWord)) {
--		bitInWord = (32 - bitInWord);
--		wordInMap++;;
--		val |= (map[wordInMap] << bitInWord);
- 	}
- 
--	val &= dev->tnodeMask;
--	val <<= dev->chunkGroupBits;
--
--	return val;
-+	return l;
- }
- 
--/* ------------------- End of individual tnode manipulation -----------------*/
--
--/* ---------Functions to manipulate the look-up tree (made up of tnodes) ------
-- * The look up tree is represented by the top tnode and the number of topLevel
-- * in the tree. 0 means only the level 0 tnode is in the tree.
-- */
--
--/* FindLevel0Tnode finds the level 0 tnode, if one exists. */
--static yaffs_Tnode *yaffs_FindLevel0Tnode(yaffs_Device *dev,
--					yaffs_FileStructure *fStruct,
--					__u32 chunkId)
-+static int yaffs_new_obj_id(yaffs_dev_t *dev)
- {
--	yaffs_Tnode *tn = fStruct->top;
--	__u32 i;
--	int requiredTallness;
--	int level = fStruct->topLevel;
--
--	/* Check sane level and chunk Id */
--	if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL)
--		return NULL;
-+	int bucket = yaffs_find_nice_bucket(dev);
- 
--	if (chunkId > YAFFS_MAX_CHUNK_ID)
--		return NULL;
-+	/* Now find an object value that has not already been taken
-+	 * by scanning the list.
-+	 */
- 
--	/* First check we're tall enough (ie enough topLevel) */
-+	int found = 0;
-+	struct ylist_head *i;
- 
--	i = chunkId >> YAFFS_TNODES_LEVEL0_BITS;
--	requiredTallness = 0;
--	while (i) {
--		i >>= YAFFS_TNODES_INTERNAL_BITS;
--		requiredTallness++;
--	}
-+	__u32 n = (__u32) bucket;
- 
--	if (requiredTallness > fStruct->topLevel)
--		return NULL; /* Not tall enough, so we can't find it */
-+	/* yaffs_check_obj_hash_sane();  */
- 
--	/* Traverse down to level 0 */
--	while (level > 0 && tn) {
--		tn = tn->internal[(chunkId >>
--			(YAFFS_TNODES_LEVEL0_BITS +
--				(level - 1) *
--				YAFFS_TNODES_INTERNAL_BITS)) &
--			YAFFS_TNODES_INTERNAL_MASK];
--		level--;
-+	while (!found) {
-+		found = 1;
-+		n += YAFFS_NOBJECT_BUCKETS;
-+		if (1 || dev->obj_bucket[bucket].count > 0) {
-+			ylist_for_each(i, &dev->obj_bucket[bucket].list) {
-+				/* If there is already one in the list */
-+				if (i && ylist_entry(i, yaffs_obj_t,
-+						hash_link)->obj_id == n) {
-+					found = 0;
-+				}
-+			}
-+		}
- 	}
- 
--	return tn;
-+	return n;
- }
- 
--/* AddOrFindLevel0Tnode finds the level 0 tnode if it exists, otherwise first expands the tree.
-- * This happens in two steps:
-- *  1. If the tree isn't tall enough, then make it taller.
-- *  2. Scan down the tree towards the level 0 tnode adding tnodes if required.
-- *
-- * Used when modifying the tree.
-- *
-- *  If the tn argument is NULL, then a fresh tnode will be added otherwise the specified tn will
-- *  be plugged into the ttree.
-- */
--
--static yaffs_Tnode *yaffs_AddOrFindLevel0Tnode(yaffs_Device *dev,
--					yaffs_FileStructure *fStruct,
--					__u32 chunkId,
--					yaffs_Tnode *passedTn)
-+static void yaffs_hash_obj(yaffs_obj_t *in)
- {
--	int requiredTallness;
--	int i;
--	int l;
--	yaffs_Tnode *tn;
--
--	__u32 x;
-+	int bucket = yaffs_hash_fn(in->obj_id);
-+	yaffs_dev_t *dev = in->my_dev;
- 
-+	ylist_add(&in->hash_link, &dev->obj_bucket[bucket].list);
-+	dev->obj_bucket[bucket].count++;
-+}
- 
--	/* Check sane level and page Id */
--	if (fStruct->topLevel < 0 || fStruct->topLevel > YAFFS_TNODES_MAX_LEVEL)
--		return NULL;
-+yaffs_obj_t *yaffs_find_by_number(yaffs_dev_t *dev, __u32 number)
-+{
-+	int bucket = yaffs_hash_fn(number);
-+	struct ylist_head *i;
-+	yaffs_obj_t *in;
- 
--	if (chunkId > YAFFS_MAX_CHUNK_ID)
--		return NULL;
-+	ylist_for_each(i, &dev->obj_bucket[bucket].list) {
-+		/* Look if it is in the list */
-+		if (i) {
-+			in = ylist_entry(i, yaffs_obj_t, hash_link);
-+			if (in->obj_id == number) {
- 
--	/* First check we're tall enough (ie enough topLevel) */
-+				/* Don't tell the VFS about this one if it is defered free */
-+				if (in->defered_free)
-+					return NULL;
- 
--	x = chunkId >> YAFFS_TNODES_LEVEL0_BITS;
--	requiredTallness = 0;
--	while (x) {
--		x >>= YAFFS_TNODES_INTERNAL_BITS;
--		requiredTallness++;
-+				return in;
-+			}
-+		}
- 	}
- 
-+	return NULL;
-+}
- 
--	if (requiredTallness > fStruct->topLevel) {
--		/* Not tall enough, gotta make the tree taller */
--		for (i = fStruct->topLevel; i < requiredTallness; i++) {
-+yaffs_obj_t *yaffs_new_obj(yaffs_dev_t *dev, int number,
-+				    yaffs_obj_type type)
-+{
-+	yaffs_obj_t *theObject=NULL;
-+	yaffs_tnode_t *tn = NULL;
- 
--			tn = yaffs_GetTnode(dev);
-+	if (number < 0)
-+		number = yaffs_new_obj_id(dev);
- 
--			if (tn) {
--				tn->internal[0] = fStruct->top;
--				fStruct->top = tn;
--			} else {
--				T(YAFFS_TRACE_ERROR,
--				  (TSTR("yaffs: no more tnodes" TENDSTR)));
--			}
--		}
-+	if (type == YAFFS_OBJECT_TYPE_FILE) {
-+		tn = yaffs_get_tnode(dev);
-+		if (!tn)
-+			return NULL;
-+	}
- 
--		fStruct->topLevel = requiredTallness;
-+	theObject = yaffs_alloc_empty_obj(dev);
-+	if (!theObject){
-+		if(tn)
-+			yaffs_free_tnode(dev,tn);
-+		return NULL;
- 	}
- 
--	/* Traverse down to level 0, adding anything we need */
- 
--	l = fStruct->topLevel;
--	tn = fStruct->top;
-+	if (theObject) {
-+		theObject->fake = 0;
-+		theObject->rename_allowed = 1;
-+		theObject->unlink_allowed = 1;
-+		theObject->obj_id = number;
-+		yaffs_hash_obj(theObject);
-+		theObject->variant_type = type;
-+#ifdef CONFIG_YAFFS_WINCE
-+		yfsd_win_file_time_now(theObject->win_atime);
-+		theObject->win_ctime[0] = theObject->win_mtime[0] =
-+		    theObject->win_atime[0];
-+		theObject->win_ctime[1] = theObject->win_mtime[1] =
-+		    theObject->win_atime[1];
-+
-+#else
- 
--	if (l > 0) {
--		while (l > 0 && tn) {
--			x = (chunkId >>
--			     (YAFFS_TNODES_LEVEL0_BITS +
--			      (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) &
--			    YAFFS_TNODES_INTERNAL_MASK;
-+		theObject->yst_atime = theObject->yst_mtime =
-+		    theObject->yst_ctime = Y_CURRENT_TIME;
-+#endif
-+		switch (type) {
-+		case YAFFS_OBJECT_TYPE_FILE:
-+			theObject->variant.file_variant.file_size = 0;
-+			theObject->variant.file_variant.scanned_size = 0;
-+			theObject->variant.file_variant.shrink_size = 0xFFFFFFFF;	/* max __u32 */
-+			theObject->variant.file_variant.top_level = 0;
-+			theObject->variant.file_variant.top = tn;
-+			break;
-+		case YAFFS_OBJECT_TYPE_DIRECTORY:
-+			YINIT_LIST_HEAD(&theObject->variant.dir_variant.
-+					children);
-+			YINIT_LIST_HEAD(&theObject->variant.dir_variant.
-+					dirty);
-+			break;
-+		case YAFFS_OBJECT_TYPE_SYMLINK:
-+		case YAFFS_OBJECT_TYPE_HARDLINK:
-+		case YAFFS_OBJECT_TYPE_SPECIAL:
-+			/* No action required */
-+			break;
-+		case YAFFS_OBJECT_TYPE_UNKNOWN:
-+			/* todo this should not happen */
-+			break;
-+		}
-+	}
- 
-+	return theObject;
-+}
- 
--			if ((l > 1) && !tn->internal[x]) {
--				/* Add missing non-level-zero tnode */
--				tn->internal[x] = yaffs_GetTnode(dev);
-+yaffs_obj_t *yaffs_find_or_create_by_number(yaffs_dev_t *dev,
-+						int number,
-+						yaffs_obj_type type)
-+{
-+	yaffs_obj_t *theObject = NULL;
- 
--			} else if (l == 1) {
--				/* Looking from level 1 at level 0 */
--				if (passedTn) {
--					/* If we already have one, then release it.*/
--					if (tn->internal[x])
--						yaffs_FreeTnode(dev, tn->internal[x]);
--					tn->internal[x] = passedTn;
-+	if (number > 0)
-+		theObject = yaffs_find_by_number(dev, number);
- 
--				} else if (!tn->internal[x]) {
--					/* Don't have one, none passed in */
--					tn->internal[x] = yaffs_GetTnode(dev);
--				}
--			}
-+	if (!theObject)
-+		theObject = yaffs_new_obj(dev, number, type);
- 
--			tn = tn->internal[x];
--			l--;
--		}
--	} else {
--		/* top is level 0 */
--		if (passedTn) {
--			memcpy(tn, passedTn, (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8);
--			yaffs_FreeTnode(dev, passedTn);
--		}
--	}
-+	return theObject;
- 
--	return tn;
- }
- 
--static int yaffs_FindChunkInGroup(yaffs_Device *dev, int theChunk,
--				yaffs_ExtendedTags *tags, int objectId,
--				int chunkInInode)
-+
-+YCHAR *yaffs_clone_str(const YCHAR *str)
- {
--	int j;
-+	YCHAR *newStr = NULL;
-+	int len;
- 
--	for (j = 0; theChunk && j < dev->chunkGroupSize; j++) {
--		if (yaffs_CheckChunkBit(dev, theChunk / dev->nChunksPerBlock,
--				theChunk % dev->nChunksPerBlock)) {
--			yaffs_ReadChunkWithTagsFromNAND(dev, theChunk, NULL,
--							tags);
--			if (yaffs_TagsMatch(tags, objectId, chunkInInode)) {
--				/* found it; */
--				return theChunk;
--			}
--		}
--		theChunk++;
-+	if (!str)
-+		str = _Y("");
-+
-+	len = yaffs_strnlen(str,YAFFS_MAX_ALIAS_LENGTH);
-+	newStr = YMALLOC((len + 1) * sizeof(YCHAR));
-+	if (newStr){
-+		yaffs_strncpy(newStr, str,len);
-+		newStr[len] = 0;
- 	}
--	return -1;
--}
-+	return newStr;
- 
-+}
- 
--/* DeleteWorker scans backwards through the tnode tree and deletes all the
-- * chunks and tnodes in the file
-- * Returns 1 if the tree was deleted.
-- * Returns 0 if it stopped early due to hitting the limit and the delete is incomplete.
-+/*
-+ * Mknod (create) a new object.
-+ * equiv_obj only has meaning for a hard link;
-+ * aliasString only has meaning for a symlink.
-+ * rdev only has meaning for devices (a subset of special objects)
-  */
- 
--static int yaffs_DeleteWorker(yaffs_Object *in, yaffs_Tnode *tn, __u32 level,
--			      int chunkOffset, int *limit)
-+static yaffs_obj_t *yaffs_create_obj(yaffs_obj_type type,
-+				       yaffs_obj_t *parent,
-+				       const YCHAR *name,
-+				       __u32 mode,
-+				       __u32 uid,
-+				       __u32 gid,
-+				       yaffs_obj_t *equiv_obj,
-+				       const YCHAR *aliasString, __u32 rdev)
- {
--	int i;
--	int chunkInInode;
--	int theChunk;
--	yaffs_ExtendedTags tags;
--	int foundChunk;
--	yaffs_Device *dev = in->myDev;
--
--	int allDone = 1;
--
--	if (tn) {
--		if (level > 0) {
--			for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0;
--			     i--) {
--				if (tn->internal[i]) {
--					if (limit && (*limit) < 0) {
--						allDone = 0;
--					} else {
--						allDone =
--							yaffs_DeleteWorker(in,
--								tn->
--								internal
--								[i],
--								level -
--								1,
--								(chunkOffset
--									<<
--									YAFFS_TNODES_INTERNAL_BITS)
--								+ i,
--								limit);
--					}
--					if (allDone) {
--						yaffs_FreeTnode(dev,
--								tn->
--								internal[i]);
--						tn->internal[i] = NULL;
--					}
--				}
--			}
--			return (allDone) ? 1 : 0;
--		} else if (level == 0) {
--			int hitLimit = 0;
--
--			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0 && !hitLimit;
--					i--) {
--				theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
--				if (theChunk) {
--
--					chunkInInode = (chunkOffset <<
--						YAFFS_TNODES_LEVEL0_BITS) + i;
--
--					foundChunk =
--						yaffs_FindChunkInGroup(dev,
--								theChunk,
--								&tags,
--								in->objectId,
--								chunkInInode);
--
--					if (foundChunk > 0) {
--						yaffs_DeleteChunk(dev,
--								  foundChunk, 1,
--								  __LINE__);
--						in->nDataChunks--;
--						if (limit) {
--							*limit = *limit - 1;
--							if (*limit <= 0)
--								hitLimit = 1;
--						}
--
--					}
--
--					yaffs_PutLevel0Tnode(dev, tn, i, 0);
--				}
--
--			}
--			return (i < 0) ? 1 : 0;
--
--		}
--
--	}
--
--	return 1;
--
--}
--
--static void yaffs_SoftDeleteChunk(yaffs_Device *dev, int chunk)
--{
--	yaffs_BlockInfo *theBlock;
--
--	T(YAFFS_TRACE_DELETION, (TSTR("soft delete chunk %d" TENDSTR), chunk));
--
--	theBlock = yaffs_GetBlockInfo(dev, chunk / dev->nChunksPerBlock);
--	if (theBlock) {
--		theBlock->softDeletions++;
--		dev->nFreeChunks++;
--	}
--}
--
--/* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all the chunks in the file.
-- * All soft deleting does is increment the block's softdelete count and pulls the chunk out
-- * of the tnode.
-- * Thus, essentially this is the same as DeleteWorker except that the chunks are soft deleted.
-- */
--
--static int yaffs_SoftDeleteWorker(yaffs_Object *in, yaffs_Tnode *tn,
--				  __u32 level, int chunkOffset)
--{
--	int i;
--	int theChunk;
--	int allDone = 1;
--	yaffs_Device *dev = in->myDev;
--
--	if (tn) {
--		if (level > 0) {
--
--			for (i = YAFFS_NTNODES_INTERNAL - 1; allDone && i >= 0;
--			     i--) {
--				if (tn->internal[i]) {
--					allDone =
--					    yaffs_SoftDeleteWorker(in,
--								   tn->
--								   internal[i],
--								   level - 1,
--								   (chunkOffset
--								    <<
--								    YAFFS_TNODES_INTERNAL_BITS)
--								   + i);
--					if (allDone) {
--						yaffs_FreeTnode(dev,
--								tn->
--								internal[i]);
--						tn->internal[i] = NULL;
--					} else {
--						/* Hoosterman... how could this happen? */
--					}
--				}
--			}
--			return (allDone) ? 1 : 0;
--		} else if (level == 0) {
--
--			for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) {
--				theChunk = yaffs_GetChunkGroupBase(dev, tn, i);
--				if (theChunk) {
--					/* Note this does not find the real chunk, only the chunk group.
--					 * We make an assumption that a chunk group is not larger than
--					 * a block.
--					 */
--					yaffs_SoftDeleteChunk(dev, theChunk);
--					yaffs_PutLevel0Tnode(dev, tn, i, 0);
--				}
--
--			}
--			return 1;
--
--		}
--
--	}
--
--	return 1;
--
--}
--
--static void yaffs_SoftDeleteFile(yaffs_Object *obj)
--{
--	if (obj->deleted &&
--	    obj->variantType == YAFFS_OBJECT_TYPE_FILE && !obj->softDeleted) {
--		if (obj->nDataChunks <= 0) {
--			/* Empty file with no duplicate object headers, just delete it immediately */
--			yaffs_FreeTnode(obj->myDev,
--					obj->variant.fileVariant.top);
--			obj->variant.fileVariant.top = NULL;
--			T(YAFFS_TRACE_TRACING,
--			  (TSTR("yaffs: Deleting empty file %d" TENDSTR),
--			   obj->objectId));
--			yaffs_DoGenericObjectDeletion(obj);
--		} else {
--			yaffs_SoftDeleteWorker(obj,
--					       obj->variant.fileVariant.top,
--					       obj->variant.fileVariant.
--					       topLevel, 0);
--			obj->softDeleted = 1;
--		}
--	}
--}
--
--/* Pruning removes any part of the file structure tree that is beyond the
-- * bounds of the file (ie that does not point to chunks).
-- *
-- * A file should only get pruned when its size is reduced.
-- *
-- * Before pruning, the chunks must be pulled from the tree and the
-- * level 0 tnode entries must be zeroed out.
-- * Could also use this for file deletion, but that's probably better handled
-- * by a special case.
-- */
--
--static yaffs_Tnode *yaffs_PruneWorker(yaffs_Device *dev, yaffs_Tnode *tn,
--				__u32 level, int del0)
--{
--	int i;
--	int hasData;
--
--	if (tn) {
--		hasData = 0;
--
--		for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) {
--			if (tn->internal[i] && level > 0) {
--				tn->internal[i] =
--				    yaffs_PruneWorker(dev, tn->internal[i],
--						      level - 1,
--						      (i == 0) ? del0 : 1);
--			}
--
--			if (tn->internal[i])
--				hasData++;
--		}
--
--		if (hasData == 0 && del0) {
--			/* Free and return NULL */
--
--			yaffs_FreeTnode(dev, tn);
--			tn = NULL;
--		}
--
--	}
--
--	return tn;
--
--}
--
--static int yaffs_PruneFileStructure(yaffs_Device *dev,
--				yaffs_FileStructure *fStruct)
--{
--	int i;
--	int hasData;
--	int done = 0;
--	yaffs_Tnode *tn;
--
--	if (fStruct->topLevel > 0) {
--		fStruct->top =
--		    yaffs_PruneWorker(dev, fStruct->top, fStruct->topLevel, 0);
--
--		/* Now we have a tree with all the non-zero branches NULL but the height
--		 * is the same as it was.
--		 * Let's see if we can trim internal tnodes to shorten the tree.
--		 * We can do this if only the 0th element in the tnode is in use
--		 * (ie all the non-zero are NULL)
--		 */
--
--		while (fStruct->topLevel && !done) {
--			tn = fStruct->top;
--
--			hasData = 0;
--			for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {
--				if (tn->internal[i])
--					hasData++;
--			}
--
--			if (!hasData) {
--				fStruct->top = tn->internal[0];
--				fStruct->topLevel--;
--				yaffs_FreeTnode(dev, tn);
--			} else {
--				done = 1;
--			}
--		}
--	}
--
--	return YAFFS_OK;
--}
--
--/*-------------------- End of File Structure functions.-------------------*/
--
--/* yaffs_CreateFreeObjects creates a bunch more objects and
-- * adds them to the object free list.
-- */
--static int yaffs_CreateFreeObjects(yaffs_Device *dev, int nObjects)
--{
--	int i;
--	yaffs_Object *newObjects;
--	yaffs_ObjectList *list;
--
--	if (nObjects < 1)
--		return YAFFS_OK;
--
--	/* make these things */
--	newObjects = YMALLOC(nObjects * sizeof(yaffs_Object));
--	list = YMALLOC(sizeof(yaffs_ObjectList));
--
--	if (!newObjects || !list) {
--		if (newObjects)
--			YFREE(newObjects);
--		if (list)
--			YFREE(list);
--		T(YAFFS_TRACE_ALLOCATE,
--		  (TSTR("yaffs: Could not allocate more objects" TENDSTR)));
--		return YAFFS_FAIL;
--	}
--
--	/* Hook them into the free list */
--	for (i = 0; i < nObjects - 1; i++) {
--		newObjects[i].siblings.next =
--				(struct ylist_head *)(&newObjects[i + 1]);
--	}
--
--	newObjects[nObjects - 1].siblings.next = (void *)dev->freeObjects;
--	dev->freeObjects = newObjects;
--	dev->nFreeObjects += nObjects;
--	dev->nObjectsCreated += nObjects;
--
--	/* Now add this bunch of Objects to a list for freeing up. */
--
--	list->objects = newObjects;
--	list->next = dev->allocatedObjectList;
--	dev->allocatedObjectList = list;
--
--	return YAFFS_OK;
--}
--
--
--/* AllocateEmptyObject gets us a clean Object. Tries to make allocate more if we run out */
--static yaffs_Object *yaffs_AllocateEmptyObject(yaffs_Device *dev)
--{
--	yaffs_Object *tn = NULL;
--
--#ifdef VALGRIND_TEST
--	tn = YMALLOC(sizeof(yaffs_Object));
--#else
--	/* If there are none left make more */
--	if (!dev->freeObjects)
--		yaffs_CreateFreeObjects(dev, YAFFS_ALLOCATION_NOBJECTS);
--
--	if (dev->freeObjects) {
--		tn = dev->freeObjects;
--		dev->freeObjects =
--			(yaffs_Object *) (dev->freeObjects->siblings.next);
--		dev->nFreeObjects--;
--	}
--#endif
--	if (tn) {
--		/* Now sweeten it up... */
--
--		memset(tn, 0, sizeof(yaffs_Object));
--		tn->beingCreated = 1;
--
--		tn->myDev = dev;
--		tn->hdrChunk = 0;
--		tn->variantType = YAFFS_OBJECT_TYPE_UNKNOWN;
--		YINIT_LIST_HEAD(&(tn->hardLinks));
--		YINIT_LIST_HEAD(&(tn->hashLink));
--		YINIT_LIST_HEAD(&tn->siblings);
--
--
--		/* Now make the directory sane */
--		if (dev->rootDir) {
--			tn->parent = dev->rootDir;
--			ylist_add(&(tn->siblings), &dev->rootDir->variant.directoryVariant.children);
--		}
--
--		/* Add it to the lost and found directory.
--		 * NB Can't put root or lostNFound in lostNFound so
--		 * check if lostNFound exists first
--		 */
--		if (dev->lostNFoundDir)
--			yaffs_AddObjectToDirectory(dev->lostNFoundDir, tn);
--
--		tn->beingCreated = 0;
--	}
--
--	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
--
--	return tn;
--}
--
--static yaffs_Object *yaffs_CreateFakeDirectory(yaffs_Device *dev, int number,
--					       __u32 mode)
--{
--
--	yaffs_Object *obj =
--	    yaffs_CreateNewObject(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);
--	if (obj) {
--		obj->fake = 1;		/* it is fake so it might have no NAND presence... */
--		obj->renameAllowed = 0;	/* ... and we're not allowed to rename it... */
--		obj->unlinkAllowed = 0;	/* ... or unlink it */
--		obj->deleted = 0;
--		obj->unlinked = 0;
--		obj->yst_mode = mode;
--		obj->myDev = dev;
--		obj->hdrChunk = 0;	/* Not a valid chunk. */
--	}
--
--	return obj;
--
--}
--
--static void yaffs_UnhashObject(yaffs_Object *tn)
--{
--	int bucket;
--	yaffs_Device *dev = tn->myDev;
--
--	/* If it is still linked into the bucket list, free from the list */
--	if (!ylist_empty(&tn->hashLink)) {
--		ylist_del_init(&tn->hashLink);
--		bucket = yaffs_HashFunction(tn->objectId);
--		dev->objectBucket[bucket].count--;
--	}
--}
--
--/*  FreeObject frees up a Object and puts it back on the free list */
--static void yaffs_FreeObject(yaffs_Object *tn)
--{
--	yaffs_Device *dev = tn->myDev;
--
--#ifdef __KERNEL__
--	T(YAFFS_TRACE_OS, (TSTR("FreeObject %p inode %p"TENDSTR), tn, tn->myInode));
--#endif
--
--	if (tn->parent)
--		YBUG();
--	if (!ylist_empty(&tn->siblings))
--		YBUG();
--
--
--#ifdef __KERNEL__
--	if (tn->myInode) {
--		/* We're still hooked up to a cached inode.
--		 * Don't delete now, but mark for later deletion
--		 */
--		tn->deferedFree = 1;
--		return;
--	}
--#endif
--
--	yaffs_UnhashObject(tn);
--
--#ifdef VALGRIND_TEST
--	YFREE(tn);
--#else
--	/* Link into the free list. */
--	tn->siblings.next = (struct ylist_head *)(dev->freeObjects);
--	dev->freeObjects = tn;
--	dev->nFreeObjects++;
--#endif
--	dev->nCheckpointBlocksRequired = 0; /* force recalculation*/
--}
--
--#ifdef __KERNEL__
--
--void yaffs_HandleDeferedFree(yaffs_Object *obj)
--{
--	if (obj->deferedFree)
--		yaffs_FreeObject(obj);
--}
--
--#endif
--
--static void yaffs_DeinitialiseObjects(yaffs_Device *dev)
--{
--	/* Free the list of allocated Objects */
--
--	yaffs_ObjectList *tmp;
--
--	while (dev->allocatedObjectList) {
--		tmp = dev->allocatedObjectList->next;
--		YFREE(dev->allocatedObjectList->objects);
--		YFREE(dev->allocatedObjectList);
--
--		dev->allocatedObjectList = tmp;
--	}
--
--	dev->freeObjects = NULL;
--	dev->nFreeObjects = 0;
--}
--
--static void yaffs_InitialiseObjects(yaffs_Device *dev)
--{
--	int i;
--
--	dev->allocatedObjectList = NULL;
--	dev->freeObjects = NULL;
--	dev->nFreeObjects = 0;
--
--	for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
--		YINIT_LIST_HEAD(&dev->objectBucket[i].list);
--		dev->objectBucket[i].count = 0;
--	}
--}
--
--static int yaffs_FindNiceObjectBucket(yaffs_Device *dev)
--{
--	static int x;
--	int i;
--	int l = 999;
--	int lowest = 999999;
--
--	/* First let's see if we can find one that's empty. */
--
--	for (i = 0; i < 10 && lowest > 0; i++) {
--		x++;
--		x %= YAFFS_NOBJECT_BUCKETS;
--		if (dev->objectBucket[x].count < lowest) {
--			lowest = dev->objectBucket[x].count;
--			l = x;
--		}
--
--	}
--
--	/* If we didn't find an empty list, then try
--	 * looking a bit further for a short one
--	 */
--
--	for (i = 0; i < 10 && lowest > 3; i++) {
--		x++;
--		x %= YAFFS_NOBJECT_BUCKETS;
--		if (dev->objectBucket[x].count < lowest) {
--			lowest = dev->objectBucket[x].count;
--			l = x;
--		}
--
--	}
--
--	return l;
--}
--
--static int yaffs_CreateNewObjectNumber(yaffs_Device *dev)
--{
--	int bucket = yaffs_FindNiceObjectBucket(dev);
--
--	/* Now find an object value that has not already been taken
--	 * by scanning the list.
--	 */
--
--	int found = 0;
--	struct ylist_head *i;
--
--	__u32 n = (__u32) bucket;
--
--	/* yaffs_CheckObjectHashSanity();  */
--
--	while (!found) {
--		found = 1;
--		n += YAFFS_NOBJECT_BUCKETS;
--		if (1 || dev->objectBucket[bucket].count > 0) {
--			ylist_for_each(i, &dev->objectBucket[bucket].list) {
--				/* If there is already one in the list */
--				if (i && ylist_entry(i, yaffs_Object,
--						hashLink)->objectId == n) {
--					found = 0;
--				}
--			}
--		}
--	}
--
--	return n;
--}
--
--static void yaffs_HashObject(yaffs_Object *in)
--{
--	int bucket = yaffs_HashFunction(in->objectId);
--	yaffs_Device *dev = in->myDev;
--
--	ylist_add(&in->hashLink, &dev->objectBucket[bucket].list);
--	dev->objectBucket[bucket].count++;
--}
--
--yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev, __u32 number)
--{
--	int bucket = yaffs_HashFunction(number);
--	struct ylist_head *i;
--	yaffs_Object *in;
--
--	ylist_for_each(i, &dev->objectBucket[bucket].list) {
--		/* Look if it is in the list */
--		if (i) {
--			in = ylist_entry(i, yaffs_Object, hashLink);
--			if (in->objectId == number) {
--#ifdef __KERNEL__
--				/* Don't tell the VFS about this one if it is defered free */
--				if (in->deferedFree)
--					return NULL;
--#endif
--
--				return in;
--			}
--		}
--	}
--
--	return NULL;
--}
--
--yaffs_Object *yaffs_CreateNewObject(yaffs_Device *dev, int number,
--				    yaffs_ObjectType type)
--{
--	yaffs_Object *theObject;
--	yaffs_Tnode *tn = NULL;
--
--	if (number < 0)
--		number = yaffs_CreateNewObjectNumber(dev);
--
--	theObject = yaffs_AllocateEmptyObject(dev);
--	if (!theObject)
--		return NULL;
--
--	if (type == YAFFS_OBJECT_TYPE_FILE) {
--		tn = yaffs_GetTnode(dev);
--		if (!tn) {
--			yaffs_FreeObject(theObject);
--			return NULL;
--		}
--	}
--
--	if (theObject) {
--		theObject->fake = 0;
--		theObject->renameAllowed = 1;
--		theObject->unlinkAllowed = 1;
--		theObject->objectId = number;
--		yaffs_HashObject(theObject);
--		theObject->variantType = type;
--#ifdef CONFIG_YAFFS_WINCE
--		yfsd_WinFileTimeNow(theObject->win_atime);
--		theObject->win_ctime[0] = theObject->win_mtime[0] =
--		    theObject->win_atime[0];
--		theObject->win_ctime[1] = theObject->win_mtime[1] =
--		    theObject->win_atime[1];
--
--#else
--
--		theObject->yst_atime = theObject->yst_mtime =
--		    theObject->yst_ctime = Y_CURRENT_TIME;
--#endif
--		switch (type) {
--		case YAFFS_OBJECT_TYPE_FILE:
--			theObject->variant.fileVariant.fileSize = 0;
--			theObject->variant.fileVariant.scannedFileSize = 0;
--			theObject->variant.fileVariant.shrinkSize = 0xFFFFFFFF;	/* max __u32 */
--			theObject->variant.fileVariant.topLevel = 0;
--			theObject->variant.fileVariant.top = tn;
--			break;
--		case YAFFS_OBJECT_TYPE_DIRECTORY:
--			YINIT_LIST_HEAD(&theObject->variant.directoryVariant.
--					children);
--			break;
--		case YAFFS_OBJECT_TYPE_SYMLINK:
--		case YAFFS_OBJECT_TYPE_HARDLINK:
--		case YAFFS_OBJECT_TYPE_SPECIAL:
--			/* No action required */
--			break;
--		case YAFFS_OBJECT_TYPE_UNKNOWN:
--			/* todo this should not happen */
--			break;
--		}
--	}
--
--	return theObject;
--}
--
--static yaffs_Object *yaffs_FindOrCreateObjectByNumber(yaffs_Device *dev,
--						      int number,
--						      yaffs_ObjectType type)
--{
--	yaffs_Object *theObject = NULL;
--
--	if (number > 0)
--		theObject = yaffs_FindObjectByNumber(dev, number);
--
--	if (!theObject)
--		theObject = yaffs_CreateNewObject(dev, number, type);
--
--	return theObject;
--
--}
--
--
--static YCHAR *yaffs_CloneString(const YCHAR *str)
--{
--	YCHAR *newStr = NULL;
--
--	if (str && *str) {
--		newStr = YMALLOC((yaffs_strlen(str) + 1) * sizeof(YCHAR));
--		if (newStr)
--			yaffs_strcpy(newStr, str);
--	}
--
--	return newStr;
--
--}
--
--/*
-- * Mknod (create) a new object.
-- * equivalentObject only has meaning for a hard link;
-- * aliasString only has meaning for a sumlink.
-- * rdev only has meaning for devices (a subset of special objects)
-- */
--
--static yaffs_Object *yaffs_MknodObject(yaffs_ObjectType type,
--				       yaffs_Object *parent,
--				       const YCHAR *name,
--				       __u32 mode,
--				       __u32 uid,
--				       __u32 gid,
--				       yaffs_Object *equivalentObject,
--				       const YCHAR *aliasString, __u32 rdev)
--{
--	yaffs_Object *in;
--	YCHAR *str = NULL;
--
--	yaffs_Device *dev = parent->myDev;
--
--	/* Check if the entry exists. If it does then fail the call since we don't want a dup.*/
--	if (yaffs_FindObjectByName(parent, name))
--		return NULL;
--
--	in = yaffs_CreateNewObject(dev, -1, type);
--
--	if (!in)
--		return YAFFS_FAIL;
--
--	if (type == YAFFS_OBJECT_TYPE_SYMLINK) {
--		str = yaffs_CloneString(aliasString);
--		if (!str) {
--			yaffs_FreeObject(in);
--			return NULL;
--		}
--	}
--
--
--
--	if (in) {
--		in->hdrChunk = 0;
--		in->valid = 1;
--		in->variantType = type;
--
--		in->yst_mode = mode;
--
--#ifdef CONFIG_YAFFS_WINCE
--		yfsd_WinFileTimeNow(in->win_atime);
--		in->win_ctime[0] = in->win_mtime[0] = in->win_atime[0];
--		in->win_ctime[1] = in->win_mtime[1] = in->win_atime[1];
--
--#else
--		in->yst_atime = in->yst_mtime = in->yst_ctime = Y_CURRENT_TIME;
--
--		in->yst_rdev = rdev;
--		in->yst_uid = uid;
--		in->yst_gid = gid;
--#endif
--		in->nDataChunks = 0;
--
--		yaffs_SetObjectName(in, name);
--		in->dirty = 1;
--
--		yaffs_AddObjectToDirectory(parent, in);
--
--		in->myDev = parent->myDev;
--
--		switch (type) {
--		case YAFFS_OBJECT_TYPE_SYMLINK:
--			in->variant.symLinkVariant.alias = str;
--			break;
--		case YAFFS_OBJECT_TYPE_HARDLINK:
--			in->variant.hardLinkVariant.equivalentObject =
--				equivalentObject;
--			in->variant.hardLinkVariant.equivalentObjectId =
--				equivalentObject->objectId;
--			ylist_add(&in->hardLinks, &equivalentObject->hardLinks);
--			break;
--		case YAFFS_OBJECT_TYPE_FILE:
--		case YAFFS_OBJECT_TYPE_DIRECTORY:
--		case YAFFS_OBJECT_TYPE_SPECIAL:
--		case YAFFS_OBJECT_TYPE_UNKNOWN:
--			/* do nothing */
--			break;
--		}
--
--		if (yaffs_UpdateObjectHeader(in, name, 0, 0, 0) < 0) {
--			/* Could not create the object header, fail the creation */
--			yaffs_DeleteObject(in);
--			in = NULL;
--		}
--
--	}
--
--	return in;
--}
--
--yaffs_Object *yaffs_MknodFile(yaffs_Object *parent, const YCHAR *name,
--			__u32 mode, __u32 uid, __u32 gid)
--{
--	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_FILE, parent, name, mode,
--				uid, gid, NULL, NULL, 0);
--}
--
--yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent, const YCHAR *name,
--				__u32 mode, __u32 uid, __u32 gid)
--{
--	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name,
--				 mode, uid, gid, NULL, NULL, 0);
--}
--
--yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent, const YCHAR *name,
--				__u32 mode, __u32 uid, __u32 gid, __u32 rdev)
--{
--	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode,
--				 uid, gid, NULL, NULL, rdev);
--}
--
--yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const YCHAR *name,
--				__u32 mode, __u32 uid, __u32 gid,
--				const YCHAR *alias)
--{
--	return yaffs_MknodObject(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode,
--				uid, gid, NULL, alias, 0);
--}
--
--/* yaffs_Link returns the object id of the equivalent object.*/
--yaffs_Object *yaffs_Link(yaffs_Object *parent, const YCHAR *name,
--			yaffs_Object *equivalentObject)
--{
--	/* Get the real object in case we were fed a hard link as an equivalent object */
--	equivalentObject = yaffs_GetEquivalentObject(equivalentObject);
--
--	if (yaffs_MknodObject
--	    (YAFFS_OBJECT_TYPE_HARDLINK, parent, name, 0, 0, 0,
--	     equivalentObject, NULL, 0)) {
--		return equivalentObject;
--	} else {
--		return NULL;
--	}
--
--}
--
--static int yaffs_ChangeObjectName(yaffs_Object *obj, yaffs_Object *newDir,
--				const YCHAR *newName, int force, int shadows)
--{
--	int unlinkOp;
--	int deleteOp;
--
--	yaffs_Object *existingTarget;
--
--	if (newDir == NULL)
--		newDir = obj->parent;	/* use the old directory */
--
--	if (newDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
--		T(YAFFS_TRACE_ALWAYS,
--		  (TSTR
--		   ("tragedy: yaffs_ChangeObjectName: newDir is not a directory"
--		    TENDSTR)));
--		YBUG();
--	}
--
--	/* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
--	if (obj->myDev->isYaffs2)
--		unlinkOp = (newDir == obj->myDev->unlinkedDir);
--	else
--		unlinkOp = (newDir == obj->myDev->unlinkedDir
--			    && obj->variantType == YAFFS_OBJECT_TYPE_FILE);
--
--	deleteOp = (newDir == obj->myDev->deletedDir);
--
--	existingTarget = yaffs_FindObjectByName(newDir, newName);
--
--	/* If the object is a file going into the unlinked directory,
--	 *   then it is OK to just stuff it in since duplicate names are allowed.
--	 *   else only proceed if the new name does not exist and if we're putting
--	 *   it into a directory.
--	 */
--	if ((unlinkOp ||
--	     deleteOp ||
--	     force ||
--	     (shadows > 0) ||
--	     !existingTarget) &&
--	    newDir->variantType == YAFFS_OBJECT_TYPE_DIRECTORY) {
--		yaffs_SetObjectName(obj, newName);
--		obj->dirty = 1;
--
--		yaffs_AddObjectToDirectory(newDir, obj);
--
--		if (unlinkOp)
--			obj->unlinked = 1;
--
--		/* If it is a deletion then we mark it as a shrink for gc purposes. */
--		if (yaffs_UpdateObjectHeader(obj, newName, 0, deleteOp, shadows) >= 0)
--			return YAFFS_OK;
--	}
--
--	return YAFFS_FAIL;
--}
--
--int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
--		yaffs_Object *newDir, const YCHAR *newName)
--{
--	yaffs_Object *obj = NULL;
--	yaffs_Object *existingTarget = NULL;
--	int force = 0;
--
--
--	if (!oldDir || oldDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
--		YBUG();
--	if (!newDir || newDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY)
--		YBUG();
--
--#ifdef CONFIG_YAFFS_CASE_INSENSITIVE
--	/* Special case for case insemsitive systems (eg. WinCE).
--	 * While look-up is case insensitive, the name isn't.
--	 * Therefore we might want to change x.txt to X.txt
--	*/
--	if (oldDir == newDir && yaffs_strcmp(oldName, newName) == 0)
--		force = 1;
--#endif
--
--	else if (yaffs_strlen(newName) > YAFFS_MAX_NAME_LENGTH)
--		/* ENAMETOOLONG */
--		return YAFFS_FAIL;
--
--	obj = yaffs_FindObjectByName(oldDir, oldName);
--
--	if (obj && obj->renameAllowed) {
--
--		/* Now do the handling for an existing target, if there is one */
--
--		existingTarget = yaffs_FindObjectByName(newDir, newName);
--		if (existingTarget &&
--			existingTarget->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
--			!ylist_empty(&existingTarget->variant.directoryVariant.children)) {
--			/* There is a target that is a non-empty directory, so we fail */
--			return YAFFS_FAIL;	/* EEXIST or ENOTEMPTY */
--		} else if (existingTarget && existingTarget != obj) {
--			/* Nuke the target first, using shadowing,
--			 * but only if it isn't the same object
--			 */
--			yaffs_ChangeObjectName(obj, newDir, newName, force,
--						existingTarget->objectId);
--			yaffs_UnlinkObject(existingTarget);
--		}
--
--		return yaffs_ChangeObjectName(obj, newDir, newName, 1, 0);
--	}
--	return YAFFS_FAIL;
--}
--
--/*------------------------- Block Management and Page Allocation ----------------*/
--
--static int yaffs_InitialiseBlocks(yaffs_Device *dev)
--{
--	int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
--
--	dev->blockInfo = NULL;
--	dev->chunkBits = NULL;
--
--	dev->allocationBlock = -1;	/* force it to get a new one */
--
--	/* If the first allocation strategy fails, thry the alternate one */
--	dev->blockInfo = YMALLOC(nBlocks * sizeof(yaffs_BlockInfo));
--	if (!dev->blockInfo) {
--		dev->blockInfo = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockInfo));
--		dev->blockInfoAlt = 1;
--	} else
--		dev->blockInfoAlt = 0;
--
--	if (dev->blockInfo) {
--		/* Set up dynamic blockinfo stuff. */
--		dev->chunkBitmapStride = (dev->nChunksPerBlock + 7) / 8; /* round up bytes */
--		dev->chunkBits = YMALLOC(dev->chunkBitmapStride * nBlocks);
--		if (!dev->chunkBits) {
--			dev->chunkBits = YMALLOC_ALT(dev->chunkBitmapStride * nBlocks);
--			dev->chunkBitsAlt = 1;
--		} else
--			dev->chunkBitsAlt = 0;
--	}
--
--	if (dev->blockInfo && dev->chunkBits) {
--		memset(dev->blockInfo, 0, nBlocks * sizeof(yaffs_BlockInfo));
--		memset(dev->chunkBits, 0, dev->chunkBitmapStride * nBlocks);
--		return YAFFS_OK;
--	}
--
--	return YAFFS_FAIL;
--}
--
--static void yaffs_DeinitialiseBlocks(yaffs_Device *dev)
--{
--	if (dev->blockInfoAlt && dev->blockInfo)
--		YFREE_ALT(dev->blockInfo);
--	else if (dev->blockInfo)
--		YFREE(dev->blockInfo);
--
--	dev->blockInfoAlt = 0;
--
--	dev->blockInfo = NULL;
--
--	if (dev->chunkBitsAlt && dev->chunkBits)
--		YFREE_ALT(dev->chunkBits);
--	else if (dev->chunkBits)
--		YFREE(dev->chunkBits);
--	dev->chunkBitsAlt = 0;
--	dev->chunkBits = NULL;
--}
--
--static int yaffs_BlockNotDisqualifiedFromGC(yaffs_Device *dev,
--					yaffs_BlockInfo *bi)
--{
--	int i;
--	__u32 seq;
--	yaffs_BlockInfo *b;
--
--	if (!dev->isYaffs2)
--		return 1;	/* disqualification only applies to yaffs2. */
--
--	if (!bi->hasShrinkHeader)
--		return 1;	/* can gc */
--
--	/* Find the oldest dirty sequence number if we don't know it and save it
--	 * so we don't have to keep recomputing it.
--	 */
--	if (!dev->oldestDirtySequence) {
--		seq = dev->sequenceNumber;
--
--		for (i = dev->internalStartBlock; i <= dev->internalEndBlock;
--				i++) {
--			b = yaffs_GetBlockInfo(dev, i);
--			if (b->blockState == YAFFS_BLOCK_STATE_FULL &&
--			    (b->pagesInUse - b->softDeletions) <
--			    dev->nChunksPerBlock && b->sequenceNumber < seq) {
--				seq = b->sequenceNumber;
--			}
--		}
--		dev->oldestDirtySequence = seq;
--	}
--
--	/* Can't do gc of this block if there are any blocks older than this one that have
--	 * discarded pages.
--	 */
--	return (bi->sequenceNumber <= dev->oldestDirtySequence);
--}
--
--/* FindDiretiestBlock is used to select the dirtiest block (or close enough)
-- * for garbage collection.
-- */
--
--static int yaffs_FindBlockForGarbageCollection(yaffs_Device *dev,
--					int aggressive)
--{
--	int b = dev->currentDirtyChecker;
--
--	int i;
--	int iterations;
--	int dirtiest = -1;
--	int pagesInUse = 0;
--	int prioritised = 0;
--	yaffs_BlockInfo *bi;
--	int pendingPrioritisedExist = 0;
--
--	/* First let's see if we need to grab a prioritised block */
--	if (dev->hasPendingPrioritisedGCs) {
--		for (i = dev->internalStartBlock; i < dev->internalEndBlock && !prioritised; i++) {
--
--			bi = yaffs_GetBlockInfo(dev, i);
--			/* yaffs_VerifyBlock(dev,bi,i); */
--
--			if (bi->gcPrioritise) {
--				pendingPrioritisedExist = 1;
--				if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
--				   yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
--					pagesInUse = (bi->pagesInUse - bi->softDeletions);
--					dirtiest = i;
--					prioritised = 1;
--					aggressive = 1; /* Fool the non-aggressive skip logiv below */
--				}
--			}
--		}
--
--		if (!pendingPrioritisedExist) /* None found, so we can clear this */
--			dev->hasPendingPrioritisedGCs = 0;
--	}
--
--	/* If we're doing aggressive GC then we are happy to take a less-dirty block, and
--	 * search harder.
--	 * else (we're doing a leasurely gc), then we only bother to do this if the
--	 * block has only a few pages in use.
--	 */
--
--	dev->nonAggressiveSkip--;
--
--	if (!aggressive && (dev->nonAggressiveSkip > 0))
--		return -1;
--
--	if (!prioritised)
--		pagesInUse =
--			(aggressive) ? dev->nChunksPerBlock : YAFFS_PASSIVE_GC_CHUNKS + 1;
--
--	if (aggressive)
--		iterations =
--		    dev->internalEndBlock - dev->internalStartBlock + 1;
--	else {
--		iterations =
--		    dev->internalEndBlock - dev->internalStartBlock + 1;
--		iterations = iterations / 16;
--		if (iterations > 200)
--			iterations = 200;
--	}
--
--	for (i = 0; i <= iterations && pagesInUse > 0 && !prioritised; i++) {
--		b++;
--		if (b < dev->internalStartBlock || b > dev->internalEndBlock)
--			b = dev->internalStartBlock;
--
--		if (b < dev->internalStartBlock || b > dev->internalEndBlock) {
--			T(YAFFS_TRACE_ERROR,
--			  (TSTR("**>> Block %d is not valid" TENDSTR), b));
--			YBUG();
--		}
--
--		bi = yaffs_GetBlockInfo(dev, b);
--
--		if (bi->blockState == YAFFS_BLOCK_STATE_FULL &&
--			(bi->pagesInUse - bi->softDeletions) < pagesInUse &&
--				yaffs_BlockNotDisqualifiedFromGC(dev, bi)) {
--			dirtiest = b;
--			pagesInUse = (bi->pagesInUse - bi->softDeletions);
--		}
--	}
--
--	dev->currentDirtyChecker = b;
--
--	if (dirtiest > 0) {
--		T(YAFFS_TRACE_GC,
--		  (TSTR("GC Selected block %d with %d free, prioritised:%d" TENDSTR), dirtiest,
--		   dev->nChunksPerBlock - pagesInUse, prioritised));
--	}
--
--	dev->oldestDirtySequence = 0;
--
--	if (dirtiest > 0)
--		dev->nonAggressiveSkip = 4;
--
--	return dirtiest;
--}
--
--static void yaffs_BlockBecameDirty(yaffs_Device *dev, int blockNo)
--{
--	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, blockNo);
--
--	int erasedOk = 0;
--
--	/* If the block is still healthy erase it and mark as clean.
--	 * If the block has had a data failure, then retire it.
--	 */
--
--	T(YAFFS_TRACE_GC | YAFFS_TRACE_ERASE,
--		(TSTR("yaffs_BlockBecameDirty block %d state %d %s"TENDSTR),
--		blockNo, bi->blockState, (bi->needsRetiring) ? "needs retiring" : ""));
--
--	bi->blockState = YAFFS_BLOCK_STATE_DIRTY;
--
--	if (!bi->needsRetiring) {
--		yaffs_InvalidateCheckpoint(dev);
--		erasedOk = yaffs_EraseBlockInNAND(dev, blockNo);
--		if (!erasedOk) {
--			dev->nErasureFailures++;
--			T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
--			  (TSTR("**>> Erasure failed %d" TENDSTR), blockNo));
--		}
--	}
--
--	if (erasedOk &&
--	    ((yaffs_traceMask & YAFFS_TRACE_ERASE) || !yaffs_SkipVerification(dev))) {
--		int i;
--		for (i = 0; i < dev->nChunksPerBlock; i++) {
--			if (!yaffs_CheckChunkErased
--			    (dev, blockNo * dev->nChunksPerBlock + i)) {
--				T(YAFFS_TRACE_ERROR,
--				  (TSTR
--				   (">>Block %d erasure supposedly OK, but chunk %d not erased"
--				    TENDSTR), blockNo, i));
--			}
--		}
--	}
--
--	if (erasedOk) {
--		/* Clean it up... */
--		bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
--		dev->nErasedBlocks++;
--		bi->pagesInUse = 0;
--		bi->softDeletions = 0;
--		bi->hasShrinkHeader = 0;
--		bi->skipErasedCheck = 1;  /* This is clean, so no need to check */
--		bi->gcPrioritise = 0;
--		yaffs_ClearChunkBits(dev, blockNo);
--
--		T(YAFFS_TRACE_ERASE,
--		  (TSTR("Erased block %d" TENDSTR), blockNo));
--	} else {
--		dev->nFreeChunks -= dev->nChunksPerBlock;	/* We lost a block of free space */
--
--		yaffs_RetireBlock(dev, blockNo);
--		T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
--		  (TSTR("**>> Block %d retired" TENDSTR), blockNo));
--	}
--}
--
--static int yaffs_FindBlockForAllocation(yaffs_Device *dev)
--{
--	int i;
--
--	yaffs_BlockInfo *bi;
--
--	if (dev->nErasedBlocks < 1) {
--		/* Hoosterman we've got a problem.
--		 * Can't get space to gc
--		 */
--		T(YAFFS_TRACE_ERROR,
--		  (TSTR("yaffs tragedy: no more erased blocks" TENDSTR)));
--
--		return -1;
--	}
--
--	/* Find an empty block. */
--
--	for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
--		dev->allocationBlockFinder++;
--		if (dev->allocationBlockFinder < dev->internalStartBlock
--		    || dev->allocationBlockFinder > dev->internalEndBlock) {
--			dev->allocationBlockFinder = dev->internalStartBlock;
--		}
--
--		bi = yaffs_GetBlockInfo(dev, dev->allocationBlockFinder);
--
--		if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY) {
--			bi->blockState = YAFFS_BLOCK_STATE_ALLOCATING;
--			dev->sequenceNumber++;
--			bi->sequenceNumber = dev->sequenceNumber;
--			dev->nErasedBlocks--;
--			T(YAFFS_TRACE_ALLOCATE,
--			  (TSTR("Allocated block %d, seq  %d, %d left" TENDSTR),
--			   dev->allocationBlockFinder, dev->sequenceNumber,
--			   dev->nErasedBlocks));
--			return dev->allocationBlockFinder;
--		}
--	}
--
--	T(YAFFS_TRACE_ALWAYS,
--	  (TSTR
--	   ("yaffs tragedy: no more erased blocks, but there should have been %d"
--	    TENDSTR), dev->nErasedBlocks));
--
--	return -1;
--}
--
--
--
--static int yaffs_CalcCheckpointBlocksRequired(yaffs_Device *dev)
--{
--	if (!dev->nCheckpointBlocksRequired &&
--	   dev->isYaffs2) {
--		/* Not a valid value so recalculate */
--		int nBytes = 0;
--		int nBlocks;
--		int devBlocks = (dev->endBlock - dev->startBlock + 1);
--		int tnodeSize;
--
--		tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
--
--		if (tnodeSize < sizeof(yaffs_Tnode))
--			tnodeSize = sizeof(yaffs_Tnode);
--
--		nBytes += sizeof(yaffs_CheckpointValidity);
--		nBytes += sizeof(yaffs_CheckpointDevice);
--		nBytes += devBlocks * sizeof(yaffs_BlockInfo);
--		nBytes += devBlocks * dev->chunkBitmapStride;
--		nBytes += (sizeof(yaffs_CheckpointObject) + sizeof(__u32)) * (dev->nObjectsCreated - dev->nFreeObjects);
--		nBytes += (tnodeSize + sizeof(__u32)) * (dev->nTnodesCreated - dev->nFreeTnodes);
--		nBytes += sizeof(yaffs_CheckpointValidity);
--		nBytes += sizeof(__u32); /* checksum*/
--
--		/* Round up and add 2 blocks to allow for some bad blocks, so add 3 */
--
--		nBlocks = (nBytes/(dev->nDataBytesPerChunk * dev->nChunksPerBlock)) + 3;
--
--		dev->nCheckpointBlocksRequired = nBlocks;
--	}
--
--	return dev->nCheckpointBlocksRequired;
--}
--
--/*
-- * Check if there's space to allocate...
-- * Thinks.... do we need top make this ths same as yaffs_GetFreeChunks()?
-- */
--static int yaffs_CheckSpaceForAllocation(yaffs_Device *dev)
--{
--	int reservedChunks;
--	int reservedBlocks = dev->nReservedBlocks;
--	int checkpointBlocks;
--
--	if (dev->isYaffs2) {
--		checkpointBlocks =  yaffs_CalcCheckpointBlocksRequired(dev) -
--				    dev->blocksInCheckpoint;
--		if (checkpointBlocks < 0)
--			checkpointBlocks = 0;
--	} else {
--		checkpointBlocks = 0;
--	}
--
--	reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->nChunksPerBlock);
--
--	return (dev->nFreeChunks > reservedChunks);
--}
--
--static int yaffs_AllocateChunk(yaffs_Device *dev, int useReserve,
--		yaffs_BlockInfo **blockUsedPtr)
--{
--	int retVal;
--	yaffs_BlockInfo *bi;
--
--	if (dev->allocationBlock < 0) {
--		/* Get next block to allocate off */
--		dev->allocationBlock = yaffs_FindBlockForAllocation(dev);
--		dev->allocationPage = 0;
--	}
--
--	if (!useReserve && !yaffs_CheckSpaceForAllocation(dev)) {
--		/* Not enough space to allocate unless we're allowed to use the reserve. */
--		return -1;
--	}
--
--	if (dev->nErasedBlocks < dev->nReservedBlocks
--			&& dev->allocationPage == 0) {
--		T(YAFFS_TRACE_ALLOCATE, (TSTR("Allocating reserve" TENDSTR)));
--	}
--
--	/* Next page please.... */
--	if (dev->allocationBlock >= 0) {
--		bi = yaffs_GetBlockInfo(dev, dev->allocationBlock);
--
--		retVal = (dev->allocationBlock * dev->nChunksPerBlock) +
--			dev->allocationPage;
--		bi->pagesInUse++;
--		yaffs_SetChunkBit(dev, dev->allocationBlock,
--				dev->allocationPage);
--
--		dev->allocationPage++;
--
--		dev->nFreeChunks--;
--
--		/* If the block is full set the state to full */
--		if (dev->allocationPage >= dev->nChunksPerBlock) {
--			bi->blockState = YAFFS_BLOCK_STATE_FULL;
--			dev->allocationBlock = -1;
--		}
--
--		if (blockUsedPtr)
--			*blockUsedPtr = bi;
--
--		return retVal;
--	}
--
--	T(YAFFS_TRACE_ERROR,
--			(TSTR("!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!" TENDSTR)));
--
--	return -1;
--}
--
--static int yaffs_GetErasedChunks(yaffs_Device *dev)
--{
--	int n;
--
--	n = dev->nErasedBlocks * dev->nChunksPerBlock;
--
--	if (dev->allocationBlock > 0)
--		n += (dev->nChunksPerBlock - dev->allocationPage);
--
--	return n;
--
--}
--
--static int yaffs_GarbageCollectBlock(yaffs_Device *dev, int block,
--		int wholeBlock)
--{
--	int oldChunk;
--	int newChunk;
--	int markNAND;
--	int retVal = YAFFS_OK;
--	int cleanups = 0;
--	int i;
--	int isCheckpointBlock;
--	int matchingChunk;
--	int maxCopies;
--
--	int chunksBefore = yaffs_GetErasedChunks(dev);
--	int chunksAfter;
--
--	yaffs_ExtendedTags tags;
--
--	yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, block);
--
--	yaffs_Object *object;
--
--	isCheckpointBlock = (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT);
--
--	bi->blockState = YAFFS_BLOCK_STATE_COLLECTING;
--
--	T(YAFFS_TRACE_TRACING,
--			(TSTR("Collecting block %d, in use %d, shrink %d, wholeBlock %d" TENDSTR),
--			 block,
--			 bi->pagesInUse,
--			 bi->hasShrinkHeader,
--			 wholeBlock));
--
--	/*yaffs_VerifyFreeChunks(dev); */
--
--	bi->hasShrinkHeader = 0;	/* clear the flag so that the block can erase */
--
--	/* Take off the number of soft deleted entries because
--	 * they're going to get really deleted during GC.
--	 */
--	dev->nFreeChunks -= bi->softDeletions;
--
--	dev->isDoingGC = 1;
--
--	if (isCheckpointBlock ||
--			!yaffs_StillSomeChunkBits(dev, block)) {
--		T(YAFFS_TRACE_TRACING,
--				(TSTR
--				 ("Collecting block %d that has no chunks in use" TENDSTR),
--				 block));
--		yaffs_BlockBecameDirty(dev, block);
--	} else {
--
--		__u8 *buffer = yaffs_GetTempBuffer(dev, __LINE__);
--
--		yaffs_VerifyBlock(dev, bi, block);
--
--		maxCopies = (wholeBlock) ? dev->nChunksPerBlock : 10;
--		oldChunk = block * dev->nChunksPerBlock + dev->gcChunk;
--
--		for (/* init already done */;
--		     retVal == YAFFS_OK &&
--		     dev->gcChunk < dev->nChunksPerBlock &&
--		     (bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) &&
--		     maxCopies > 0;
--		     dev->gcChunk++, oldChunk++) {
--			if (yaffs_CheckChunkBit(dev, block, dev->gcChunk)) {
--
--				/* This page is in use and might need to be copied off */
--
--				maxCopies--;
--
--				markNAND = 1;
--
--				yaffs_InitialiseTags(&tags);
--
--				yaffs_ReadChunkWithTagsFromNAND(dev, oldChunk,
--								buffer, &tags);
--
--				object =
--				    yaffs_FindObjectByNumber(dev,
--							     tags.objectId);
--
--				T(YAFFS_TRACE_GC_DETAIL,
--				  (TSTR
--				   ("Collecting chunk in block %d, %d %d %d " TENDSTR),
--				   dev->gcChunk, tags.objectId, tags.chunkId,
--				   tags.byteCount));
--
--				if (object && !yaffs_SkipVerification(dev)) {
--					if (tags.chunkId == 0)
--						matchingChunk = object->hdrChunk;
--					else if (object->softDeleted)
--						matchingChunk = oldChunk; /* Defeat the test */
--					else
--						matchingChunk = yaffs_FindChunkInFile(object, tags.chunkId, NULL);
--
--					if (oldChunk != matchingChunk)
--						T(YAFFS_TRACE_ERROR,
--						  (TSTR("gc: page in gc mismatch: %d %d %d %d"TENDSTR),
--						  oldChunk, matchingChunk, tags.objectId, tags.chunkId));
--
--				}
--
--				if (!object) {
--					T(YAFFS_TRACE_ERROR,
--					  (TSTR
--					   ("page %d in gc has no object: %d %d %d "
--					    TENDSTR), oldChunk,
--					    tags.objectId, tags.chunkId, tags.byteCount));
--				}
--
--				if (object &&
--				    object->deleted &&
--				    object->softDeleted &&
--				    tags.chunkId != 0) {
--					/* Data chunk in a soft deleted file, throw it away
--					 * It's a soft deleted data chunk,
--					 * No need to copy this, just forget about it and
--					 * fix up the object.
--					 */
--
--					object->nDataChunks--;
--
--					if (object->nDataChunks <= 0) {
--						/* remeber to clean up the object */
--						dev->gcCleanupList[cleanups] =
--						    tags.objectId;
--						cleanups++;
--					}
--					markNAND = 0;
--				} else if (0) {
--					/* Todo object && object->deleted && object->nDataChunks == 0 */
--					/* Deleted object header with no data chunks.
--					 * Can be discarded and the file deleted.
--					 */
--					object->hdrChunk = 0;
--					yaffs_FreeTnode(object->myDev,
--							object->variant.
--							fileVariant.top);
--					object->variant.fileVariant.top = NULL;
--					yaffs_DoGenericObjectDeletion(object);
--
--				} else if (object) {
--					/* It's either a data chunk in a live file or
--					 * an ObjectHeader, so we're interested in it.
--					 * NB Need to keep the ObjectHeaders of deleted files
--					 * until the whole file has been deleted off
--					 */
--					tags.serialNumber++;
--
--					dev->nGCCopies++;
--
--					if (tags.chunkId == 0) {
--						/* It is an object Id,
--						 * We need to nuke the shrinkheader flags first
--						 * We no longer want the shrinkHeader flag since its work is done
--						 * and if it is left in place it will mess up scanning.
--						 */
--
--						yaffs_ObjectHeader *oh;
--						oh = (yaffs_ObjectHeader *)buffer;
--						oh->isShrink = 0;
--						tags.extraIsShrinkHeader = 0;
--
--						yaffs_VerifyObjectHeader(object, oh, &tags, 1);
--					}
--
--					newChunk =
--					    yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &tags, 1);
--
--					if (newChunk < 0) {
--						retVal = YAFFS_FAIL;
--					} else {
--
--						/* Ok, now fix up the Tnodes etc. */
--
--						if (tags.chunkId == 0) {
--							/* It's a header */
--							object->hdrChunk =  newChunk;
--							object->serial =   tags.serialNumber;
--						} else {
--							/* It's a data chunk */
--							yaffs_PutChunkIntoFile
--							    (object,
--							     tags.chunkId,
--							     newChunk, 0);
--						}
--					}
--				}
--
--				if (retVal == YAFFS_OK)
--					yaffs_DeleteChunk(dev, oldChunk, markNAND, __LINE__);
--
--			}
--		}
--
--		yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
--
--
--		/* Do any required cleanups */
--		for (i = 0; i < cleanups; i++) {
--			/* Time to delete the file too */
--			object =
--			    yaffs_FindObjectByNumber(dev,
--						     dev->gcCleanupList[i]);
--			if (object) {
--				yaffs_FreeTnode(dev,
--						object->variant.fileVariant.
--						top);
--				object->variant.fileVariant.top = NULL;
--				T(YAFFS_TRACE_GC,
--				  (TSTR
--				   ("yaffs: About to finally delete object %d"
--				    TENDSTR), object->objectId));
--				yaffs_DoGenericObjectDeletion(object);
--				object->myDev->nDeletedFiles--;
--			}
--
--		}
--
--	}
--
--	yaffs_VerifyCollectedBlock(dev, bi, block);
--
--	chunksAfter = yaffs_GetErasedChunks(dev);
--	if (chunksBefore >= chunksAfter) {
--		T(YAFFS_TRACE_GC,
--		  (TSTR
--		   ("gc did not increase free chunks before %d after %d"
--		    TENDSTR), chunksBefore, chunksAfter));
--	}
--
--	/* If the gc completed then clear the current gcBlock so that we find another. */
--	if (bi->blockState != YAFFS_BLOCK_STATE_COLLECTING) {
--		dev->gcBlock = -1;
--		dev->gcChunk = 0;
--	}
--
--	dev->isDoingGC = 0;
--
--	return retVal;
--}
--
--/* New garbage collector
-- * If we're very low on erased blocks then we do aggressive garbage collection
-- * otherwise we do "leasurely" garbage collection.
-- * Aggressive gc looks further (whole array) and will accept less dirty blocks.
-- * Passive gc only inspects smaller areas and will only accept more dirty blocks.
-- *
-- * The idea is to help clear out space in a more spread-out manner.
-- * Dunno if it really does anything useful.
-- */
--static int yaffs_CheckGarbageCollection(yaffs_Device *dev)
--{
--	int block;
--	int aggressive;
--	int gcOk = YAFFS_OK;
--	int maxTries = 0;
--
--	int checkpointBlockAdjust;
--
--	if (dev->isDoingGC) {
--		/* Bail out so we don't get recursive gc */
--		return YAFFS_OK;
--	}
--
--	/* This loop should pass the first time.
--	 * We'll only see looping here if the erase of the collected block fails.
--	 */
--
--	do {
--		maxTries++;
--
--		checkpointBlockAdjust = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
--		if (checkpointBlockAdjust < 0)
--			checkpointBlockAdjust = 0;
--
--		if (dev->nErasedBlocks < (dev->nReservedBlocks + checkpointBlockAdjust + 2)) {
--			/* We need a block soon...*/
--			aggressive = 1;
--		} else {
--			/* We're in no hurry */
--			aggressive = 0;
--		}
--
--		if (dev->gcBlock <= 0) {
--			dev->gcBlock = yaffs_FindBlockForGarbageCollection(dev, aggressive);
--			dev->gcChunk = 0;
--		}
--
--		block = dev->gcBlock;
--
--		if (block > 0) {
--			dev->garbageCollections++;
--			if (!aggressive)
--				dev->passiveGarbageCollections++;
--
--			T(YAFFS_TRACE_GC,
--			  (TSTR
--			   ("yaffs: GC erasedBlocks %d aggressive %d" TENDSTR),
--			   dev->nErasedBlocks, aggressive));
--
--			gcOk = yaffs_GarbageCollectBlock(dev, block, aggressive);
--		}
--
--		if (dev->nErasedBlocks < (dev->nReservedBlocks) && block > 0) {
--			T(YAFFS_TRACE_GC,
--			  (TSTR
--			   ("yaffs: GC !!!no reclaim!!! erasedBlocks %d after try %d block %d"
--			    TENDSTR), dev->nErasedBlocks, maxTries, block));
--		}
--	} while ((dev->nErasedBlocks < dev->nReservedBlocks) &&
--		 (block > 0) &&
--		 (maxTries < 2));
--
--	return aggressive ? gcOk : YAFFS_OK;
--}
--
--/*-------------------------  TAGS --------------------------------*/
--
--static int yaffs_TagsMatch(const yaffs_ExtendedTags *tags, int objectId,
--			   int chunkInObject)
--{
--	return (tags->chunkId == chunkInObject &&
--		tags->objectId == objectId && !tags->chunkDeleted) ? 1 : 0;
--
--}
--
--
--/*-------------------- Data file manipulation -----------------*/
--
--static int yaffs_FindChunkInFile(yaffs_Object *in, int chunkInInode,
--				 yaffs_ExtendedTags *tags)
--{
--	/*Get the Tnode, then get the level 0 offset chunk offset */
--	yaffs_Tnode *tn;
--	int theChunk = -1;
--	yaffs_ExtendedTags localTags;
--	int retVal = -1;
--
--	yaffs_Device *dev = in->myDev;
--
--	if (!tags) {
--		/* Passed a NULL, so use our own tags space */
--		tags = &localTags;
--	}
--
--	tn = yaffs_FindLevel0Tnode(dev, &in->variant.fileVariant, chunkInInode);
--
--	if (tn) {
--		theChunk = yaffs_GetChunkGroupBase(dev, tn, chunkInInode);
--
--		retVal =
--		    yaffs_FindChunkInGroup(dev, theChunk, tags, in->objectId,
--					   chunkInInode);
--	}
--	return retVal;
--}
--
--static int yaffs_FindAndDeleteChunkInFile(yaffs_Object *in, int chunkInInode,
--					  yaffs_ExtendedTags *tags)
--{
--	/* Get the Tnode, then get the level 0 offset chunk offset */
--	yaffs_Tnode *tn;
--	int theChunk = -1;
--	yaffs_ExtendedTags localTags;
--
--	yaffs_Device *dev = in->myDev;
--	int retVal = -1;
--
--	if (!tags) {
--		/* Passed a NULL, so use our own tags space */
--		tags = &localTags;
--	}
--
--	tn = yaffs_FindLevel0Tnode(dev, &in->variant.fileVariant, chunkInInode);
--
--	if (tn) {
--
--		theChunk = yaffs_GetChunkGroupBase(dev, tn, chunkInInode);
--
--		retVal =
--		    yaffs_FindChunkInGroup(dev, theChunk, tags, in->objectId,
--					   chunkInInode);
--
--		/* Delete the entry in the filestructure (if found) */
--		if (retVal != -1)
--			yaffs_PutLevel0Tnode(dev, tn, chunkInInode, 0);
--	}
--
--	return retVal;
--}
--
--#ifdef YAFFS_PARANOID
--
--static int yaffs_CheckFileSanity(yaffs_Object *in)
--{
--	int chunk;
--	int nChunks;
--	int fSize;
--	int failed = 0;
--	int objId;
--	yaffs_Tnode *tn;
--	yaffs_Tags localTags;
--	yaffs_Tags *tags = &localTags;
--	int theChunk;
--	int chunkDeleted;
--
--	if (in->variantType != YAFFS_OBJECT_TYPE_FILE)
--		return YAFFS_FAIL;
--
--	objId = in->objectId;
--	fSize = in->variant.fileVariant.fileSize;
--	nChunks =
--	    (fSize + in->myDev->nDataBytesPerChunk - 1) / in->myDev->nDataBytesPerChunk;
--
--	for (chunk = 1; chunk <= nChunks; chunk++) {
--		tn = yaffs_FindLevel0Tnode(in->myDev, &in->variant.fileVariant,
--					   chunk);
--
--		if (tn) {
--
--			theChunk = yaffs_GetChunkGroupBase(dev, tn, chunk);
--
--			if (yaffs_CheckChunkBits
--			    (dev, theChunk / dev->nChunksPerBlock,
--			     theChunk % dev->nChunksPerBlock)) {
--
--				yaffs_ReadChunkTagsFromNAND(in->myDev, theChunk,
--							    tags,
--							    &chunkDeleted);
--				if (yaffs_TagsMatch
--				    (tags, in->objectId, chunk, chunkDeleted)) {
--					/* found it; */
--
--				}
--			} else {
--
--				failed = 1;
--			}
--
--		} else {
--			/* T(("No level 0 found for %d\n", chunk)); */
--		}
--	}
--
--	return failed ? YAFFS_FAIL : YAFFS_OK;
--}
--
--#endif
--
--static int yaffs_PutChunkIntoFile(yaffs_Object *in, int chunkInInode,
--				  int chunkInNAND, int inScan)
--{
--	/* NB inScan is zero unless scanning.
--	 * For forward scanning, inScan is > 0;
--	 * for backward scanning inScan is < 0
--	 */
--
--	yaffs_Tnode *tn;
--	yaffs_Device *dev = in->myDev;
--	int existingChunk;
--	yaffs_ExtendedTags existingTags;
--	yaffs_ExtendedTags newTags;
--	unsigned existingSerial, newSerial;
--
--	if (in->variantType != YAFFS_OBJECT_TYPE_FILE) {
--		/* Just ignore an attempt at putting a chunk into a non-file during scanning
--		 * If it is not during Scanning then something went wrong!
--		 */
--		if (!inScan) {
--			T(YAFFS_TRACE_ERROR,
--			  (TSTR
--			   ("yaffs tragedy:attempt to put data chunk into a non-file"
--			    TENDSTR)));
--			YBUG();
--		}
--
--		yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
--		return YAFFS_OK;
--	}
--
--	tn = yaffs_AddOrFindLevel0Tnode(dev,
--					&in->variant.fileVariant,
--					chunkInInode,
--					NULL);
--	if (!tn)
--		return YAFFS_FAIL;
--
--	existingChunk = yaffs_GetChunkGroupBase(dev, tn, chunkInInode);
--
--	if (inScan != 0) {
--		/* If we're scanning then we need to test for duplicates
--		 * NB This does not need to be efficient since it should only ever
--		 * happen when the power fails during a write, then only one
--		 * chunk should ever be affected.
--		 *
--		 * Correction for YAFFS2: This could happen quite a lot and we need to think about efficiency! TODO
--		 * Update: For backward scanning we don't need to re-read tags so this is quite cheap.
--		 */
--
--		if (existingChunk > 0) {
--			/* NB Right now existing chunk will not be real chunkId if the device >= 32MB
--			 *    thus we have to do a FindChunkInFile to get the real chunk id.
--			 *
--			 * We have a duplicate now we need to decide which one to use:
--			 *
--			 * Backwards scanning YAFFS2: The old one is what we use, dump the new one.
--			 * Forward scanning YAFFS2: The new one is what we use, dump the old one.
--			 * YAFFS1: Get both sets of tags and compare serial numbers.
--			 */
--
--			if (inScan > 0) {
--				/* Only do this for forward scanning */
--				yaffs_ReadChunkWithTagsFromNAND(dev,
--								chunkInNAND,
--								NULL, &newTags);
--
--				/* Do a proper find */
--				existingChunk =
--				    yaffs_FindChunkInFile(in, chunkInInode,
--							  &existingTags);
--			}
--
--			if (existingChunk <= 0) {
--				/*Hoosterman - how did this happen? */
--
--				T(YAFFS_TRACE_ERROR,
--				  (TSTR
--				   ("yaffs tragedy: existing chunk < 0 in scan"
--				    TENDSTR)));
--
--			}
--
--			/* NB The deleted flags should be false, otherwise the chunks will
--			 * not be loaded during a scan
--			 */
--
--			if (inScan > 0) {
--				newSerial = newTags.serialNumber;
--				existingSerial = existingTags.serialNumber;
--			}
--
--			if ((inScan > 0) &&
--			    (in->myDev->isYaffs2 ||
--			     existingChunk <= 0 ||
--			     ((existingSerial + 1) & 3) == newSerial)) {
--				/* Forward scanning.
--				 * Use new
--				 * Delete the old one and drop through to update the tnode
--				 */
--				yaffs_DeleteChunk(dev, existingChunk, 1,
--						  __LINE__);
--			} else {
--				/* Backward scanning or we want to use the existing one
--				 * Use existing.
--				 * Delete the new one and return early so that the tnode isn't changed
--				 */
--				yaffs_DeleteChunk(dev, chunkInNAND, 1,
--						  __LINE__);
--				return YAFFS_OK;
--			}
--		}
--
--	}
--
--	if (existingChunk == 0)
--		in->nDataChunks++;
--
--	yaffs_PutLevel0Tnode(dev, tn, chunkInInode, chunkInNAND);
--
--	return YAFFS_OK;
--}
--
--static int yaffs_ReadChunkDataFromObject(yaffs_Object *in, int chunkInInode,
--					__u8 *buffer)
--{
--	int chunkInNAND = yaffs_FindChunkInFile(in, chunkInInode, NULL);
--
--	if (chunkInNAND >= 0)
--		return yaffs_ReadChunkWithTagsFromNAND(in->myDev, chunkInNAND,
--						buffer, NULL);
--	else {
--		T(YAFFS_TRACE_NANDACCESS,
--		  (TSTR("Chunk %d not found zero instead" TENDSTR),
--		   chunkInNAND));
--		/* get sane (zero) data if you read a hole */
--		memset(buffer, 0, in->myDev->nDataBytesPerChunk);
--		return 0;
--	}
--
--}
--
--void yaffs_DeleteChunk(yaffs_Device *dev, int chunkId, int markNAND, int lyn)
--{
--	int block;
--	int page;
--	yaffs_ExtendedTags tags;
--	yaffs_BlockInfo *bi;
--
--	if (chunkId <= 0)
--		return;
--
--	dev->nDeletions++;
--	block = chunkId / dev->nChunksPerBlock;
--	page = chunkId % dev->nChunksPerBlock;
--
--
--	if (!yaffs_CheckChunkBit(dev, block, page))
--		T(YAFFS_TRACE_VERIFY,
--			(TSTR("Deleting invalid chunk %d"TENDSTR),
--			 chunkId));
--
--	bi = yaffs_GetBlockInfo(dev, block);
--
--	T(YAFFS_TRACE_DELETION,
--	  (TSTR("line %d delete of chunk %d" TENDSTR), lyn, chunkId));
--
--	if (markNAND &&
--	    bi->blockState != YAFFS_BLOCK_STATE_COLLECTING && !dev->isYaffs2) {
--
--		yaffs_InitialiseTags(&tags);
--
--		tags.chunkDeleted = 1;
--
--		yaffs_WriteChunkWithTagsToNAND(dev, chunkId, NULL, &tags);
--		yaffs_HandleUpdateChunk(dev, chunkId, &tags);
--	} else {
--		dev->nUnmarkedDeletions++;
--	}
--
--	/* Pull out of the management area.
--	 * If the whole block became dirty, this will kick off an erasure.
--	 */
--	if (bi->blockState == YAFFS_BLOCK_STATE_ALLOCATING ||
--	    bi->blockState == YAFFS_BLOCK_STATE_FULL ||
--	    bi->blockState == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
--	    bi->blockState == YAFFS_BLOCK_STATE_COLLECTING) {
--		dev->nFreeChunks++;
--
--		yaffs_ClearChunkBit(dev, block, page);
--
--		bi->pagesInUse--;
--
--		if (bi->pagesInUse == 0 &&
--		    !bi->hasShrinkHeader &&
--		    bi->blockState != YAFFS_BLOCK_STATE_ALLOCATING &&
--		    bi->blockState != YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
--			yaffs_BlockBecameDirty(dev, block);
--		}
--
--	}
--
--}
--
--static int yaffs_WriteChunkDataToObject(yaffs_Object *in, int chunkInInode,
--					const __u8 *buffer, int nBytes,
--					int useReserve)
--{
--	/* Find old chunk Need to do this to get serial number
--	 * Write new one and patch into tree.
--	 * Invalidate old tags.
--	 */
--
--	int prevChunkId;
--	yaffs_ExtendedTags prevTags;
--
--	int newChunkId;
--	yaffs_ExtendedTags newTags;
--
--	yaffs_Device *dev = in->myDev;
--
--	yaffs_CheckGarbageCollection(dev);
--
--	/* Get the previous chunk at this location in the file if it exists */
--	prevChunkId = yaffs_FindChunkInFile(in, chunkInInode, &prevTags);
--
--	/* Set up new tags */
--	yaffs_InitialiseTags(&newTags);
--
--	newTags.chunkId = chunkInInode;
--	newTags.objectId = in->objectId;
--	newTags.serialNumber =
--	    (prevChunkId >= 0) ? prevTags.serialNumber + 1 : 1;
--	newTags.byteCount = nBytes;
--
--	if (nBytes < 1 || nBytes > dev->totalBytesPerChunk) {
--		T(YAFFS_TRACE_ERROR,
--		(TSTR("Writing %d bytes to chunk!!!!!!!!!" TENDSTR), nBytes));
--		YBUG();
--	}
--
--	newChunkId =
--	    yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags,
--					      useReserve);
--
--	if (newChunkId >= 0) {
--		yaffs_PutChunkIntoFile(in, chunkInInode, newChunkId, 0);
--
--		if (prevChunkId >= 0)
--			yaffs_DeleteChunk(dev, prevChunkId, 1, __LINE__);
--
--		yaffs_CheckFileSanity(in);
--	}
--	return newChunkId;
--
--}
--
--/* UpdateObjectHeader updates the header on NAND for an object.
-- * If name is not NULL, then that new name is used.
-- */
--int yaffs_UpdateObjectHeader(yaffs_Object *in, const YCHAR *name, int force,
--			     int isShrink, int shadows)
--{
--
--	yaffs_BlockInfo *bi;
--
--	yaffs_Device *dev = in->myDev;
--
--	int prevChunkId;
--	int retVal = 0;
--	int result = 0;
--
--	int newChunkId;
--	yaffs_ExtendedTags newTags;
--	yaffs_ExtendedTags oldTags;
--
--	__u8 *buffer = NULL;
--	YCHAR oldName[YAFFS_MAX_NAME_LENGTH + 1];
--
--	yaffs_ObjectHeader *oh = NULL;
-+	yaffs_obj_t *in;
-+	YCHAR *str = NULL;
- 
--	yaffs_strcpy(oldName, _Y("silly old name"));
-+	yaffs_dev_t *dev = parent->my_dev;
- 
-+	/* Check if the entry exists. If it does then fail the call since we don't want a dup.*/
-+	if (yaffs_find_by_name(parent, name))
-+		return NULL;
- 
--	if (!in->fake ||
--		in == dev->rootDir || /* The rootDir should also be saved */
--		force) {
-+	if (type == YAFFS_OBJECT_TYPE_SYMLINK) {
-+		str = yaffs_clone_str(aliasString);
-+		if (!str)
-+			return NULL;
-+	}
- 
--		yaffs_CheckGarbageCollection(dev);
--		yaffs_CheckObjectDetailsLoaded(in);
-+	in = yaffs_new_obj(dev, -1, type);
- 
--		buffer = yaffs_GetTempBuffer(in->myDev, __LINE__);
--		oh = (yaffs_ObjectHeader *) buffer;
-+	if (!in){
-+		if(str)
-+			YFREE(str);
-+		return NULL;
-+	}
- 
--		prevChunkId = in->hdrChunk;
- 
--		if (prevChunkId > 0) {
--			result = yaffs_ReadChunkWithTagsFromNAND(dev, prevChunkId,
--							buffer, &oldTags);
- 
--			yaffs_VerifyObjectHeader(in, oh, &oldTags, 0);
- 
--			memcpy(oldName, oh->name, sizeof(oh->name));
--		}
- 
--		memset(buffer, 0xFF, dev->nDataBytesPerChunk);
-+	if (in) {
-+		in->hdr_chunk = 0;
-+		in->valid = 1;
-+		in->variant_type = type;
- 
--		oh->type = in->variantType;
--		oh->yst_mode = in->yst_mode;
--		oh->shadowsObject = oh->inbandShadowsObject = shadows;
-+		in->yst_mode = mode;
- 
- #ifdef CONFIG_YAFFS_WINCE
--		oh->win_atime[0] = in->win_atime[0];
--		oh->win_ctime[0] = in->win_ctime[0];
--		oh->win_mtime[0] = in->win_mtime[0];
--		oh->win_atime[1] = in->win_atime[1];
--		oh->win_ctime[1] = in->win_ctime[1];
--		oh->win_mtime[1] = in->win_mtime[1];
-+		yfsd_win_file_time_now(in->win_atime);
-+		in->win_ctime[0] = in->win_mtime[0] = in->win_atime[0];
-+		in->win_ctime[1] = in->win_mtime[1] = in->win_atime[1];
-+
- #else
--		oh->yst_uid = in->yst_uid;
--		oh->yst_gid = in->yst_gid;
--		oh->yst_atime = in->yst_atime;
--		oh->yst_mtime = in->yst_mtime;
--		oh->yst_ctime = in->yst_ctime;
--		oh->yst_rdev = in->yst_rdev;
-+		in->yst_atime = in->yst_mtime = in->yst_ctime = Y_CURRENT_TIME;
-+
-+		in->yst_rdev = rdev;
-+		in->yst_uid = uid;
-+		in->yst_gid = gid;
- #endif
--		if (in->parent)
--			oh->parentObjectId = in->parent->objectId;
--		else
--			oh->parentObjectId = 0;
-+		in->n_data_chunks = 0;
- 
--		if (name && *name) {
--			memset(oh->name, 0, sizeof(oh->name));
--			yaffs_strncpy(oh->name, name, YAFFS_MAX_NAME_LENGTH);
--		} else if (prevChunkId >= 0)
--			memcpy(oh->name, oldName, sizeof(oh->name));
--		else
--			memset(oh->name, 0, sizeof(oh->name));
-+		yaffs_set_obj_name(in, name);
-+		in->dirty = 1;
- 
--		oh->isShrink = isShrink;
-+		yaffs_add_obj_to_dir(parent, in);
- 
--		switch (in->variantType) {
--		case YAFFS_OBJECT_TYPE_UNKNOWN:
--			/* Should not happen */
--			break;
--		case YAFFS_OBJECT_TYPE_FILE:
--			oh->fileSize =
--			    (oh->parentObjectId == YAFFS_OBJECTID_DELETED
--			     || oh->parentObjectId ==
--			     YAFFS_OBJECTID_UNLINKED) ? 0 : in->variant.
--			    fileVariant.fileSize;
-+		in->my_dev = parent->my_dev;
-+
-+		switch (type) {
-+		case YAFFS_OBJECT_TYPE_SYMLINK:
-+			in->variant.symlink_variant.alias = str;
- 			break;
- 		case YAFFS_OBJECT_TYPE_HARDLINK:
--			oh->equivalentObjectId =
--			    in->variant.hardLinkVariant.equivalentObjectId;
--			break;
--		case YAFFS_OBJECT_TYPE_SPECIAL:
--			/* Do nothing */
-+			in->variant.hardlink_variant.equiv_obj =
-+				equiv_obj;
-+			in->variant.hardlink_variant.equiv_id =
-+				equiv_obj->obj_id;
-+			ylist_add(&in->hard_links, &equiv_obj->hard_links);
- 			break;
-+		case YAFFS_OBJECT_TYPE_FILE:
- 		case YAFFS_OBJECT_TYPE_DIRECTORY:
--			/* Do nothing */
--			break;
--		case YAFFS_OBJECT_TYPE_SYMLINK:
--			yaffs_strncpy(oh->alias,
--				      in->variant.symLinkVariant.alias,
--				      YAFFS_MAX_ALIAS_LENGTH);
--			oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0;
-+		case YAFFS_OBJECT_TYPE_SPECIAL:
-+		case YAFFS_OBJECT_TYPE_UNKNOWN:
-+			/* do nothing */
- 			break;
- 		}
- 
--		/* Tags */
--		yaffs_InitialiseTags(&newTags);
--		in->serial++;
--		newTags.chunkId = 0;
--		newTags.objectId = in->objectId;
--		newTags.serialNumber = in->serial;
--
--		/* Add extra info for file header */
--
--		newTags.extraHeaderInfoAvailable = 1;
--		newTags.extraParentObjectId = oh->parentObjectId;
--		newTags.extraFileLength = oh->fileSize;
--		newTags.extraIsShrinkHeader = oh->isShrink;
--		newTags.extraEquivalentObjectId = oh->equivalentObjectId;
--		newTags.extraShadows = (oh->shadowsObject > 0) ? 1 : 0;
--		newTags.extraObjectType = in->variantType;
--
--		yaffs_VerifyObjectHeader(in, oh, &newTags, 1);
--
--		/* Create new chunk in NAND */
--		newChunkId =
--		    yaffs_WriteNewChunkWithTagsToNAND(dev, buffer, &newTags,
--						      (prevChunkId >= 0) ? 1 : 0);
--
--		if (newChunkId >= 0) {
--
--			in->hdrChunk = newChunkId;
--
--			if (prevChunkId >= 0) {
--				yaffs_DeleteChunk(dev, prevChunkId, 1,
--						  __LINE__);
--			}
--
--			if (!yaffs_ObjectHasCachedWriteData(in))
--				in->dirty = 0;
--
--			/* If this was a shrink, then mark the block that the chunk lives on */
--			if (isShrink) {
--				bi = yaffs_GetBlockInfo(in->myDev,
--					newChunkId / in->myDev->nChunksPerBlock);
--				bi->hasShrinkHeader = 1;
--			}
--
-+		if (yaffs_update_oh(in, name, 0, 0, 0, NULL) < 0) {
-+			/* Could not create the object header, fail the creation */
-+			yaffs_del_obj(in);
-+			in = NULL;
- 		}
- 
--		retVal = newChunkId;
--
-+		yaffs_update_parent(parent);
- 	}
- 
--	if (buffer)
--		yaffs_ReleaseTempBuffer(dev, buffer, __LINE__);
--
--	return retVal;
-+	return in;
- }
- 
--/*------------------------ Short Operations Cache ----------------------------------------
-- *   In many situations where there is no high level buffering (eg WinCE) a lot of
-- *   reads might be short sequential reads, and a lot of writes may be short
-- *   sequential writes. eg. scanning/writing a jpeg file.
-- *   In these cases, a short read/write cache can provide a huge perfomance benefit
-- *   with dumb-as-a-rock code.
-- *   In Linux, the page cache provides read buffering aand the short op cache provides write
-- *   buffering.
-- *
-- *   There are a limited number (~10) of cache chunks per device so that we don't
-- *   need a very intelligent search.
-- */
--
--static int yaffs_ObjectHasCachedWriteData(yaffs_Object *obj)
-+yaffs_obj_t *yaffs_create_file(yaffs_obj_t *parent, const YCHAR *name,
-+			__u32 mode, __u32 uid, __u32 gid)
- {
--	yaffs_Device *dev = obj->myDev;
--	int i;
--	yaffs_ChunkCache *cache;
--	int nCaches = obj->myDev->nShortOpCaches;
--
--	for (i = 0; i < nCaches; i++) {
--		cache = &dev->srCache[i];
--		if (cache->object == obj &&
--		    cache->dirty)
--			return 1;
--	}
-+	return yaffs_create_obj(YAFFS_OBJECT_TYPE_FILE, parent, name, mode,
-+				uid, gid, NULL, NULL, 0);
-+}
- 
--	return 0;
-+yaffs_obj_t *yaffs_create_dir(yaffs_obj_t *parent, const YCHAR *name,
-+				__u32 mode, __u32 uid, __u32 gid)
-+{
-+	return yaffs_create_obj(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name,
-+				 mode, uid, gid, NULL, NULL, 0);
- }
- 
-+yaffs_obj_t *yaffs_create_special(yaffs_obj_t *parent, const YCHAR *name,
-+				__u32 mode, __u32 uid, __u32 gid, __u32 rdev)
-+{
-+	return yaffs_create_obj(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode,
-+				 uid, gid, NULL, NULL, rdev);
-+}
- 
--static void yaffs_FlushFilesChunkCache(yaffs_Object *obj)
-+yaffs_obj_t *yaffs_create_symlink(yaffs_obj_t *parent, const YCHAR *name,
-+				__u32 mode, __u32 uid, __u32 gid,
-+				const YCHAR *alias)
- {
--	yaffs_Device *dev = obj->myDev;
--	int lowest = -99;	/* Stop compiler whining. */
--	int i;
--	yaffs_ChunkCache *cache;
--	int chunkWritten = 0;
--	int nCaches = obj->myDev->nShortOpCaches;
-+	return yaffs_create_obj(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode,
-+				uid, gid, NULL, alias, 0);
-+}
- 
--	if (nCaches > 0) {
--		do {
--			cache = NULL;
-+/* yaffs_link_obj returns the object id of the equivalent object.*/
-+yaffs_obj_t *yaffs_link_obj(yaffs_obj_t *parent, const YCHAR *name,
-+			yaffs_obj_t *equiv_obj)
-+{
-+	/* Get the real object in case we were fed a hard link as an equivalent object */
-+	equiv_obj = yaffs_get_equivalent_obj(equiv_obj);
- 
--			/* Find the dirty cache for this object with the lowest chunk id. */
--			for (i = 0; i < nCaches; i++) {
--				if (dev->srCache[i].object == obj &&
--				    dev->srCache[i].dirty) {
--					if (!cache
--					    || dev->srCache[i].chunkId <
--					    lowest) {
--						cache = &dev->srCache[i];
--						lowest = cache->chunkId;
--					}
--				}
--			}
-+	if (yaffs_create_obj
-+	    (YAFFS_OBJECT_TYPE_HARDLINK, parent, name, 0, 0, 0,
-+	     equiv_obj, NULL, 0)) {
-+		return equiv_obj;
-+	} else {
-+		return NULL;
-+	}
- 
--			if (cache && !cache->locked) {
--				/* Write it out and free it up */
-+}
- 
--				chunkWritten =
--				    yaffs_WriteChunkDataToObject(cache->object,
--								 cache->chunkId,
--								 cache->data,
--								 cache->nBytes,
--								 1);
--				cache->dirty = 0;
--				cache->object = NULL;
--			}
-+static int yaffs_change_obj_name(yaffs_obj_t *obj, yaffs_obj_t *new_dir,
-+				const YCHAR *new_name, int force, int shadows)
-+{
-+	int unlinkOp;
-+	int deleteOp;
- 
--		} while (cache && chunkWritten > 0);
-+	yaffs_obj_t *existingTarget;
- 
--		if (cache) {
--			/* Hoosterman, disk full while writing cache out. */
--			T(YAFFS_TRACE_ERROR,
--			  (TSTR("yaffs tragedy: no space during cache write" TENDSTR)));
-+	if (new_dir == NULL)
-+		new_dir = obj->parent;	/* use the old directory */
- 
--		}
-+	if (new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+		T(YAFFS_TRACE_ALWAYS,
-+		  (TSTR
-+		   ("tragedy: yaffs_change_obj_name: new_dir is not a directory"
-+		    TENDSTR)));
-+		YBUG();
- 	}
- 
--}
-+	/* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
-+	if (obj->my_dev->param.is_yaffs2)
-+		unlinkOp = (new_dir == obj->my_dev->unlinked_dir);
-+	else
-+		unlinkOp = (new_dir == obj->my_dev->unlinked_dir
-+			    && obj->variant_type == YAFFS_OBJECT_TYPE_FILE);
- 
--/*yaffs_FlushEntireDeviceCache(dev)
-- *
-- *
-- */
-+	deleteOp = (new_dir == obj->my_dev->del_dir);
- 
--void yaffs_FlushEntireDeviceCache(yaffs_Device *dev)
--{
--	yaffs_Object *obj;
--	int nCaches = dev->nShortOpCaches;
--	int i;
-+	existingTarget = yaffs_find_by_name(new_dir, new_name);
- 
--	/* Find a dirty object in the cache and flush it...
--	 * until there are no further dirty objects.
-+	/* If the object is a file going into the unlinked directory,
-+	 *   then it is OK to just stuff it in since duplicate names are allowed.
-+	 *   else only proceed if the new name does not exist and if we're putting
-+	 *   it into a directory.
- 	 */
--	do {
--		obj = NULL;
--		for (i = 0; i < nCaches && !obj; i++) {
--			if (dev->srCache[i].object &&
--			    dev->srCache[i].dirty)
--				obj = dev->srCache[i].object;
--
--		}
--		if (obj)
--			yaffs_FlushFilesChunkCache(obj);
--
--	} while (obj);
--
--}
-+	if ((unlinkOp ||
-+	     deleteOp ||
-+	     force ||
-+	     (shadows > 0) ||
-+	     !existingTarget) &&
-+	    new_dir->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {
-+		yaffs_set_obj_name(obj, new_name);
-+		obj->dirty = 1;
- 
-+		yaffs_add_obj_to_dir(new_dir, obj);
- 
--/* Grab us a cache chunk for use.
-- * First look for an empty one.
-- * Then look for the least recently used non-dirty one.
-- * Then look for the least recently used dirty one...., flush and look again.
-- */
--static yaffs_ChunkCache *yaffs_GrabChunkCacheWorker(yaffs_Device *dev)
--{
--	int i;
-+		if (unlinkOp)
-+			obj->unlinked = 1;
- 
--	if (dev->nShortOpCaches > 0) {
--		for (i = 0; i < dev->nShortOpCaches; i++) {
--			if (!dev->srCache[i].object)
--				return &dev->srCache[i];
--		}
-+		/* If it is a deletion then we mark it as a shrink for gc purposes. */
-+		if (yaffs_update_oh(obj, new_name, 0, deleteOp, shadows, NULL) >= 0)
-+			return YAFFS_OK;
- 	}
- 
--	return NULL;
-+	return YAFFS_FAIL;
- }
- 
--static yaffs_ChunkCache *yaffs_GrabChunkCache(yaffs_Device *dev)
-+int yaffs_rename_obj(yaffs_obj_t *old_dir, const YCHAR *old_name,
-+		yaffs_obj_t *new_dir, const YCHAR *new_name)
- {
--	yaffs_ChunkCache *cache;
--	yaffs_Object *theObj;
--	int usage;
--	int i;
--	int pushout;
--
--	if (dev->nShortOpCaches > 0) {
--		/* Try find a non-dirty one... */
--
--		cache = yaffs_GrabChunkCacheWorker(dev);
-+	yaffs_obj_t *obj = NULL;
-+	yaffs_obj_t *existingTarget = NULL;
-+	int force = 0;
-+	int result;
-+	yaffs_dev_t *dev;
- 
--		if (!cache) {
--			/* They were all dirty, find the last recently used object and flush
--			 * its cache, then  find again.
--			 * NB what's here is not very accurate, we actually flush the object
--			 * the last recently used page.
--			 */
- 
--			/* With locking we can't assume we can use entry zero */
-+	if (!old_dir || old_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-+		YBUG();
-+	if (!new_dir || new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-+		YBUG();
- 
--			theObj = NULL;
--			usage = -1;
--			cache = NULL;
--			pushout = -1;
-+	dev = old_dir->my_dev;
- 
--			for (i = 0; i < dev->nShortOpCaches; i++) {
--				if (dev->srCache[i].object &&
--				    !dev->srCache[i].locked &&
--				    (dev->srCache[i].lastUse < usage || !cache)) {
--					usage = dev->srCache[i].lastUse;
--					theObj = dev->srCache[i].object;
--					cache = &dev->srCache[i];
--					pushout = i;
--				}
--			}
-+#ifdef CONFIG_YAFFS_CASE_INSENSITIVE
-+	/* Special case for case insemsitive systems (eg. WinCE).
-+	 * While look-up is case insensitive, the name isn't.
-+	 * Therefore we might want to change x.txt to X.txt
-+	*/
-+	if (old_dir == new_dir && yaffs_strcmp(old_name, new_name) == 0)
-+		force = 1;
-+#endif
- 
--			if (!cache || cache->dirty) {
--				/* Flush and try again */
--				yaffs_FlushFilesChunkCache(theObj);
--				cache = yaffs_GrabChunkCacheWorker(dev);
--			}
-+	if(yaffs_strnlen(new_name,YAFFS_MAX_NAME_LENGTH+1) > YAFFS_MAX_NAME_LENGTH)
-+		/* ENAMETOOLONG */
-+		return YAFFS_FAIL;
- 
--		}
--		return cache;
--	} else
--		return NULL;
-+	obj = yaffs_find_by_name(old_dir, old_name);
- 
--}
-+	if (obj && obj->rename_allowed) {
- 
--/* Find a cached chunk */
--static yaffs_ChunkCache *yaffs_FindChunkCache(const yaffs_Object *obj,
--					      int chunkId)
--{
--	yaffs_Device *dev = obj->myDev;
--	int i;
--	if (dev->nShortOpCaches > 0) {
--		for (i = 0; i < dev->nShortOpCaches; i++) {
--			if (dev->srCache[i].object == obj &&
--			    dev->srCache[i].chunkId == chunkId) {
--				dev->cacheHits++;
-+		/* Now do the handling for an existing target, if there is one */
- 
--				return &dev->srCache[i];
--			}
-+		existingTarget = yaffs_find_by_name(new_dir, new_name);
-+		if (existingTarget &&
-+			existingTarget->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY &&
-+			!ylist_empty(&existingTarget->variant.dir_variant.children)) {
-+			/* There is a target that is a non-empty directory, so we fail */
-+			return YAFFS_FAIL;	/* EEXIST or ENOTEMPTY */
-+		} else if (existingTarget && existingTarget != obj) {
-+			/* Nuke the target first, using shadowing,
-+			 * but only if it isn't the same object.
-+			 *
-+			 * Note we must disable gc otherwise it can mess up the shadowing.
-+			 *
-+			 */
-+			dev->gc_disable=1;
-+			yaffs_change_obj_name(obj, new_dir, new_name, force,
-+						existingTarget->obj_id);
-+			existingTarget->is_shadowed = 1;
-+			yaffs_unlink_obj(existingTarget);
-+			dev->gc_disable=0;
- 		}
-+
-+		result = yaffs_change_obj_name(obj, new_dir, new_name, 1, 0);
-+
-+		yaffs_update_parent(old_dir);
-+		if(new_dir != old_dir)
-+			yaffs_update_parent(new_dir);
-+		
-+		return result;
- 	}
--	return NULL;
-+	return YAFFS_FAIL;
- }
- 
--/* Mark the chunk for the least recently used algorithym */
--static void yaffs_UseChunkCache(yaffs_Device *dev, yaffs_ChunkCache *cache,
--				int isAWrite)
-+/*------------------------- Block Management and Page Allocation ----------------*/
-+
-+static int yaffs_init_blocks(yaffs_dev_t *dev)
- {
-+	int nBlocks = dev->internal_end_block - dev->internal_start_block + 1;
- 
--	if (dev->nShortOpCaches > 0) {
--		if (dev->srLastUse < 0 || dev->srLastUse > 100000000) {
--			/* Reset the cache usages */
--			int i;
--			for (i = 1; i < dev->nShortOpCaches; i++)
--				dev->srCache[i].lastUse = 0;
-+	dev->block_info = NULL;
-+	dev->chunk_bits = NULL;
- 
--			dev->srLastUse = 0;
--		}
-+	dev->alloc_block = -1;	/* force it to get a new one */
- 
--		dev->srLastUse++;
-+	/* If the first allocation strategy fails, thry the alternate one */
-+	dev->block_info = YMALLOC(nBlocks * sizeof(yaffs_block_info_t));
-+	if (!dev->block_info) {
-+		dev->block_info = YMALLOC_ALT(nBlocks * sizeof(yaffs_block_info_t));
-+		dev->block_info_alt = 1;
-+	} else
-+		dev->block_info_alt = 0;
- 
--		cache->lastUse = dev->srLastUse;
-+	if (dev->block_info) {
-+		/* Set up dynamic blockinfo stuff. */
-+		dev->chunk_bit_stride = (dev->param.chunks_per_block + 7) / 8; /* round up bytes */
-+		dev->chunk_bits = YMALLOC(dev->chunk_bit_stride * nBlocks);
-+		if (!dev->chunk_bits) {
-+			dev->chunk_bits = YMALLOC_ALT(dev->chunk_bit_stride * nBlocks);
-+			dev->chunk_bits_alt = 1;
-+		} else
-+			dev->chunk_bits_alt = 0;
-+	}
- 
--		if (isAWrite)
--			cache->dirty = 1;
-+	if (dev->block_info && dev->chunk_bits) {
-+		memset(dev->block_info, 0, nBlocks * sizeof(yaffs_block_info_t));
-+		memset(dev->chunk_bits, 0, dev->chunk_bit_stride * nBlocks);
-+		return YAFFS_OK;
- 	}
-+
-+	return YAFFS_FAIL;
- }
- 
--/* Invalidate a single cache page.
-- * Do this when a whole page gets written,
-- * ie the short cache for this page is no longer valid.
-- */
--static void yaffs_InvalidateChunkCache(yaffs_Object *object, int chunkId)
-+static void yaffs_deinit_blocks(yaffs_dev_t *dev)
- {
--	if (object->myDev->nShortOpCaches > 0) {
--		yaffs_ChunkCache *cache = yaffs_FindChunkCache(object, chunkId);
-+	if (dev->block_info_alt && dev->block_info)
-+		YFREE_ALT(dev->block_info);
-+	else if (dev->block_info)
-+		YFREE(dev->block_info);
- 
--		if (cache)
--			cache->object = NULL;
--	}
--}
-+	dev->block_info_alt = 0;
- 
--/* Invalidate all the cache pages associated with this object
-- * Do this whenever ther file is deleted or resized.
-- */
--static void yaffs_InvalidateWholeChunkCache(yaffs_Object *in)
--{
--	int i;
--	yaffs_Device *dev = in->myDev;
-+	dev->block_info = NULL;
- 
--	if (dev->nShortOpCaches > 0) {
--		/* Invalidate it. */
--		for (i = 0; i < dev->nShortOpCaches; i++) {
--			if (dev->srCache[i].object == in)
--				dev->srCache[i].object = NULL;
--		}
--	}
-+	if (dev->chunk_bits_alt && dev->chunk_bits)
-+		YFREE_ALT(dev->chunk_bits);
-+	else if (dev->chunk_bits)
-+		YFREE(dev->chunk_bits);
-+	dev->chunk_bits_alt = 0;
-+	dev->chunk_bits = NULL;
- }
- 
--/*--------------------- Checkpointing --------------------*/
-+void yaffs_block_became_dirty(yaffs_dev_t *dev, int block_no)
-+{
-+	yaffs_block_info_t *bi = yaffs_get_block_info(dev, block_no);
- 
-+	int erasedOk = 0;
- 
--static int yaffs_WriteCheckpointValidityMarker(yaffs_Device *dev, int head)
--{
--	yaffs_CheckpointValidity cp;
-+	/* If the block is still healthy erase it and mark as clean.
-+	 * If the block has had a data failure, then retire it.
-+	 */
- 
--	memset(&cp, 0, sizeof(cp));
-+	T(YAFFS_TRACE_GC | YAFFS_TRACE_ERASE,
-+		(TSTR("yaffs_block_became_dirty block %d state %d %s"TENDSTR),
-+		block_no, bi->block_state, (bi->needs_retiring) ? "needs retiring" : ""));
- 
--	cp.structType = sizeof(cp);
--	cp.magic = YAFFS_MAGIC;
--	cp.version = YAFFS_CHECKPOINT_VERSION;
--	cp.head = (head) ? 1 : 0;
-+	yaffs2_clear_oldest_dirty_seq(dev,bi);
- 
--	return (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp)) ?
--		1 : 0;
--}
-+	bi->block_state = YAFFS_BLOCK_STATE_DIRTY;
- 
--static int yaffs_ReadCheckpointValidityMarker(yaffs_Device *dev, int head)
--{
--	yaffs_CheckpointValidity cp;
--	int ok;
-+	/* If this is the block being garbage collected then stop gc'ing this block */
-+	if(block_no == dev->gc_block)
-+		dev->gc_block = 0;
- 
--	ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp));
-+	/* If this block is currently the best candidate for gc then drop as a candidate */
-+	if(block_no == dev->gc_dirtiest){
-+		dev->gc_dirtiest = 0;
-+		dev->gc_pages_in_use = 0;
-+	}
- 
--	if (ok)
--		ok = (cp.structType == sizeof(cp)) &&
--		     (cp.magic == YAFFS_MAGIC) &&
--		     (cp.version == YAFFS_CHECKPOINT_VERSION) &&
--		     (cp.head == ((head) ? 1 : 0));
--	return ok ? 1 : 0;
--}
-+	if (!bi->needs_retiring) {
-+		yaffs2_checkpt_invalidate(dev);
-+		erasedOk = yaffs_erase_block(dev, block_no);
-+		if (!erasedOk) {
-+			dev->n_erase_failures++;
-+			T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
-+			  (TSTR("**>> Erasure failed %d" TENDSTR), block_no));
-+		}
-+	}
- 
--static void yaffs_DeviceToCheckpointDevice(yaffs_CheckpointDevice *cp,
--					   yaffs_Device *dev)
--{
--	cp->nErasedBlocks = dev->nErasedBlocks;
--	cp->allocationBlock = dev->allocationBlock;
--	cp->allocationPage = dev->allocationPage;
--	cp->nFreeChunks = dev->nFreeChunks;
-+	if (erasedOk &&
-+	    ((yaffs_trace_mask & YAFFS_TRACE_ERASE) || !yaffs_skip_verification(dev))) {
-+		int i;
-+		for (i = 0; i < dev->param.chunks_per_block; i++) {
-+			if (!yaffs_check_chunk_erased
-+			    (dev, block_no * dev->param.chunks_per_block + i)) {
-+				T(YAFFS_TRACE_ERROR,
-+				  (TSTR
-+				   (">>Block %d erasure supposedly OK, but chunk %d not erased"
-+				    TENDSTR), block_no, i));
-+			}
-+		}
-+	}
-+
-+	if (erasedOk) {
-+		/* Clean it up... */
-+		bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
-+		bi->seq_number = 0;
-+		dev->n_erased_blocks++;
-+		bi->pages_in_use = 0;
-+		bi->soft_del_pages = 0;
-+		bi->has_shrink_hdr = 0;
-+		bi->skip_erased_check = 1;  /* This is clean, so no need to check */
-+		bi->gc_prioritise = 0;
-+		yaffs_clear_chunk_bits(dev, block_no);
- 
--	cp->nDeletedFiles = dev->nDeletedFiles;
--	cp->nUnlinkedFiles = dev->nUnlinkedFiles;
--	cp->nBackgroundDeletions = dev->nBackgroundDeletions;
--	cp->sequenceNumber = dev->sequenceNumber;
--	cp->oldestDirtySequence = dev->oldestDirtySequence;
-+		T(YAFFS_TRACE_ERASE,
-+		  (TSTR("Erased block %d" TENDSTR), block_no));
-+	} else {
-+		dev->n_free_chunks -= dev->param.chunks_per_block;	/* We lost a block of free space */
- 
-+		yaffs_retire_block(dev, block_no);
-+		T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
-+		  (TSTR("**>> Block %d retired" TENDSTR), block_no));
-+	}
- }
- 
--static void yaffs_CheckpointDeviceToDevice(yaffs_Device *dev,
--					   yaffs_CheckpointDevice *cp)
-+static int yaffs_find_alloc_block(yaffs_dev_t *dev)
- {
--	dev->nErasedBlocks = cp->nErasedBlocks;
--	dev->allocationBlock = cp->allocationBlock;
--	dev->allocationPage = cp->allocationPage;
--	dev->nFreeChunks = cp->nFreeChunks;
--
--	dev->nDeletedFiles = cp->nDeletedFiles;
--	dev->nUnlinkedFiles = cp->nUnlinkedFiles;
--	dev->nBackgroundDeletions = cp->nBackgroundDeletions;
--	dev->sequenceNumber = cp->sequenceNumber;
--	dev->oldestDirtySequence = cp->oldestDirtySequence;
--}
-+	int i;
- 
-+	yaffs_block_info_t *bi;
- 
--static int yaffs_WriteCheckpointDevice(yaffs_Device *dev)
--{
--	yaffs_CheckpointDevice cp;
--	__u32 nBytes;
--	__u32 nBlocks = (dev->internalEndBlock - dev->internalStartBlock + 1);
-+	if (dev->n_erased_blocks < 1) {
-+		/* Hoosterman we've got a problem.
-+		 * Can't get space to gc
-+		 */
-+		T(YAFFS_TRACE_ERROR,
-+		  (TSTR("yaffs tragedy: no more erased blocks" TENDSTR)));
- 
--	int ok;
-+		return -1;
-+	}
- 
--	/* Write device runtime values*/
--	yaffs_DeviceToCheckpointDevice(&cp, dev);
--	cp.structType = sizeof(cp);
-+	/* Find an empty block. */
- 
--	ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
-+	for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
-+		dev->alloc_block_finder++;
-+		if (dev->alloc_block_finder < dev->internal_start_block
-+		    || dev->alloc_block_finder > dev->internal_end_block) {
-+			dev->alloc_block_finder = dev->internal_start_block;
-+		}
- 
--	/* Write block info */
--	if (ok) {
--		nBytes = nBlocks * sizeof(yaffs_BlockInfo);
--		ok = (yaffs_CheckpointWrite(dev, dev->blockInfo, nBytes) == nBytes);
-+		bi = yaffs_get_block_info(dev, dev->alloc_block_finder);
-+
-+		if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) {
-+			bi->block_state = YAFFS_BLOCK_STATE_ALLOCATING;
-+			dev->seq_number++;
-+			bi->seq_number = dev->seq_number;
-+			dev->n_erased_blocks--;
-+			T(YAFFS_TRACE_ALLOCATE,
-+			  (TSTR("Allocated block %d, seq  %d, %d left" TENDSTR),
-+			   dev->alloc_block_finder, dev->seq_number,
-+			   dev->n_erased_blocks));
-+			return dev->alloc_block_finder;
-+		}
- 	}
- 
--	/* Write chunk bits */
--	if (ok) {
--		nBytes = nBlocks * dev->chunkBitmapStride;
--		ok = (yaffs_CheckpointWrite(dev, dev->chunkBits, nBytes) == nBytes);
--	}
--	return	 ok ? 1 : 0;
-+	T(YAFFS_TRACE_ALWAYS,
-+	  (TSTR
-+	   ("yaffs tragedy: no more erased blocks, but there should have been %d"
-+	    TENDSTR), dev->n_erased_blocks));
- 
-+	return -1;
- }
- 
--static int yaffs_ReadCheckpointDevice(yaffs_Device *dev)
-+
-+/*
-+ * Check if there's space to allocate...
-+ * Thinks.... do we need top make this ths same as yaffs_get_free_chunks()?
-+ */
-+int yaffs_check_alloc_available(yaffs_dev_t *dev, int n_chunks)
- {
--	yaffs_CheckpointDevice cp;
--	__u32 nBytes;
--	__u32 nBlocks = (dev->internalEndBlock - dev->internalStartBlock + 1);
-+	int reservedChunks;
-+	int reservedBlocks = dev->param.n_reserved_blocks;
-+	int checkpointBlocks;
- 
--	int ok;
-+	checkpointBlocks = yaffs_calc_checkpt_blocks_required(dev);
- 
--	ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp));
--	if (!ok)
--		return 0;
-+	reservedChunks = ((reservedBlocks + checkpointBlocks) * dev->param.chunks_per_block);
- 
--	if (cp.structType != sizeof(cp))
--		return 0;
-+	return (dev->n_free_chunks > (reservedChunks + n_chunks));
-+}
-+
-+static int yaffs_alloc_chunk(yaffs_dev_t *dev, int useReserve,
-+		yaffs_block_info_t **blockUsedPtr)
-+{
-+	int retVal;
-+	yaffs_block_info_t *bi;
-+
-+	if (dev->alloc_block < 0) {
-+		/* Get next block to allocate off */
-+		dev->alloc_block = yaffs_find_alloc_block(dev);
-+		dev->alloc_page = 0;
-+	}
- 
-+	if (!useReserve && !yaffs_check_alloc_available(dev, 1)) {
-+		/* Not enough space to allocate unless we're allowed to use the reserve. */
-+		return -1;
-+	}
- 
--	yaffs_CheckpointDeviceToDevice(dev, &cp);
-+	if (dev->n_erased_blocks < dev->param.n_reserved_blocks
-+			&& dev->alloc_page == 0) {
-+		T(YAFFS_TRACE_ALLOCATE, (TSTR("Allocating reserve" TENDSTR)));
-+	}
- 
--	nBytes = nBlocks * sizeof(yaffs_BlockInfo);
-+	/* Next page please.... */
-+	if (dev->alloc_block >= 0) {
-+		bi = yaffs_get_block_info(dev, dev->alloc_block);
- 
--	ok = (yaffs_CheckpointRead(dev, dev->blockInfo, nBytes) == nBytes);
-+		retVal = (dev->alloc_block * dev->param.chunks_per_block) +
-+			dev->alloc_page;
-+		bi->pages_in_use++;
-+		yaffs_set_chunk_bit(dev, dev->alloc_block,
-+				dev->alloc_page);
- 
--	if (!ok)
--		return 0;
--	nBytes = nBlocks * dev->chunkBitmapStride;
-+		dev->alloc_page++;
- 
--	ok = (yaffs_CheckpointRead(dev, dev->chunkBits, nBytes) == nBytes);
-+		dev->n_free_chunks--;
- 
--	return ok ? 1 : 0;
--}
-+		/* If the block is full set the state to full */
-+		if (dev->alloc_page >= dev->param.chunks_per_block) {
-+			bi->block_state = YAFFS_BLOCK_STATE_FULL;
-+			dev->alloc_block = -1;
-+		}
- 
--static void yaffs_ObjectToCheckpointObject(yaffs_CheckpointObject *cp,
--					   yaffs_Object *obj)
--{
-+		if (blockUsedPtr)
-+			*blockUsedPtr = bi;
-+
-+		return retVal;
-+	}
- 
--	cp->objectId = obj->objectId;
--	cp->parentId = (obj->parent) ? obj->parent->objectId : 0;
--	cp->hdrChunk = obj->hdrChunk;
--	cp->variantType = obj->variantType;
--	cp->deleted = obj->deleted;
--	cp->softDeleted = obj->softDeleted;
--	cp->unlinked = obj->unlinked;
--	cp->fake = obj->fake;
--	cp->renameAllowed = obj->renameAllowed;
--	cp->unlinkAllowed = obj->unlinkAllowed;
--	cp->serial = obj->serial;
--	cp->nDataChunks = obj->nDataChunks;
-+	T(YAFFS_TRACE_ERROR,
-+			(TSTR("!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!" TENDSTR)));
- 
--	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE)
--		cp->fileSizeOrEquivalentObjectId = obj->variant.fileVariant.fileSize;
--	else if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK)
--		cp->fileSizeOrEquivalentObjectId = obj->variant.hardLinkVariant.equivalentObjectId;
-+	return -1;
- }
- 
--static int yaffs_CheckpointObjectToObject(yaffs_Object *obj, yaffs_CheckpointObject *cp)
-+static int yaffs_get_erased_chunks(yaffs_dev_t *dev)
- {
-+	int n;
- 
--	yaffs_Object *parent;
-+	n = dev->n_erased_blocks * dev->param.chunks_per_block;
- 
--	if (obj->variantType != cp->variantType) {
--		T(YAFFS_TRACE_ERROR, (TSTR("Checkpoint read object %d type %d "
--			TCONT("chunk %d does not match existing object type %d")
--			TENDSTR), cp->objectId, cp->variantType, cp->hdrChunk,
--			obj->variantType));
--		return 0;
--	}
-+	if (dev->alloc_block > 0)
-+		n += (dev->param.chunks_per_block - dev->alloc_page);
- 
--	obj->objectId = cp->objectId;
-+	return n;
- 
--	if (cp->parentId)
--		parent = yaffs_FindOrCreateObjectByNumber(
--					obj->myDev,
--					cp->parentId,
--					YAFFS_OBJECT_TYPE_DIRECTORY);
--	else
--		parent = NULL;
-+}
- 
--	if (parent) {
--		if (parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
--			T(YAFFS_TRACE_ALWAYS, (TSTR("Checkpoint read object %d parent %d type %d"
--				TCONT(" chunk %d Parent type, %d, not directory")
--				TENDSTR),
--				cp->objectId, cp->parentId, cp->variantType,
--				cp->hdrChunk, parent->variantType));
--			return 0;
-+/*
-+ * yaffs_skip_rest_of_block() skips over the rest of the allocation block
-+ * if we don't want to write to it.
-+ */
-+void yaffs_skip_rest_of_block(yaffs_dev_t *dev)
-+{
-+	if(dev->alloc_block > 0){
-+		yaffs_block_info_t *bi = yaffs_get_block_info(dev, dev->alloc_block);
-+		if(bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING){
-+			bi->block_state = YAFFS_BLOCK_STATE_FULL;
-+			dev->alloc_block = -1;
- 		}
--		yaffs_AddObjectToDirectory(parent, obj);
- 	}
--
--	obj->hdrChunk = cp->hdrChunk;
--	obj->variantType = cp->variantType;
--	obj->deleted = cp->deleted;
--	obj->softDeleted = cp->softDeleted;
--	obj->unlinked = cp->unlinked;
--	obj->fake = cp->fake;
--	obj->renameAllowed = cp->renameAllowed;
--	obj->unlinkAllowed = cp->unlinkAllowed;
--	obj->serial = cp->serial;
--	obj->nDataChunks = cp->nDataChunks;
--
--	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE)
--		obj->variant.fileVariant.fileSize = cp->fileSizeOrEquivalentObjectId;
--	else if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK)
--		obj->variant.hardLinkVariant.equivalentObjectId = cp->fileSizeOrEquivalentObjectId;
--
--	if (obj->hdrChunk > 0)
--		obj->lazyLoaded = 1;
--	return 1;
- }
- 
- 
--
--static int yaffs_CheckpointTnodeWorker(yaffs_Object *in, yaffs_Tnode *tn,
--					__u32 level, int chunkOffset)
-+static int yaffs_gc_block(yaffs_dev_t *dev, int block,
-+		int wholeBlock)
- {
-+	int oldChunk;
-+	int newChunk;
-+	int mark_flash;
-+	int retVal = YAFFS_OK;
- 	int i;
--	yaffs_Device *dev = in->myDev;
--	int ok = 1;
--	int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
--
--	if (tnodeSize < sizeof(yaffs_Tnode))
--		tnodeSize = sizeof(yaffs_Tnode);
-+	int isCheckpointBlock;
-+	int matchingChunk;
-+	int maxCopies;
- 
-+	int chunksBefore = yaffs_get_erased_chunks(dev);
-+	int chunksAfter;
- 
--	if (tn) {
--		if (level > 0) {
-+	yaffs_ext_tags tags;
- 
--			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
--				if (tn->internal[i]) {
--					ok = yaffs_CheckpointTnodeWorker(in,
--							tn->internal[i],
--							level - 1,
--							(chunkOffset<<YAFFS_TNODES_INTERNAL_BITS) + i);
--				}
--			}
--		} else if (level == 0) {
--			__u32 baseOffset = chunkOffset <<  YAFFS_TNODES_LEVEL0_BITS;
--			ok = (yaffs_CheckpointWrite(dev, &baseOffset, sizeof(baseOffset)) == sizeof(baseOffset));
--			if (ok)
--				ok = (yaffs_CheckpointWrite(dev, tn, tnodeSize) == tnodeSize);
--		}
--	}
-+	yaffs_block_info_t *bi = yaffs_get_block_info(dev, block);
- 
--	return ok;
-+	yaffs_obj_t *object;
- 
--}
-+	isCheckpointBlock = (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT);
- 
--static int yaffs_WriteCheckpointTnodes(yaffs_Object *obj)
--{
--	__u32 endMarker = ~0;
--	int ok = 1;
- 
--	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE) {
--		ok = yaffs_CheckpointTnodeWorker(obj,
--					    obj->variant.fileVariant.top,
--					    obj->variant.fileVariant.topLevel,
--					    0);
--		if (ok)
--			ok = (yaffs_CheckpointWrite(obj->myDev, &endMarker, sizeof(endMarker)) ==
--				sizeof(endMarker));
--	}
-+	T(YAFFS_TRACE_TRACING,
-+			(TSTR("Collecting block %d, in use %d, shrink %d, wholeBlock %d" TENDSTR),
-+			 block,
-+			 bi->pages_in_use,
-+			 bi->has_shrink_hdr,
-+			 wholeBlock));
- 
--	return ok ? 1 : 0;
--}
-+	/*yaffs_verify_free_chunks(dev); */
- 
--static int yaffs_ReadCheckpointTnodes(yaffs_Object *obj)
--{
--	__u32 baseChunk;
--	int ok = 1;
--	yaffs_Device *dev = obj->myDev;
--	yaffs_FileStructure *fileStructPtr = &obj->variant.fileVariant;
--	yaffs_Tnode *tn;
--	int nread = 0;
--	int tnodeSize = (dev->tnodeWidth * YAFFS_NTNODES_LEVEL0)/8;
-+	if(bi->block_state == YAFFS_BLOCK_STATE_FULL)
-+		bi->block_state = YAFFS_BLOCK_STATE_COLLECTING;
-+	
-+	bi->has_shrink_hdr = 0;	/* clear the flag so that the block can erase */
- 
--	if (tnodeSize < sizeof(yaffs_Tnode))
--		tnodeSize = sizeof(yaffs_Tnode);
-+	dev->gc_disable = 1;
- 
--	ok = (yaffs_CheckpointRead(dev, &baseChunk, sizeof(baseChunk)) == sizeof(baseChunk));
-+	if (isCheckpointBlock ||
-+			!yaffs_still_some_chunks(dev, block)) {
-+		T(YAFFS_TRACE_TRACING,
-+				(TSTR
-+				 ("Collecting block %d that has no chunks in use" TENDSTR),
-+				 block));
-+		yaffs_block_became_dirty(dev, block);
-+	} else {
- 
--	while (ok && (~baseChunk)) {
--		nread++;
--		/* Read level 0 tnode */
-+		__u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
- 
-+		yaffs_verify_blk(dev, bi, block);
- 
--		tn = yaffs_GetTnodeRaw(dev);
--		if (tn)
--			ok = (yaffs_CheckpointRead(dev, tn, tnodeSize) == tnodeSize);
--		else
--			ok = 0;
-+		maxCopies = (wholeBlock) ? dev->param.chunks_per_block : 5;
-+		oldChunk = block * dev->param.chunks_per_block + dev->gc_chunk;
- 
--		if (tn && ok)
--			ok = yaffs_AddOrFindLevel0Tnode(dev,
--							fileStructPtr,
--							baseChunk,
--							tn) ? 1 : 0;
-+		for (/* init already done */;
-+		     retVal == YAFFS_OK &&
-+		     dev->gc_chunk < dev->param.chunks_per_block &&
-+		     (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) &&
-+		     maxCopies > 0;
-+		     dev->gc_chunk++, oldChunk++) {
-+			if (yaffs_check_chunk_bit(dev, block, dev->gc_chunk)) {
- 
--		if (ok)
--			ok = (yaffs_CheckpointRead(dev, &baseChunk, sizeof(baseChunk)) == sizeof(baseChunk));
-+				/* This page is in use and might need to be copied off */
- 
--	}
-+				maxCopies--;
- 
--	T(YAFFS_TRACE_CHECKPOINT, (
--		TSTR("Checkpoint read tnodes %d records, last %d. ok %d" TENDSTR),
--		nread, baseChunk, ok));
-+				mark_flash = 1;
- 
--	return ok ? 1 : 0;
--}
-+				yaffs_init_tags(&tags);
- 
-+				yaffs_rd_chunk_tags_nand(dev, oldChunk,
-+								buffer, &tags);
- 
--static int yaffs_WriteCheckpointObjects(yaffs_Device *dev)
--{
--	yaffs_Object *obj;
--	yaffs_CheckpointObject cp;
--	int i;
--	int ok = 1;
--	struct ylist_head *lh;
-+				object =
-+				    yaffs_find_by_number(dev,
-+							     tags.obj_id);
- 
-+				T(YAFFS_TRACE_GC_DETAIL,
-+				  (TSTR
-+				   ("Collecting chunk in block %d, %d %d %d " TENDSTR),
-+				   dev->gc_chunk, tags.obj_id, tags.chunk_id,
-+				   tags.n_bytes));
- 
--	/* Iterate through the objects in each hash entry,
--	 * dumping them to the checkpointing stream.
--	 */
-+				if (object && !yaffs_skip_verification(dev)) {
-+					if (tags.chunk_id == 0)
-+						matchingChunk = object->hdr_chunk;
-+					else if (object->soft_del)
-+						matchingChunk = oldChunk; /* Defeat the test */
-+					else
-+						matchingChunk = yaffs_find_chunk_in_file(object, tags.chunk_id, NULL);
- 
--	for (i = 0; ok &&  i <  YAFFS_NOBJECT_BUCKETS; i++) {
--		ylist_for_each(lh, &dev->objectBucket[i].list) {
--			if (lh) {
--				obj = ylist_entry(lh, yaffs_Object, hashLink);
--				if (!obj->deferedFree) {
--					yaffs_ObjectToCheckpointObject(&cp, obj);
--					cp.structType = sizeof(cp);
--
--					T(YAFFS_TRACE_CHECKPOINT, (
--						TSTR("Checkpoint write object %d parent %d type %d chunk %d obj addr %x" TENDSTR),
--						cp.objectId, cp.parentId, cp.variantType, cp.hdrChunk, (unsigned) obj));
-+					if (oldChunk != matchingChunk)
-+						T(YAFFS_TRACE_ERROR,
-+						  (TSTR("gc: page in gc mismatch: %d %d %d %d"TENDSTR),
-+						  oldChunk, matchingChunk, tags.obj_id, tags.chunk_id));
- 
--					ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
-+				}
- 
--					if (ok && obj->variantType == YAFFS_OBJECT_TYPE_FILE)
--						ok = yaffs_WriteCheckpointTnodes(obj);
-+				if (!object) {
-+					T(YAFFS_TRACE_ERROR,
-+					  (TSTR
-+					   ("page %d in gc has no object: %d %d %d "
-+					    TENDSTR), oldChunk,
-+					    tags.obj_id, tags.chunk_id, tags.n_bytes));
- 				}
--			}
--		}
--	}
- 
--	/* Dump end of list */
--	memset(&cp, 0xFF, sizeof(yaffs_CheckpointObject));
--	cp.structType = sizeof(cp);
-+				if (object &&
-+				    object->deleted &&
-+				    object->soft_del &&
-+				    tags.chunk_id != 0) {
-+					/* Data chunk in a soft deleted file, throw it away
-+					 * It's a soft deleted data chunk,
-+					 * No need to copy this, just forget about it and
-+					 * fix up the object.
-+					 */
-+					 
-+					/* Free chunks already includes softdeleted chunks.
-+					 * How ever this chunk is going to soon be really deleted
-+					 * which will increment free chunks.
-+					 * We have to decrement free chunks so this works out properly.
-+					 */
-+					dev->n_free_chunks--;
-+					bi->soft_del_pages--;
-+
-+					object->n_data_chunks--;
- 
--	if (ok)
--		ok = (yaffs_CheckpointWrite(dev, &cp, sizeof(cp)) == sizeof(cp));
-+					if (object->n_data_chunks <= 0) {
-+						/* remeber to clean up the object */
-+						dev->gc_cleanup_list[dev->n_clean_ups] =
-+						    tags.obj_id;
-+						dev->n_clean_ups++;
-+					}
-+					mark_flash = 0;
-+				} else if (0) {
-+					/* Todo object && object->deleted && object->n_data_chunks == 0 */
-+					/* Deleted object header with no data chunks.
-+					 * Can be discarded and the file deleted.
-+					 */
-+					object->hdr_chunk = 0;
-+					yaffs_free_tnode(object->my_dev,
-+							object->variant.
-+							file_variant.top);
-+					object->variant.file_variant.top = NULL;
-+					yaffs_generic_obj_del(object);
- 
--	return ok ? 1 : 0;
--}
-+				} else if (object) {
-+					/* It's either a data chunk in a live file or
-+					 * an ObjectHeader, so we're interested in it.
-+					 * NB Need to keep the ObjectHeaders of deleted files
-+					 * until the whole file has been deleted off
-+					 */
-+					tags.serial_number++;
- 
--static int yaffs_ReadCheckpointObjects(yaffs_Device *dev)
--{
--	yaffs_Object *obj;
--	yaffs_CheckpointObject cp;
--	int ok = 1;
--	int done = 0;
--	yaffs_Object *hardList = NULL;
-+					dev->n_gc_copies++;
- 
--	while (ok && !done) {
--		ok = (yaffs_CheckpointRead(dev, &cp, sizeof(cp)) == sizeof(cp));
--		if (cp.structType != sizeof(cp)) {
--			T(YAFFS_TRACE_CHECKPOINT, (TSTR("struct size %d instead of %d ok %d"TENDSTR),
--				cp.structType, sizeof(cp), ok));
--			ok = 0;
--		}
--
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("Checkpoint read object %d parent %d type %d chunk %d " TENDSTR),
--			cp.objectId, cp.parentId, cp.variantType, cp.hdrChunk));
--
--		if (ok && cp.objectId == ~0)
--			done = 1;
--		else if (ok) {
--			obj = yaffs_FindOrCreateObjectByNumber(dev, cp.objectId, cp.variantType);
--			if (obj) {
--				ok = yaffs_CheckpointObjectToObject(obj, &cp);
--				if (!ok)
--					break;
--				if (obj->variantType == YAFFS_OBJECT_TYPE_FILE) {
--					ok = yaffs_ReadCheckpointTnodes(obj);
--				} else if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
--					obj->hardLinks.next =
--						(struct ylist_head *) hardList;
--					hardList = obj;
--				}
--			} else
--				ok = 0;
--		}
--	}
-+					if (tags.chunk_id == 0) {
-+						/* It is an object Id,
-+						 * We need to nuke the shrinkheader flags first
-+						 * Also need to clean up shadowing.
-+						 * We no longer want the shrinkHeader flag since its work is done
-+						 * and if it is left in place it will mess up scanning.
-+						 */
- 
--	if (ok)
--		yaffs_HardlinkFixup(dev, hardList);
-+						yaffs_obj_header *oh;
-+						oh = (yaffs_obj_header *)buffer;
- 
--	return ok ? 1 : 0;
--}
-+						oh->is_shrink = 0;
-+						tags.extra_is_shrink = 0;
- 
--static int yaffs_WriteCheckpointSum(yaffs_Device *dev)
--{
--	__u32 checkpointSum;
--	int ok;
-+						oh->shadows_obj = 0;
-+						oh->inband_shadowed_obj_id = 0;
-+						tags.extra_shadows = 0;
-+
-+						/* Update file size */
-+						if(object->variant_type == YAFFS_OBJECT_TYPE_FILE){
-+							oh->file_size = object->variant.file_variant.file_size;
-+							tags.extra_length = oh->file_size;
-+						}
-+
-+						yaffs_verify_oh(object, oh, &tags, 1);
-+						newChunk =
-+						    yaffs_write_new_chunk(dev,(__u8 *) oh, &tags, 1);
-+					} else
-+						newChunk =
-+						    yaffs_write_new_chunk(dev, buffer, &tags, 1);
-+
-+					if (newChunk < 0) {
-+						retVal = YAFFS_FAIL;
-+					} else {
- 
--	yaffs_GetCheckpointSum(dev, &checkpointSum);
-+						/* Ok, now fix up the Tnodes etc. */
- 
--	ok = (yaffs_CheckpointWrite(dev, &checkpointSum, sizeof(checkpointSum)) == sizeof(checkpointSum));
-+						if (tags.chunk_id == 0) {
-+							/* It's a header */
-+							object->hdr_chunk =  newChunk;
-+							object->serial =   tags.serial_number;
-+						} else {
-+							/* It's a data chunk */
-+							int ok;
-+							ok = yaffs_put_chunk_in_file
-+							    (object,
-+							     tags.chunk_id,
-+							     newChunk, 0);
-+						}
-+					}
-+				}
- 
--	if (!ok)
--		return 0;
-+				if (retVal == YAFFS_OK)
-+					yaffs_chunk_del(dev, oldChunk, mark_flash, __LINE__);
- 
--	return 1;
--}
-+			}
-+		}
- 
--static int yaffs_ReadCheckpointSum(yaffs_Device *dev)
--{
--	__u32 checkpointSum0;
--	__u32 checkpointSum1;
--	int ok;
-+		yaffs_release_temp_buffer(dev, buffer, __LINE__);
- 
--	yaffs_GetCheckpointSum(dev, &checkpointSum0);
- 
--	ok = (yaffs_CheckpointRead(dev, &checkpointSum1, sizeof(checkpointSum1)) == sizeof(checkpointSum1));
- 
--	if (!ok)
--		return 0;
-+	}
- 
--	if (checkpointSum0 != checkpointSum1)
--		return 0;
-+	yaffs_verify_collected_blk(dev, bi, block);
- 
--	return 1;
--}
- 
- 
--static int yaffs_WriteCheckpointData(yaffs_Device *dev)
--{
--	int ok = 1;
-+	if (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) {
-+		/*
-+		 * The gc did not complete. Set block state back to FULL
-+		 * because checkpointing does not restore gc.
-+		 */
-+		bi->block_state = YAFFS_BLOCK_STATE_FULL;
-+	} else {
-+		/* The gc completed. */
-+		/* Do any required cleanups */
-+		for (i = 0; i < dev->n_clean_ups; i++) {
-+			/* Time to delete the file too */
-+			object =
-+			    yaffs_find_by_number(dev,
-+						     dev->gc_cleanup_list[i]);
-+			if (object) {
-+				yaffs_free_tnode(dev,
-+						object->variant.file_variant.
-+						top);
-+				object->variant.file_variant.top = NULL;
-+				T(YAFFS_TRACE_GC,
-+				  (TSTR
-+				   ("yaffs: About to finally delete object %d"
-+				    TENDSTR), object->obj_id));
-+				yaffs_generic_obj_del(object);
-+				object->my_dev->n_deleted_files--;
-+			}
- 
--	if (dev->skipCheckpointWrite || !dev->isYaffs2) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint write" TENDSTR)));
--		ok = 0;
--	}
-+		}
- 
--	if (ok)
--		ok = yaffs_CheckpointOpen(dev, 1);
- 
--	if (ok) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint validity" TENDSTR)));
--		ok = yaffs_WriteCheckpointValidityMarker(dev, 1);
--	}
--	if (ok) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint device" TENDSTR)));
--		ok = yaffs_WriteCheckpointDevice(dev);
--	}
--	if (ok) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint objects" TENDSTR)));
--		ok = yaffs_WriteCheckpointObjects(dev);
--	}
--	if (ok) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint validity" TENDSTR)));
--		ok = yaffs_WriteCheckpointValidityMarker(dev, 0);
-+		chunksAfter = yaffs_get_erased_chunks(dev);
-+		if (chunksBefore >= chunksAfter) {
-+			T(YAFFS_TRACE_GC,
-+			  (TSTR
-+			   ("gc did not increase free chunks before %d after %d"
-+			    TENDSTR), chunksBefore, chunksAfter));
-+		}
-+		dev->gc_block = 0;
-+		dev->gc_chunk = 0;
-+		dev->n_clean_ups = 0;
- 	}
- 
--	if (ok)
--		ok = yaffs_WriteCheckpointSum(dev);
--
--	if (!yaffs_CheckpointClose(dev))
--		ok = 0;
--
--	if (ok)
--		dev->isCheckpointed = 1;
--	else
--		dev->isCheckpointed = 0;
-+	dev->gc_disable = 0;
- 
--	return dev->isCheckpointed;
-+	return retVal;
- }
- 
--static int yaffs_ReadCheckpointData(yaffs_Device *dev)
-+/*
-+ * FindBlockForgarbageCollection is used to select the dirtiest block (or close enough)
-+ * for garbage collection.
-+ */
-+
-+static unsigned yaffs_find_gc_block(yaffs_dev_t *dev,
-+					int aggressive,
-+					int background)
- {
--	int ok = 1;
-+	int i;
-+	int iterations;
-+	unsigned selected = 0;
-+	int prioritised = 0;
-+	int prioritisedExists = 0;
-+	yaffs_block_info_t *bi;
-+	int threshold;
- 
--	if (dev->skipCheckpointRead || !dev->isYaffs2) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint read" TENDSTR)));
--		ok = 0;
--	}
-+	/* First let's see if we need to grab a prioritised block */
-+	if (dev->has_pending_prioritised_gc && !aggressive) {
-+		dev->gc_dirtiest = 0;
-+		bi = dev->block_info;
-+		for (i = dev->internal_start_block;
-+			i <= dev->internal_end_block && !selected;
-+			i++) {
-+
-+			if (bi->gc_prioritise) {
-+				prioritisedExists = 1;
-+				if (bi->block_state == YAFFS_BLOCK_STATE_FULL &&
-+				   yaffs_block_ok_for_gc(dev, bi)) {
-+					selected = i;
-+					prioritised = 1;
-+				}
-+			}
-+			bi++;
-+		}
- 
--	if (ok)
--		ok = yaffs_CheckpointOpen(dev, 0); /* open for read */
-+		/*
-+		 * If there is a prioritised block and none was selected then
-+		 * this happened because there is at least one old dirty block gumming
-+		 * up the works. Let's gc the oldest dirty block.
-+		 */
- 
--	if (ok) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint validity" TENDSTR)));
--		ok = yaffs_ReadCheckpointValidityMarker(dev, 1);
--	}
--	if (ok) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint device" TENDSTR)));
--		ok = yaffs_ReadCheckpointDevice(dev);
--	}
--	if (ok) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint objects" TENDSTR)));
--		ok = yaffs_ReadCheckpointObjects(dev);
--	}
--	if (ok) {
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint validity" TENDSTR)));
--		ok = yaffs_ReadCheckpointValidityMarker(dev, 0);
--	}
-+		if(prioritisedExists &&
-+			!selected &&
-+			dev->oldest_dirty_block > 0)
-+			selected = dev->oldest_dirty_block;
- 
--	if (ok) {
--		ok = yaffs_ReadCheckpointSum(dev);
--		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint checksum %d" TENDSTR), ok));
-+		if (!prioritisedExists) /* None found, so we can clear this */
-+			dev->has_pending_prioritised_gc = 0;
- 	}
- 
--	if (!yaffs_CheckpointClose(dev))
--		ok = 0;
--
--	if (ok)
--		dev->isCheckpointed = 1;
--	else
--		dev->isCheckpointed = 0;
--
--	return ok ? 1 : 0;
-+	/* If we're doing aggressive GC then we are happy to take a less-dirty block, and
-+	 * search harder.
-+	 * else (we're doing a leasurely gc), then we only bother to do this if the
-+	 * block has only a few pages in use.
-+	 */
- 
--}
-+	if (!selected){
-+		int pagesUsed;
-+		int nBlocks = dev->internal_end_block - dev->internal_start_block + 1;
-+		if (aggressive){
-+			threshold = dev->param.chunks_per_block;
-+			iterations = nBlocks;
-+		} else {
-+			int maxThreshold;
- 
--static void yaffs_InvalidateCheckpoint(yaffs_Device *dev)
--{
--	if (dev->isCheckpointed ||
--			dev->blocksInCheckpoint > 0) {
--		dev->isCheckpointed = 0;
--		yaffs_CheckpointInvalidateStream(dev);
--		if (dev->superBlock && dev->markSuperBlockDirty)
--			dev->markSuperBlockDirty(dev->superBlock);
--	}
--}
-+			if(background)
-+				maxThreshold = dev->param.chunks_per_block/2;
-+			else
-+				maxThreshold = dev->param.chunks_per_block/8;
- 
-+			if(maxThreshold <  YAFFS_GC_PASSIVE_THRESHOLD)
-+				maxThreshold = YAFFS_GC_PASSIVE_THRESHOLD;
- 
--int yaffs_CheckpointSave(yaffs_Device *dev)
--{
-+			threshold = background ?
-+				(dev->gc_not_done + 2) * 2 : 0;
-+			if(threshold <YAFFS_GC_PASSIVE_THRESHOLD)
-+				threshold = YAFFS_GC_PASSIVE_THRESHOLD;
-+			if(threshold > maxThreshold)
-+				threshold = maxThreshold;
- 
--	T(YAFFS_TRACE_CHECKPOINT, (TSTR("save entry: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
-+			iterations = nBlocks / 16 + 1;
-+			if (iterations > 100)
-+				iterations = 100;
-+		}
- 
--	yaffs_VerifyObjects(dev);
--	yaffs_VerifyBlocks(dev);
--	yaffs_VerifyFreeChunks(dev);
-+		for (i = 0;
-+			i < iterations &&
-+			(dev->gc_dirtiest < 1 ||
-+				dev->gc_pages_in_use > YAFFS_GC_GOOD_ENOUGH);
-+			i++) {
-+			dev->gc_block_finder++;
-+			if (dev->gc_block_finder < dev->internal_start_block ||
-+				dev->gc_block_finder > dev->internal_end_block)
-+				dev->gc_block_finder = dev->internal_start_block;
- 
--	if (!dev->isCheckpointed) {
--		yaffs_InvalidateCheckpoint(dev);
--		yaffs_WriteCheckpointData(dev);
--	}
-+			bi = yaffs_get_block_info(dev, dev->gc_block_finder);
- 
--	T(YAFFS_TRACE_ALWAYS, (TSTR("save exit: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
-+			pagesUsed = bi->pages_in_use - bi->soft_del_pages;
- 
--	return dev->isCheckpointed;
--}
-+			if (bi->block_state == YAFFS_BLOCK_STATE_FULL &&
-+				pagesUsed < dev->param.chunks_per_block &&
-+				(dev->gc_dirtiest < 1 || pagesUsed < dev->gc_pages_in_use) &&
-+				yaffs_block_ok_for_gc(dev, bi)) {
-+				dev->gc_dirtiest = dev->gc_block_finder;
-+				dev->gc_pages_in_use = pagesUsed;
-+			}
-+		}
- 
--int yaffs_CheckpointRestore(yaffs_Device *dev)
--{
--	int retval;
--	T(YAFFS_TRACE_CHECKPOINT, (TSTR("restore entry: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
-+		if(dev->gc_dirtiest > 0 && dev->gc_pages_in_use <= threshold)
-+			selected = dev->gc_dirtiest;
-+	}
- 
--	retval = yaffs_ReadCheckpointData(dev);
-+	/*
-+	 * If nothing has been selected for a while, try selecting the oldest dirty
-+	 * because that's gumming up the works.
-+	 */
- 
--	if (dev->isCheckpointed) {
--		yaffs_VerifyObjects(dev);
--		yaffs_VerifyBlocks(dev);
--		yaffs_VerifyFreeChunks(dev);
-+	if(!selected && dev->param.is_yaffs2 &&
-+		dev->gc_not_done >= ( background ? 10 : 20)){
-+		yaffs2_find_oldest_dirty_seq(dev);
-+		if(dev->oldest_dirty_block > 0) {
-+			selected = dev->oldest_dirty_block;
-+			dev->gc_dirtiest = selected;
-+			dev->oldest_dirty_gc_count++;
-+			bi = yaffs_get_block_info(dev, selected);
-+			dev->gc_pages_in_use =  bi->pages_in_use - bi->soft_del_pages;
-+		} else
-+			dev->gc_not_done = 0;
- 	}
- 
--	T(YAFFS_TRACE_CHECKPOINT, (TSTR("restore exit: isCheckpointed %d"TENDSTR), dev->isCheckpointed));
-+	if(selected){
-+		T(YAFFS_TRACE_GC,
-+		  (TSTR("GC Selected block %d with %d free, prioritised:%d" TENDSTR),
-+		  selected,
-+		  dev->param.chunks_per_block - dev->gc_pages_in_use,
-+		  prioritised));
-+
-+		dev->n_gc_blocks++;
-+		if(background)
-+			dev->bg_gcs++;
-+
-+		dev->gc_dirtiest = 0;
-+		dev->gc_pages_in_use = 0;
-+		dev->gc_not_done = 0;
-+		if(dev->refresh_skip > 0)
-+			dev->refresh_skip--;
-+	} else{
-+		dev->gc_not_done++;
-+		T(YAFFS_TRACE_GC,
-+		  (TSTR("GC none: finder %d skip %d threshold %d dirtiest %d using %d oldest %d%s" TENDSTR),
-+		  dev->gc_block_finder, dev->gc_not_done,
-+		  threshold,
-+		  dev->gc_dirtiest, dev->gc_pages_in_use,
-+		  dev->oldest_dirty_block,
-+		  background ? " bg" : ""));
-+	}
- 
--	return retval;
-+	return selected;
- }
- 
--/*--------------------- File read/write ------------------------
-- * Read and write have very similar structures.
-- * In general the read/write has three parts to it
-- * An incomplete chunk to start with (if the read/write is not chunk-aligned)
-- * Some complete chunks
-- * An incomplete chunk to end off with
-+/* New garbage collector
-+ * If we're very low on erased blocks then we do aggressive garbage collection
-+ * otherwise we do "leasurely" garbage collection.
-+ * Aggressive gc looks further (whole array) and will accept less dirty blocks.
-+ * Passive gc only inspects smaller areas and will only accept more dirty blocks.
-  *
-- * Curve-balls: the first chunk might also be the last chunk.
-+ * The idea is to help clear out space in a more spread-out manner.
-+ * Dunno if it really does anything useful.
-  */
--
--int yaffs_ReadDataFromFile(yaffs_Object *in, __u8 *buffer, loff_t offset,
--			int nBytes)
-+static int yaffs_check_gc(yaffs_dev_t *dev, int background)
- {
-+	int aggressive = 0;
-+	int gcOk = YAFFS_OK;
-+	int maxTries = 0;
-+	int minErased;
-+	int erasedChunks;
-+	int checkpointBlockAdjust;
- 
--	int chunk;
--	__u32 start;
--	int nToCopy;
--	int n = nBytes;
--	int nDone = 0;
--	yaffs_ChunkCache *cache;
--
--	yaffs_Device *dev;
--
--	dev = in->myDev;
--
--	while (n > 0) {
--		/* chunk = offset / dev->nDataBytesPerChunk + 1; */
--		/* start = offset % dev->nDataBytesPerChunk; */
--		yaffs_AddrToChunk(dev, offset, &chunk, &start);
--		chunk++;
--
--		/* OK now check for the curveball where the start and end are in
--		 * the same chunk.
--		 */
--		if ((start + n) < dev->nDataBytesPerChunk)
--			nToCopy = n;
--		else
--			nToCopy = dev->nDataBytesPerChunk - start;
--
--		cache = yaffs_FindChunkCache(in, chunk);
--
--		/* If the chunk is already in the cache or it is less than a whole chunk
--		 * or we're using inband tags then use the cache (if there is caching)
--		 * else bypass the cache.
--		 */
--		if (cache || nToCopy != dev->nDataBytesPerChunk || dev->inbandTags) {
--			if (dev->nShortOpCaches > 0) {
--
--				/* If we can't find the data in the cache, then load it up. */
-+	if(dev->param.gc_control &&
-+		(dev->param.gc_control(dev) & 1) == 0)
-+		return YAFFS_OK;
- 
--				if (!cache) {
--					cache = yaffs_GrabChunkCache(in->myDev);
--					cache->object = in;
--					cache->chunkId = chunk;
--					cache->dirty = 0;
--					cache->locked = 0;
--					yaffs_ReadChunkDataFromObject(in, chunk,
--								      cache->
--								      data);
--					cache->nBytes = 0;
--				}
-+	if (dev->gc_disable) {
-+		/* Bail out so we don't get recursive gc */
-+		return YAFFS_OK;
-+	}
- 
--				yaffs_UseChunkCache(dev, cache, 0);
-+	/* This loop should pass the first time.
-+	 * We'll only see looping here if the collection does not increase space.
-+	 */
- 
--				cache->locked = 1;
-+	do {
-+		maxTries++;
- 
-+		checkpointBlockAdjust = yaffs_calc_checkpt_blocks_required(dev);
- 
--				memcpy(buffer, &cache->data[start], nToCopy);
-+		minErased  = dev->param.n_reserved_blocks + checkpointBlockAdjust + 1;
-+		erasedChunks = dev->n_erased_blocks * dev->param.chunks_per_block;
- 
--				cache->locked = 0;
--			} else {
--				/* Read into the local buffer then copy..*/
-+		/* If we need a block soon then do aggressive gc.*/
-+		if (dev->n_erased_blocks < minErased)
-+			aggressive = 1;
-+		else {
-+			if(!background && erasedChunks > (dev->n_free_chunks / 4))
-+				break;
- 
--				__u8 *localBuffer =
--				    yaffs_GetTempBuffer(dev, __LINE__);
--				yaffs_ReadChunkDataFromObject(in, chunk,
--							      localBuffer);
-+			if(dev->gc_skip > 20)
-+				dev->gc_skip = 20;
-+			if(erasedChunks < dev->n_free_chunks/2 ||
-+				dev->gc_skip < 1 ||
-+				background)
-+				aggressive = 0;
-+			else {
-+				dev->gc_skip--;
-+				break;
-+			}
-+		}
- 
--				memcpy(buffer, &localBuffer[start], nToCopy);
-+		dev->gc_skip = 5;
- 
-+                /* If we don't already have a block being gc'd then see if we should start another */
- 
--				yaffs_ReleaseTempBuffer(dev, localBuffer,
--							__LINE__);
--			}
-+		if (dev->gc_block < 1 && !aggressive) {
-+			dev->gc_block = yaffs2_find_refresh_block(dev);
-+			dev->gc_chunk = 0;
-+			dev->n_clean_ups=0;
-+		}
-+		if (dev->gc_block < 1) {
-+			dev->gc_block = yaffs_find_gc_block(dev, aggressive, background);
-+			dev->gc_chunk = 0;
-+			dev->n_clean_ups=0;
-+		}
- 
--		} else {
-+		if (dev->gc_block > 0) {
-+			dev->all_gcs++;
-+			if (!aggressive)
-+				dev->passive_gc_count++;
- 
--			/* A full chunk. Read directly into the supplied buffer. */
--			yaffs_ReadChunkDataFromObject(in, chunk, buffer);
-+			T(YAFFS_TRACE_GC,
-+			  (TSTR
-+			   ("yaffs: GC erasedBlocks %d aggressive %d" TENDSTR),
-+			   dev->n_erased_blocks, aggressive));
- 
-+			gcOk = yaffs_gc_block(dev, dev->gc_block, aggressive);
- 		}
- 
--		n -= nToCopy;
--		offset += nToCopy;
--		buffer += nToCopy;
--		nDone += nToCopy;
--
--	}
-+		if (dev->n_erased_blocks < (dev->param.n_reserved_blocks) && dev->gc_block > 0) {
-+			T(YAFFS_TRACE_GC,
-+			  (TSTR
-+			   ("yaffs: GC !!!no reclaim!!! erasedBlocks %d after try %d block %d"
-+			    TENDSTR), dev->n_erased_blocks, maxTries, dev->gc_block));
-+		}
-+	} while ((dev->n_erased_blocks < dev->param.n_reserved_blocks) &&
-+		 (dev->gc_block > 0) &&
-+		 (maxTries < 2));
- 
--	return nDone;
-+	return aggressive ? gcOk : YAFFS_OK;
- }
- 
--int yaffs_WriteDataToFile(yaffs_Object *in, const __u8 *buffer, loff_t offset,
--			int nBytes, int writeThrough)
-+/*
-+ * yaffs_bg_gc()
-+ * Garbage collects. Intended to be called from a background thread.
-+ * Returns non-zero if at least half the free chunks are erased.
-+ */
-+int yaffs_bg_gc(yaffs_dev_t *dev, unsigned urgency)
- {
-+	int erasedChunks = dev->n_erased_blocks * dev->param.chunks_per_block;
- 
--	int chunk;
--	__u32 start;
--	int nToCopy;
--	int n = nBytes;
--	int nDone = 0;
--	int nToWriteBack;
--	int startOfWrite = offset;
--	int chunkWritten = 0;
--	__u32 nBytesRead;
--	__u32 chunkStart;
-+	T(YAFFS_TRACE_BACKGROUND, (TSTR("Background gc %u" TENDSTR),urgency));
- 
--	yaffs_Device *dev;
-+	yaffs_check_gc(dev, 1);
-+	return erasedChunks > dev->n_free_chunks/2;
-+}
- 
--	dev = in->myDev;
-+/*-------------------------  TAGS --------------------------------*/
- 
--	while (n > 0 && chunkWritten >= 0) {
--		/* chunk = offset / dev->nDataBytesPerChunk + 1; */
--		/* start = offset % dev->nDataBytesPerChunk; */
--		yaffs_AddrToChunk(dev, offset, &chunk, &start);
-+static int yaffs_tags_match(const yaffs_ext_tags *tags, int obj_id,
-+			   int chunkInObject)
-+{
-+	return (tags->chunk_id == chunkInObject &&
-+		tags->obj_id == obj_id && !tags->is_deleted) ? 1 : 0;
- 
--		if (chunk * dev->nDataBytesPerChunk + start != offset ||
--				start >= dev->nDataBytesPerChunk) {
--			T(YAFFS_TRACE_ERROR, (
--			   TSTR("AddrToChunk of offset %d gives chunk %d start %d"
--			   TENDSTR),
--			   (int)offset, chunk, start));
--		}
--		chunk++;
-+}
- 
--		/* OK now check for the curveball where the start and end are in
--		 * the same chunk.
--		 */
- 
--		if ((start + n) < dev->nDataBytesPerChunk) {
--			nToCopy = n;
-+/*-------------------- Data file manipulation -----------------*/
- 
--			/* Now folks, to calculate how many bytes to write back....
--			 * If we're overwriting and not writing to then end of file then
--			 * we need to write back as much as was there before.
--			 */
-+static int yaffs_find_chunk_in_file(yaffs_obj_t *in, int inode_chunk,
-+				 yaffs_ext_tags *tags)
-+{
-+	/*Get the Tnode, then get the level 0 offset chunk offset */
-+	yaffs_tnode_t *tn;
-+	int theChunk = -1;
-+	yaffs_ext_tags localTags;
-+	int retVal = -1;
- 
--			chunkStart = ((chunk - 1) * dev->nDataBytesPerChunk);
-+	yaffs_dev_t *dev = in->my_dev;
- 
--			if (chunkStart > in->variant.fileVariant.fileSize)
--				nBytesRead = 0; /* Past end of file */
--			else
--				nBytesRead = in->variant.fileVariant.fileSize - chunkStart;
-+	if (!tags) {
-+		/* Passed a NULL, so use our own tags space */
-+		tags = &localTags;
-+	}
- 
--			if (nBytesRead > dev->nDataBytesPerChunk)
--				nBytesRead = dev->nDataBytesPerChunk;
-+	tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk);
- 
--			nToWriteBack =
--			    (nBytesRead >
--			     (start + n)) ? nBytesRead : (start + n);
-+	if (tn) {
-+		theChunk = yaffs_get_group_base(dev, tn, inode_chunk);
- 
--			if (nToWriteBack < 0 || nToWriteBack > dev->nDataBytesPerChunk)
--				YBUG();
-+		retVal =
-+		    yaffs_find_chunk_in_group(dev, theChunk, tags, in->obj_id,
-+					   inode_chunk);
-+	}
-+	return retVal;
-+}
- 
--		} else {
--			nToCopy = dev->nDataBytesPerChunk - start;
--			nToWriteBack = dev->nDataBytesPerChunk;
--		}
-+static int yaffs_find_del_file_chunk(yaffs_obj_t *in, int inode_chunk,
-+					  yaffs_ext_tags *tags)
-+{
-+	/* Get the Tnode, then get the level 0 offset chunk offset */
-+	yaffs_tnode_t *tn;
-+	int theChunk = -1;
-+	yaffs_ext_tags localTags;
- 
--		if (nToCopy != dev->nDataBytesPerChunk || dev->inbandTags) {
--			/* An incomplete start or end chunk (or maybe both start and end chunk),
--			 * or we're using inband tags, so we want to use the cache buffers.
--			 */
--			if (dev->nShortOpCaches > 0) {
--				yaffs_ChunkCache *cache;
--				/* If we can't find the data in the cache, then load the cache */
--				cache = yaffs_FindChunkCache(in, chunk);
-+	yaffs_dev_t *dev = in->my_dev;
-+	int retVal = -1;
- 
--				if (!cache
--				    && yaffs_CheckSpaceForAllocation(in->
--								     myDev)) {
--					cache = yaffs_GrabChunkCache(in->myDev);
--					cache->object = in;
--					cache->chunkId = chunk;
--					cache->dirty = 0;
--					cache->locked = 0;
--					yaffs_ReadChunkDataFromObject(in, chunk,
--								      cache->
--								      data);
--				} else if (cache &&
--					!cache->dirty &&
--					!yaffs_CheckSpaceForAllocation(in->myDev)) {
--					/* Drop the cache if it was a read cache item and
--					 * no space check has been made for it.
--					 */
--					 cache = NULL;
--				}
-+	if (!tags) {
-+		/* Passed a NULL, so use our own tags space */
-+		tags = &localTags;
-+	}
- 
--				if (cache) {
--					yaffs_UseChunkCache(dev, cache, 1);
--					cache->locked = 1;
-+	tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk);
- 
-+	if (tn) {
- 
--					memcpy(&cache->data[start], buffer,
--					       nToCopy);
-+		theChunk = yaffs_get_group_base(dev, tn, inode_chunk);
- 
-+		retVal =
-+		    yaffs_find_chunk_in_group(dev, theChunk, tags, in->obj_id,
-+					   inode_chunk);
- 
--					cache->locked = 0;
--					cache->nBytes = nToWriteBack;
-+		/* Delete the entry in the filestructure (if found) */
-+		if (retVal != -1)
-+			yaffs_load_tnode_0(dev, tn, inode_chunk, 0);
-+	}
- 
--					if (writeThrough) {
--						chunkWritten =
--						    yaffs_WriteChunkDataToObject
--						    (cache->object,
--						     cache->chunkId,
--						     cache->data, cache->nBytes,
--						     1);
--						cache->dirty = 0;
--					}
-+	return retVal;
-+}
- 
--				} else {
--					chunkWritten = -1;	/* fail the write */
--				}
--			} else {
--				/* An incomplete start or end chunk (or maybe both start and end chunk)
--				 * Read into the local buffer then copy, then copy over and write back.
--				 */
- 
--				__u8 *localBuffer =
--				    yaffs_GetTempBuffer(dev, __LINE__);
-+int yaffs_put_chunk_in_file(yaffs_obj_t *in, int inode_chunk,
-+			        int nand_chunk, int in_scan)
-+{
-+	/* NB in_scan is zero unless scanning.
-+	 * For forward scanning, in_scan is > 0;
-+	 * for backward scanning in_scan is < 0
-+	 *
-+	 * nand_chunk = 0 is a dummy insert to make sure the tnodes are there.
-+	 */
- 
--				yaffs_ReadChunkDataFromObject(in, chunk,
--							      localBuffer);
-+	yaffs_tnode_t *tn;
-+	yaffs_dev_t *dev = in->my_dev;
-+	int existingChunk;
-+	yaffs_ext_tags existingTags;
-+	yaffs_ext_tags newTags;
-+	unsigned existingSerial, newSerial;
- 
-+	if (in->variant_type != YAFFS_OBJECT_TYPE_FILE) {
-+		/* Just ignore an attempt at putting a chunk into a non-file during scanning
-+		 * If it is not during Scanning then something went wrong!
-+		 */
-+		if (!in_scan) {
-+			T(YAFFS_TRACE_ERROR,
-+			  (TSTR
-+			   ("yaffs tragedy:attempt to put data chunk into a non-file"
-+			    TENDSTR)));
-+			YBUG();
-+		}
- 
-+		yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
-+		return YAFFS_OK;
-+	}
- 
--				memcpy(&localBuffer[start], buffer, nToCopy);
-+	tn = yaffs_add_find_tnode_0(dev,
-+					&in->variant.file_variant,
-+					inode_chunk,
-+					NULL);
-+	if (!tn)
-+		return YAFFS_FAIL;
-+	
-+	if(!nand_chunk)
-+		/* Dummy insert, bail now */
-+		return YAFFS_OK;
- 
--				chunkWritten =
--				    yaffs_WriteChunkDataToObject(in, chunk,
--								 localBuffer,
--								 nToWriteBack,
--								 0);
-+	existingChunk = yaffs_get_group_base(dev, tn, inode_chunk);
- 
--				yaffs_ReleaseTempBuffer(dev, localBuffer,
--							__LINE__);
-+	if (in_scan != 0) {
-+		/* If we're scanning then we need to test for duplicates
-+		 * NB This does not need to be efficient since it should only ever
-+		 * happen when the power fails during a write, then only one
-+		 * chunk should ever be affected.
-+		 *
-+		 * Correction for YAFFS2: This could happen quite a lot and we need to think about efficiency! TODO
-+		 * Update: For backward scanning we don't need to re-read tags so this is quite cheap.
-+		 */
-+
-+		if (existingChunk > 0) {
-+			/* NB Right now existing chunk will not be real chunk_id if the chunk group size > 1
-+			 *    thus we have to do a FindChunkInFile to get the real chunk id.
-+			 *
-+			 * We have a duplicate now we need to decide which one to use:
-+			 *
-+			 * Backwards scanning YAFFS2: The old one is what we use, dump the new one.
-+			 * Forward scanning YAFFS2: The new one is what we use, dump the old one.
-+			 * YAFFS1: Get both sets of tags and compare serial numbers.
-+			 */
-+
-+			if (in_scan > 0) {
-+				/* Only do this for forward scanning */
-+				yaffs_rd_chunk_tags_nand(dev,
-+								nand_chunk,
-+								NULL, &newTags);
- 
-+				/* Do a proper find */
-+				existingChunk =
-+				    yaffs_find_chunk_in_file(in, inode_chunk,
-+							  &existingTags);
- 			}
- 
--		} else {
--			/* A full chunk. Write directly from the supplied buffer. */
-+			if (existingChunk <= 0) {
-+				/*Hoosterman - how did this happen? */
- 
-+				T(YAFFS_TRACE_ERROR,
-+				  (TSTR
-+				   ("yaffs tragedy: existing chunk < 0 in scan"
-+				    TENDSTR)));
- 
-+			}
- 
--			chunkWritten =
--			    yaffs_WriteChunkDataToObject(in, chunk, buffer,
--							 dev->nDataBytesPerChunk,
--							 0);
-+			/* NB The deleted flags should be false, otherwise the chunks will
-+			 * not be loaded during a scan
-+			 */
- 
--			/* Since we've overwritten the cached data, we better invalidate it. */
--			yaffs_InvalidateChunkCache(in, chunk);
--		}
-+			if (in_scan > 0) {
-+				newSerial = newTags.serial_number;
-+				existingSerial = existingTags.serial_number;
-+			}
- 
--		if (chunkWritten >= 0) {
--			n -= nToCopy;
--			offset += nToCopy;
--			buffer += nToCopy;
--			nDone += nToCopy;
-+			if ((in_scan > 0) &&
-+			    (existingChunk <= 0 ||
-+			     ((existingSerial + 1) & 3) == newSerial)) {
-+				/* Forward scanning.
-+				 * Use new
-+				 * Delete the old one and drop through to update the tnode
-+				 */
-+				yaffs_chunk_del(dev, existingChunk, 1,
-+						  __LINE__);
-+			} else {
-+				/* Backward scanning or we want to use the existing one
-+				 * Use existing.
-+				 * Delete the new one and return early so that the tnode isn't changed
-+				 */
-+				yaffs_chunk_del(dev, nand_chunk, 1,
-+						  __LINE__);
-+				return YAFFS_OK;
-+			}
- 		}
- 
- 	}
- 
--	/* Update file object */
--
--	if ((startOfWrite + nDone) > in->variant.fileVariant.fileSize)
--		in->variant.fileVariant.fileSize = (startOfWrite + nDone);
-+	if (existingChunk == 0)
-+		in->n_data_chunks++;
- 
--	in->dirty = 1;
-+	yaffs_load_tnode_0(dev, tn, inode_chunk, nand_chunk);
- 
--	return nDone;
-+	return YAFFS_OK;
- }
- 
-+static int yaffs_rd_data_obj(yaffs_obj_t *in, int inode_chunk,
-+					__u8 *buffer)
-+{
-+	int nand_chunk = yaffs_find_chunk_in_file(in, inode_chunk, NULL);
- 
--/* ---------------------- File resizing stuff ------------------ */
-+	if (nand_chunk >= 0)
-+		return yaffs_rd_chunk_tags_nand(in->my_dev, nand_chunk,
-+						buffer, NULL);
-+	else {
-+		T(YAFFS_TRACE_NANDACCESS,
-+		  (TSTR("Chunk %d not found zero instead" TENDSTR),
-+		   nand_chunk));
-+		/* get sane (zero) data if you read a hole */
-+		memset(buffer, 0, in->my_dev->data_bytes_per_chunk);
-+		return 0;
-+	}
-+
-+}
- 
--static void yaffs_PruneResizedChunks(yaffs_Object *in, int newSize)
-+void yaffs_chunk_del(yaffs_dev_t *dev, int chunk_id, int mark_flash, int lyn)
- {
-+	int block;
-+	int page;
-+	yaffs_ext_tags tags;
-+	yaffs_block_info_t *bi;
- 
--	yaffs_Device *dev = in->myDev;
--	int oldFileSize = in->variant.fileVariant.fileSize;
-+	if (chunk_id <= 0)
-+		return;
- 
--	int lastDel = 1 + (oldFileSize - 1) / dev->nDataBytesPerChunk;
-+	dev->n_deletions++;
-+	block = chunk_id / dev->param.chunks_per_block;
-+	page = chunk_id % dev->param.chunks_per_block;
- 
--	int startDel = 1 + (newSize + dev->nDataBytesPerChunk - 1) /
--	    dev->nDataBytesPerChunk;
--	int i;
--	int chunkId;
- 
--	/* Delete backwards so that we don't end up with holes if
--	 * power is lost part-way through the operation.
-+	if (!yaffs_check_chunk_bit(dev, block, page))
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Deleting invalid chunk %d"TENDSTR),
-+			 chunk_id));
-+
-+	bi = yaffs_get_block_info(dev, block);
-+	
-+	yaffs2_update_oldest_dirty_seq(dev, block, bi);
-+
-+	T(YAFFS_TRACE_DELETION,
-+	  (TSTR("line %d delete of chunk %d" TENDSTR), lyn, chunk_id));
-+
-+	if (!dev->param.is_yaffs2 && mark_flash &&
-+	    bi->block_state != YAFFS_BLOCK_STATE_COLLECTING) {
-+
-+		yaffs_init_tags(&tags);
-+
-+		tags.is_deleted = 1;
-+
-+		yaffs_wr_chunk_tags_nand(dev, chunk_id, NULL, &tags);
-+		yaffs_handle_chunk_update(dev, chunk_id, &tags);
-+	} else {
-+		dev->n_unmarked_deletions++;
-+	}
-+
-+	/* Pull out of the management area.
-+	 * If the whole block became dirty, this will kick off an erasure.
- 	 */
--	for (i = lastDel; i >= startDel; i--) {
--		/* NB this could be optimised somewhat,
--		 * eg. could retrieve the tags and write them without
--		 * using yaffs_DeleteChunk
--		 */
-+	if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING ||
-+	    bi->block_state == YAFFS_BLOCK_STATE_FULL ||
-+	    bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
-+	    bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) {
-+		dev->n_free_chunks++;
- 
--		chunkId = yaffs_FindAndDeleteChunkInFile(in, i, NULL);
--		if (chunkId > 0) {
--			if (chunkId <
--			    (dev->internalStartBlock * dev->nChunksPerBlock)
--			    || chunkId >=
--			    ((dev->internalEndBlock +
--			      1) * dev->nChunksPerBlock)) {
--				T(YAFFS_TRACE_ALWAYS,
--				  (TSTR("Found daft chunkId %d for %d" TENDSTR),
--				   chunkId, i));
--			} else {
--				in->nDataChunks--;
--				yaffs_DeleteChunk(dev, chunkId, 1, __LINE__);
--			}
-+		yaffs_clear_chunk_bit(dev, block, page);
-+
-+		bi->pages_in_use--;
-+
-+		if (bi->pages_in_use == 0 &&
-+		    !bi->has_shrink_hdr &&
-+		    bi->block_state != YAFFS_BLOCK_STATE_ALLOCATING &&
-+		    bi->block_state != YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-+			yaffs_block_became_dirty(dev, block);
- 		}
-+
- 	}
- 
- }
- 
--int yaffs_ResizeFile(yaffs_Object *in, loff_t newSize)
-+static int yaffs_wr_data_obj(yaffs_obj_t *in, int inode_chunk,
-+					const __u8 *buffer, int n_bytes,
-+					int useReserve)
- {
-+	/* Find old chunk Need to do this to get serial number
-+	 * Write new one and patch into tree.
-+	 * Invalidate old tags.
-+	 */
- 
--	int oldFileSize = in->variant.fileVariant.fileSize;
--	__u32 newSizeOfPartialChunk;
--	int newFullChunks;
-+	int prevChunkId;
-+	yaffs_ext_tags prevTags;
- 
--	yaffs_Device *dev = in->myDev;
-+	int newChunkId;
-+	yaffs_ext_tags newTags;
- 
--	yaffs_AddrToChunk(dev, newSize, &newFullChunks, &newSizeOfPartialChunk);
-+	yaffs_dev_t *dev = in->my_dev;
- 
--	yaffs_FlushFilesChunkCache(in);
--	yaffs_InvalidateWholeChunkCache(in);
-+	yaffs_check_gc(dev,0);
- 
--	yaffs_CheckGarbageCollection(dev);
-+	/* Get the previous chunk at this location in the file if it exists.
-+	 * If it does not exist then put a zero into the tree. This creates
-+	 * the tnode now, rather than later when it is harder to clean up.
-+	 */
-+	prevChunkId = yaffs_find_chunk_in_file(in, inode_chunk, &prevTags);
-+	if(prevChunkId < 1 &&
-+		!yaffs_put_chunk_in_file(in, inode_chunk, 0, 0))
-+		return 0;
- 
--	if (in->variantType != YAFFS_OBJECT_TYPE_FILE)
--		return YAFFS_FAIL;
-+	/* Set up new tags */
-+	yaffs_init_tags(&newTags);
- 
--	if (newSize == oldFileSize)
--		return YAFFS_OK;
-+	newTags.chunk_id = inode_chunk;
-+	newTags.obj_id = in->obj_id;
-+	newTags.serial_number =
-+	    (prevChunkId > 0) ? prevTags.serial_number + 1 : 1;
-+	newTags.n_bytes = n_bytes;
- 
--	if (newSize < oldFileSize) {
-+	if (n_bytes < 1 || n_bytes > dev->param.total_bytes_per_chunk) {
-+		T(YAFFS_TRACE_ERROR,
-+		(TSTR("Writing %d bytes to chunk!!!!!!!!!" TENDSTR), n_bytes));
-+		YBUG();
-+	}
-+	
-+		
-+	newChunkId =
-+	    yaffs_write_new_chunk(dev, buffer, &newTags,
-+					      useReserve);
- 
--		yaffs_PruneResizedChunks(in, newSize);
-+	if (newChunkId > 0) {
-+		yaffs_put_chunk_in_file(in, inode_chunk, newChunkId, 0);
- 
--		if (newSizeOfPartialChunk != 0) {
--			int lastChunk = 1 + newFullChunks;
-+		if (prevChunkId > 0)
-+			yaffs_chunk_del(dev, prevChunkId, 1, __LINE__);
- 
--			__u8 *localBuffer = yaffs_GetTempBuffer(dev, __LINE__);
-+		yaffs_verify_file_sane(in);
-+	}
-+	return newChunkId;
- 
--			/* Got to read and rewrite the last chunk with its new size and zero pad */
--			yaffs_ReadChunkDataFromObject(in, lastChunk,
--						      localBuffer);
-+}
- 
--			memset(localBuffer + newSizeOfPartialChunk, 0,
--			       dev->nDataBytesPerChunk - newSizeOfPartialChunk);
-+/* UpdateObjectHeader updates the header on NAND for an object.
-+ * If name is not NULL, then that new name is used.
-+ */
-+int yaffs_update_oh(yaffs_obj_t *in, const YCHAR *name, int force,
-+			     int is_shrink, int shadows, yaffs_xattr_mod *xmod)
-+{
- 
--			yaffs_WriteChunkDataToObject(in, lastChunk, localBuffer,
--						     newSizeOfPartialChunk, 1);
-+	yaffs_block_info_t *bi;
- 
--			yaffs_ReleaseTempBuffer(dev, localBuffer, __LINE__);
--		}
-+	yaffs_dev_t *dev = in->my_dev;
- 
--		in->variant.fileVariant.fileSize = newSize;
-+	int prevChunkId;
-+	int retVal = 0;
-+	int result = 0;
- 
--		yaffs_PruneFileStructure(dev, &in->variant.fileVariant);
--	} else {
--		/* newsSize > oldFileSize */
--		in->variant.fileVariant.fileSize = newSize;
--	}
-+	int newChunkId;
-+	yaffs_ext_tags newTags;
-+	yaffs_ext_tags oldTags;
-+	const YCHAR *alias = NULL;
- 
-+	__u8 *buffer = NULL;
-+	YCHAR old_name[YAFFS_MAX_NAME_LENGTH + 1];
- 
--	/* Write a new object header.
--	 * show we've shrunk the file, if need be
--	 * Do this only if the file is not in the deleted directories.
--	 */
--	if (in->parent &&
--	    in->parent->objectId != YAFFS_OBJECTID_UNLINKED &&
--	    in->parent->objectId != YAFFS_OBJECTID_DELETED)
--		yaffs_UpdateObjectHeader(in, NULL, 0,
--					 (newSize < oldFileSize) ? 1 : 0, 0);
-+	yaffs_obj_header *oh = NULL;
- 
--	return YAFFS_OK;
--}
-+	yaffs_strcpy(old_name, _Y("silly old name"));
- 
--loff_t yaffs_GetFileSize(yaffs_Object *obj)
--{
--	obj = yaffs_GetEquivalentObject(obj);
- 
--	switch (obj->variantType) {
--	case YAFFS_OBJECT_TYPE_FILE:
--		return obj->variant.fileVariant.fileSize;
--	case YAFFS_OBJECT_TYPE_SYMLINK:
--		return yaffs_strlen(obj->variant.symLinkVariant.alias);
--	default:
--		return 0;
--	}
--}
-+	if (!in->fake ||
-+		in == dev->root_dir || /* The root_dir should also be saved */
-+		force  || xmod) {
- 
-+		yaffs_check_gc(dev,0);
-+		yaffs_check_obj_details_loaded(in);
- 
-+		buffer = yaffs_get_temp_buffer(in->my_dev, __LINE__);
-+		oh = (yaffs_obj_header *) buffer;
-+
-+		prevChunkId = in->hdr_chunk;
-+
-+		if (prevChunkId > 0) {
-+			result = yaffs_rd_chunk_tags_nand(dev, prevChunkId,
-+							buffer, &oldTags);
-+
-+			yaffs_verify_oh(in, oh, &oldTags, 0);
-+
-+			memcpy(old_name, oh->name, sizeof(oh->name));
-+			memset(buffer, 0xFF, sizeof(yaffs_obj_header));
-+		} else
-+			memset(buffer, 0xFF, dev->data_bytes_per_chunk);
-+
-+		oh->type = in->variant_type;
-+		oh->yst_mode = in->yst_mode;
-+		oh->shadows_obj = oh->inband_shadowed_obj_id = shadows;
- 
--int yaffs_FlushFile(yaffs_Object *in, int updateTime)
--{
--	int retVal;
--	if (in->dirty) {
--		yaffs_FlushFilesChunkCache(in);
--		if (updateTime) {
- #ifdef CONFIG_YAFFS_WINCE
--			yfsd_WinFileTimeNow(in->win_mtime);
-+		oh->win_atime[0] = in->win_atime[0];
-+		oh->win_ctime[0] = in->win_ctime[0];
-+		oh->win_mtime[0] = in->win_mtime[0];
-+		oh->win_atime[1] = in->win_atime[1];
-+		oh->win_ctime[1] = in->win_ctime[1];
-+		oh->win_mtime[1] = in->win_mtime[1];
- #else
-+		oh->yst_uid = in->yst_uid;
-+		oh->yst_gid = in->yst_gid;
-+		oh->yst_atime = in->yst_atime;
-+		oh->yst_mtime = in->yst_mtime;
-+		oh->yst_ctime = in->yst_ctime;
-+		oh->yst_rdev = in->yst_rdev;
-+#endif
-+		if (in->parent)
-+			oh->parent_obj_id = in->parent->obj_id;
-+		else
-+			oh->parent_obj_id = 0;
-+
-+		if (name && *name) {
-+			memset(oh->name, 0, sizeof(oh->name));
-+			yaffs_load_oh_from_name(dev,oh->name,name);
-+		} else if (prevChunkId > 0)
-+			memcpy(oh->name, old_name, sizeof(oh->name));
-+		else
-+			memset(oh->name, 0, sizeof(oh->name));
- 
--			in->yst_mtime = Y_CURRENT_TIME;
-+		oh->is_shrink = is_shrink;
- 
--#endif
-+		switch (in->variant_type) {
-+		case YAFFS_OBJECT_TYPE_UNKNOWN:
-+			/* Should not happen */
-+			break;
-+		case YAFFS_OBJECT_TYPE_FILE:
-+			oh->file_size =
-+			    (oh->parent_obj_id == YAFFS_OBJECTID_DELETED
-+			     || oh->parent_obj_id ==
-+			     YAFFS_OBJECTID_UNLINKED) ? 0 : in->variant.
-+			    file_variant.file_size;
-+			break;
-+		case YAFFS_OBJECT_TYPE_HARDLINK:
-+			oh->equiv_id =
-+			    in->variant.hardlink_variant.equiv_id;
-+			break;
-+		case YAFFS_OBJECT_TYPE_SPECIAL:
-+			/* Do nothing */
-+			break;
-+		case YAFFS_OBJECT_TYPE_DIRECTORY:
-+			/* Do nothing */
-+			break;
-+		case YAFFS_OBJECT_TYPE_SYMLINK:
-+			alias = in->variant.symlink_variant.alias;
-+			if(!alias)
-+				alias = _Y("no alias");
-+			yaffs_strncpy(oh->alias,
-+					alias,
-+				      YAFFS_MAX_ALIAS_LENGTH);
-+			oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0;
-+			break;
- 		}
- 
--		retVal = (yaffs_UpdateObjectHeader(in, NULL, 0, 0, 0) >=
--			0) ? YAFFS_OK : YAFFS_FAIL;
--	} else {
--		retVal = YAFFS_OK;
--	}
-+		/* process any xattrib modifications */
-+		if(xmod)
-+			yaffs_apply_xattrib_mod(in, (char *)buffer, xmod);
- 
--	return retVal;
- 
--}
-+		/* Tags */
-+		yaffs_init_tags(&newTags);
-+		in->serial++;
-+		newTags.chunk_id = 0;
-+		newTags.obj_id = in->obj_id;
-+		newTags.serial_number = in->serial;
- 
--static int yaffs_DoGenericObjectDeletion(yaffs_Object *in)
--{
-+		/* Add extra info for file header */
- 
--	/* First off, invalidate the file's data in the cache, without flushing. */
--	yaffs_InvalidateWholeChunkCache(in);
-+		newTags.extra_available = 1;
-+		newTags.extra_parent_id = oh->parent_obj_id;
-+		newTags.extra_length = oh->file_size;
-+		newTags.extra_is_shrink = oh->is_shrink;
-+		newTags.extra_equiv_id = oh->equiv_id;
-+		newTags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0;
-+		newTags.extra_obj_type = in->variant_type;
- 
--	if (in->myDev->isYaffs2 && (in->parent != in->myDev->deletedDir)) {
--		/* Move to the unlinked directory so we have a record that it was deleted. */
--		yaffs_ChangeObjectName(in, in->myDev->deletedDir, _Y("deleted"), 0, 0);
-+		yaffs_verify_oh(in, oh, &newTags, 1);
- 
--	}
-+		/* Create new chunk in NAND */
-+		newChunkId =
-+		    yaffs_write_new_chunk(dev, buffer, &newTags,
-+						      (prevChunkId > 0) ? 1 : 0);
- 
--	yaffs_RemoveObjectFromDirectory(in);
--	yaffs_DeleteChunk(in->myDev, in->hdrChunk, 1, __LINE__);
--	in->hdrChunk = 0;
-+		if (newChunkId >= 0) {
- 
--	yaffs_FreeObject(in);
--	return YAFFS_OK;
-+			in->hdr_chunk = newChunkId;
- 
--}
-+			if (prevChunkId > 0) {
-+				yaffs_chunk_del(dev, prevChunkId, 1,
-+						  __LINE__);
-+			}
- 
--/* yaffs_DeleteFile deletes the whole file data
-- * and the inode associated with the file.
-- * It does not delete the links associated with the file.
-- */
--static int yaffs_UnlinkFileIfNeeded(yaffs_Object *in)
--{
-+			if (!yaffs_obj_cache_dirty(in))
-+				in->dirty = 0;
- 
--	int retVal;
--	int immediateDeletion = 0;
-+			/* If this was a shrink, then mark the block that the chunk lives on */
-+			if (is_shrink) {
-+				bi = yaffs_get_block_info(in->my_dev,
-+					newChunkId / in->my_dev->param.chunks_per_block);
-+				bi->has_shrink_hdr = 1;
-+			}
- 
--#ifdef __KERNEL__
--	if (!in->myInode)
--		immediateDeletion = 1;
--#else
--	if (in->inUse <= 0)
--		immediateDeletion = 1;
--#endif
-+		}
-+
-+		retVal = newChunkId;
- 
--	if (immediateDeletion) {
--		retVal =
--		    yaffs_ChangeObjectName(in, in->myDev->deletedDir,
--					   _Y("deleted"), 0, 0);
--		T(YAFFS_TRACE_TRACING,
--		  (TSTR("yaffs: immediate deletion of file %d" TENDSTR),
--		   in->objectId));
--		in->deleted = 1;
--		in->myDev->nDeletedFiles++;
--		if (1 || in->myDev->isYaffs2)
--			yaffs_ResizeFile(in, 0);
--		yaffs_SoftDeleteFile(in);
--	} else {
--		retVal =
--		    yaffs_ChangeObjectName(in, in->myDev->unlinkedDir,
--					   _Y("unlinked"), 0, 0);
- 	}
- 
-+	if (buffer)
-+		yaffs_release_temp_buffer(dev, buffer, __LINE__);
- 
- 	return retVal;
- }
- 
--int yaffs_DeleteFile(yaffs_Object *in)
--{
--	int retVal = YAFFS_OK;
--	int deleted = in->deleted;
--
--	yaffs_ResizeFile(in, 0);
--
--	if (in->nDataChunks > 0) {
--		/* Use soft deletion if there is data in the file.
--		 * That won't be the case if it has been resized to zero.
--		 */
--		if (!in->unlinked)
--			retVal = yaffs_UnlinkFileIfNeeded(in);
--
--		if (retVal == YAFFS_OK && in->unlinked && !in->deleted) {
--			in->deleted = 1;
--			deleted = 1;
--			in->myDev->nDeletedFiles++;
--			yaffs_SoftDeleteFile(in);
--		}
--		return deleted ? YAFFS_OK : YAFFS_FAIL;
--	} else {
--		/* The file has no data chunks so we toss it immediately */
--		yaffs_FreeTnode(in->myDev, in->variant.fileVariant.top);
--		in->variant.fileVariant.top = NULL;
--		yaffs_DoGenericObjectDeletion(in);
--
--		return YAFFS_OK;
--	}
--}
-+/*------------------------ Short Operations Cache ----------------------------------------
-+ *   In many situations where there is no high level buffering (eg WinCE) a lot of
-+ *   reads might be short sequential reads, and a lot of writes may be short
-+ *   sequential writes. eg. scanning/writing a jpeg file.
-+ *   In these cases, a short read/write cache can provide a huge perfomance benefit
-+ *   with dumb-as-a-rock code.
-+ *   In Linux, the page cache provides read buffering aand the short op cache provides write
-+ *   buffering.
-+ *
-+ *   There are a limited number (~10) of cache chunks per device so that we don't
-+ *   need a very intelligent search.
-+ */
- 
--static int yaffs_DeleteDirectory(yaffs_Object *in)
-+static int yaffs_obj_cache_dirty(yaffs_obj_t *obj)
- {
--	/* First check that the directory is empty. */
--	if (ylist_empty(&in->variant.directoryVariant.children))
--		return yaffs_DoGenericObjectDeletion(in);
-+	yaffs_dev_t *dev = obj->my_dev;
-+	int i;
-+	yaffs_cache_t *cache;
-+	int nCaches = obj->my_dev->param.n_caches;
- 
--	return YAFFS_FAIL;
-+	for (i = 0; i < nCaches; i++) {
-+		cache = &dev->cache[i];
-+		if (cache->object == obj &&
-+		    cache->dirty)
-+			return 1;
-+	}
- 
-+	return 0;
- }
- 
--static int yaffs_DeleteSymLink(yaffs_Object *in)
--{
--	YFREE(in->variant.symLinkVariant.alias);
--
--	return yaffs_DoGenericObjectDeletion(in);
--}
- 
--static int yaffs_DeleteHardLink(yaffs_Object *in)
-+static void yaffs_flush_file_cache(yaffs_obj_t *obj)
- {
--	/* remove this hardlink from the list assocaited with the equivalent
--	 * object
--	 */
--	ylist_del_init(&in->hardLinks);
--	return yaffs_DoGenericObjectDeletion(in);
--}
-+	yaffs_dev_t *dev = obj->my_dev;
-+	int lowest = -99;	/* Stop compiler whining. */
-+	int i;
-+	yaffs_cache_t *cache;
-+	int chunkWritten = 0;
-+	int nCaches = obj->my_dev->param.n_caches;
- 
--int yaffs_DeleteObject(yaffs_Object *obj)
--{
--int retVal = -1;
--	switch (obj->variantType) {
--	case YAFFS_OBJECT_TYPE_FILE:
--		retVal = yaffs_DeleteFile(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_DIRECTORY:
--		return yaffs_DeleteDirectory(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_SYMLINK:
--		retVal = yaffs_DeleteSymLink(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_HARDLINK:
--		retVal = yaffs_DeleteHardLink(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_SPECIAL:
--		retVal = yaffs_DoGenericObjectDeletion(obj);
--		break;
--	case YAFFS_OBJECT_TYPE_UNKNOWN:
--		retVal = 0;
--		break;		/* should not happen. */
--	}
-+	if (nCaches > 0) {
-+		do {
-+			cache = NULL;
- 
--	return retVal;
--}
-+			/* Find the dirty cache for this object with the lowest chunk id. */
-+			for (i = 0; i < nCaches; i++) {
-+				if (dev->cache[i].object == obj &&
-+				    dev->cache[i].dirty) {
-+					if (!cache
-+					    || dev->cache[i].chunk_id <
-+					    lowest) {
-+						cache = &dev->cache[i];
-+						lowest = cache->chunk_id;
-+					}
-+				}
-+			}
- 
--static int yaffs_UnlinkWorker(yaffs_Object *obj)
--{
-+			if (cache && !cache->locked) {
-+				/* Write it out and free it up */
- 
--	int immediateDeletion = 0;
-+				chunkWritten =
-+				    yaffs_wr_data_obj(cache->object,
-+								 cache->chunk_id,
-+								 cache->data,
-+								 cache->n_bytes,
-+								 1);
-+				cache->dirty = 0;
-+				cache->object = NULL;
-+			}
- 
--#ifdef __KERNEL__
--	if (!obj->myInode)
--		immediateDeletion = 1;
--#else
--	if (obj->inUse <= 0)
--		immediateDeletion = 1;
--#endif
-+		} while (cache && chunkWritten > 0);
- 
--	if (obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
--		return yaffs_DeleteHardLink(obj);
--	} else if (!ylist_empty(&obj->hardLinks)) {
--		/* Curve ball: We're unlinking an object that has a hardlink.
--		 *
--		 * This problem arises because we are not strictly following
--		 * The Linux link/inode model.
--		 *
--		 * We can't really delete the object.
--		 * Instead, we do the following:
--		 * - Select a hardlink.
--		 * - Unhook it from the hard links
--		 * - Unhook it from its parent directory (so that the rename can work)
--		 * - Rename the object to the hardlink's name.
--		 * - Delete the hardlink
--		 */
-+		if (cache) {
-+			/* Hoosterman, disk full while writing cache out. */
-+			T(YAFFS_TRACE_ERROR,
-+			  (TSTR("yaffs tragedy: no space during cache write" TENDSTR)));
- 
--		yaffs_Object *hl;
--		int retVal;
--		YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
-+		}
-+	}
- 
--		hl = ylist_entry(obj->hardLinks.next, yaffs_Object, hardLinks);
-+}
- 
--		ylist_del_init(&hl->hardLinks);
--		ylist_del_init(&hl->siblings);
-+/*yaffs_flush_whole_cache(dev)
-+ *
-+ *
-+ */
- 
--		yaffs_GetObjectName(hl, name, YAFFS_MAX_NAME_LENGTH + 1);
-+void yaffs_flush_whole_cache(yaffs_dev_t *dev)
-+{
-+	yaffs_obj_t *obj;
-+	int nCaches = dev->param.n_caches;
-+	int i;
- 
--		retVal = yaffs_ChangeObjectName(obj, hl->parent, name, 0, 0);
-+	/* Find a dirty object in the cache and flush it...
-+	 * until there are no further dirty objects.
-+	 */
-+	do {
-+		obj = NULL;
-+		for (i = 0; i < nCaches && !obj; i++) {
-+			if (dev->cache[i].object &&
-+			    dev->cache[i].dirty)
-+				obj = dev->cache[i].object;
- 
--		if (retVal == YAFFS_OK)
--			retVal = yaffs_DoGenericObjectDeletion(hl);
-+		}
-+		if (obj)
-+			yaffs_flush_file_cache(obj);
- 
--		return retVal;
-+	} while (obj);
- 
--	} else if (immediateDeletion) {
--		switch (obj->variantType) {
--		case YAFFS_OBJECT_TYPE_FILE:
--			return yaffs_DeleteFile(obj);
--			break;
--		case YAFFS_OBJECT_TYPE_DIRECTORY:
--			return yaffs_DeleteDirectory(obj);
--			break;
--		case YAFFS_OBJECT_TYPE_SYMLINK:
--			return yaffs_DeleteSymLink(obj);
--			break;
--		case YAFFS_OBJECT_TYPE_SPECIAL:
--			return yaffs_DoGenericObjectDeletion(obj);
--			break;
--		case YAFFS_OBJECT_TYPE_HARDLINK:
--		case YAFFS_OBJECT_TYPE_UNKNOWN:
--		default:
--			return YAFFS_FAIL;
--		}
--	} else
--		return yaffs_ChangeObjectName(obj, obj->myDev->unlinkedDir,
--					   _Y("unlinked"), 0, 0);
- }
- 
- 
--static int yaffs_UnlinkObject(yaffs_Object *obj)
-+/* Grab us a cache chunk for use.
-+ * First look for an empty one.
-+ * Then look for the least recently used non-dirty one.
-+ * Then look for the least recently used dirty one...., flush and look again.
-+ */
-+static yaffs_cache_t *yaffs_grab_chunk_worker(yaffs_dev_t *dev)
- {
-+	int i;
- 
--	if (obj && obj->unlinkAllowed)
--		return yaffs_UnlinkWorker(obj);
--
--	return YAFFS_FAIL;
--
--}
--int yaffs_Unlink(yaffs_Object *dir, const YCHAR *name)
--{
--	yaffs_Object *obj;
-+	if (dev->param.n_caches > 0) {
-+		for (i = 0; i < dev->param.n_caches; i++) {
-+			if (!dev->cache[i].object)
-+				return &dev->cache[i];
-+		}
-+	}
- 
--	obj = yaffs_FindObjectByName(dir, name);
--	return yaffs_UnlinkObject(obj);
-+	return NULL;
- }
- 
--/*----------------------- Initialisation Scanning ---------------------- */
--
--static void yaffs_HandleShadowedObject(yaffs_Device *dev, int objId,
--				int backwardScanning)
-+static yaffs_cache_t *yaffs_grab_chunk_cache(yaffs_dev_t *dev)
- {
--	yaffs_Object *obj;
-+	yaffs_cache_t *cache;
-+	yaffs_obj_t *theObj;
-+	int usage;
-+	int i;
-+	int pushout;
- 
--	if (!backwardScanning) {
--		/* Handle YAFFS1 forward scanning case
--		 * For YAFFS1 we always do the deletion
--		 */
-+	if (dev->param.n_caches > 0) {
-+		/* Try find a non-dirty one... */
- 
--	} else {
--		/* Handle YAFFS2 case (backward scanning)
--		 * If the shadowed object exists then ignore.
--		 */
--		if (yaffs_FindObjectByNumber(dev, objId))
--			return;
--	}
-+		cache = yaffs_grab_chunk_worker(dev);
- 
--	/* Let's create it (if it does not exist) assuming it is a file so that it can do shrinking etc.
--	 * We put it in unlinked dir to be cleaned up after the scanning
--	 */
--	obj =
--	    yaffs_FindOrCreateObjectByNumber(dev, objId,
--					     YAFFS_OBJECT_TYPE_FILE);
--	if (!obj)
--		return;
--	yaffs_AddObjectToDirectory(dev->unlinkedDir, obj);
--	obj->variant.fileVariant.shrinkSize = 0;
--	obj->valid = 1;		/* So that we don't read any other info for this file */
-+		if (!cache) {
-+			/* They were all dirty, find the last recently used object and flush
-+			 * its cache, then  find again.
-+			 * NB what's here is not very accurate, we actually flush the object
-+			 * the last recently used page.
-+			 */
- 
--}
-+			/* With locking we can't assume we can use entry zero */
- 
--typedef struct {
--	int seq;
--	int block;
--} yaffs_BlockIndex;
-+			theObj = NULL;
-+			usage = -1;
-+			cache = NULL;
-+			pushout = -1;
- 
-+			for (i = 0; i < dev->param.n_caches; i++) {
-+				if (dev->cache[i].object &&
-+				    !dev->cache[i].locked &&
-+				    (dev->cache[i].last_use < usage || !cache)) {
-+					usage = dev->cache[i].last_use;
-+					theObj = dev->cache[i].object;
-+					cache = &dev->cache[i];
-+					pushout = i;
-+				}
-+			}
- 
--static void yaffs_HardlinkFixup(yaffs_Device *dev, yaffs_Object *hardList)
--{
--	yaffs_Object *hl;
--	yaffs_Object *in;
-+			if (!cache || cache->dirty) {
-+				/* Flush and try again */
-+				yaffs_flush_file_cache(theObj);
-+				cache = yaffs_grab_chunk_worker(dev);
-+			}
- 
--	while (hardList) {
--		hl = hardList;
--		hardList = (yaffs_Object *) (hardList->hardLinks.next);
-+		}
-+		return cache;
-+	} else
-+		return NULL;
- 
--		in = yaffs_FindObjectByNumber(dev,
--					      hl->variant.hardLinkVariant.
--					      equivalentObjectId);
-+}
- 
--		if (in) {
--			/* Add the hardlink pointers */
--			hl->variant.hardLinkVariant.equivalentObject = in;
--			ylist_add(&hl->hardLinks, &in->hardLinks);
--		} else {
--			/* Todo Need to report/handle this better.
--			 * Got a problem... hardlink to a non-existant object
--			 */
--			hl->variant.hardLinkVariant.equivalentObject = NULL;
--			YINIT_LIST_HEAD(&hl->hardLinks);
-+/* Find a cached chunk */
-+static yaffs_cache_t *yaffs_find_chunk_cache(const yaffs_obj_t *obj,
-+					      int chunk_id)
-+{
-+	yaffs_dev_t *dev = obj->my_dev;
-+	int i;
-+	if (dev->param.n_caches > 0) {
-+		for (i = 0; i < dev->param.n_caches; i++) {
-+			if (dev->cache[i].object == obj &&
-+			    dev->cache[i].chunk_id == chunk_id) {
-+				dev->cache_hits++;
- 
-+				return &dev->cache[i];
-+			}
- 		}
- 	}
-+	return NULL;
- }
- 
-+/* Mark the chunk for the least recently used algorithym */
-+static void yaffs_use_cache(yaffs_dev_t *dev, yaffs_cache_t *cache,
-+				int isAWrite)
-+{
-+
-+	if (dev->param.n_caches > 0) {
-+		if (dev->cache_last_use < 0 || dev->cache_last_use > 100000000) {
-+			/* Reset the cache usages */
-+			int i;
-+			for (i = 1; i < dev->param.n_caches; i++)
-+				dev->cache[i].last_use = 0;
- 
-+			dev->cache_last_use = 0;
-+		}
- 
-+		dev->cache_last_use++;
- 
-+		cache->last_use = dev->cache_last_use;
- 
--static int ybicmp(const void *a, const void *b)
--{
--	register int aseq = ((yaffs_BlockIndex *)a)->seq;
--	register int bseq = ((yaffs_BlockIndex *)b)->seq;
--	register int ablock = ((yaffs_BlockIndex *)a)->block;
--	register int bblock = ((yaffs_BlockIndex *)b)->block;
--	if (aseq == bseq)
--		return ablock - bblock;
--	else
--		return aseq - bseq;
-+		if (isAWrite)
-+			cache->dirty = 1;
-+	}
- }
- 
-+/* Invalidate a single cache page.
-+ * Do this when a whole page gets written,
-+ * ie the short cache for this page is no longer valid.
-+ */
-+static void yaffs_invalidate_chunk_cache(yaffs_obj_t *object, int chunk_id)
-+{
-+	if (object->my_dev->param.n_caches > 0) {
-+		yaffs_cache_t *cache = yaffs_find_chunk_cache(object, chunk_id);
- 
--struct yaffs_ShadowFixerStruct {
--	int objectId;
--	int shadowedId;
--	struct yaffs_ShadowFixerStruct *next;
--};
--
-+		if (cache)
-+			cache->object = NULL;
-+	}
-+}
- 
--static void yaffs_StripDeletedObjects(yaffs_Device *dev)
-+/* Invalidate all the cache pages associated with this object
-+ * Do this whenever ther file is deleted or resized.
-+ */
-+static void yaffs_invalidate_whole_cache(yaffs_obj_t *in)
- {
--	/*
--	*  Sort out state of unlinked and deleted objects after scanning.
--	*/
--	struct ylist_head *i;
--	struct ylist_head *n;
--	yaffs_Object *l;
-+	int i;
-+	yaffs_dev_t *dev = in->my_dev;
- 
--	/* Soft delete all the unlinked files */
--	ylist_for_each_safe(i, n,
--		&dev->unlinkedDir->variant.directoryVariant.children) {
--		if (i) {
--			l = ylist_entry(i, yaffs_Object, siblings);
--			yaffs_DeleteObject(l);
-+	if (dev->param.n_caches > 0) {
-+		/* Invalidate it. */
-+		for (i = 0; i < dev->param.n_caches; i++) {
-+			if (dev->cache[i].object == in)
-+				dev->cache[i].object = NULL;
- 		}
- 	}
-+}
- 
--	ylist_for_each_safe(i, n,
--		&dev->deletedDir->variant.directoryVariant.children) {
--		if (i) {
--			l = ylist_entry(i, yaffs_Object, siblings);
--			yaffs_DeleteObject(l);
--		}
--	}
- 
--}
-+/*--------------------- File read/write ------------------------
-+ * Read and write have very similar structures.
-+ * In general the read/write has three parts to it
-+ * An incomplete chunk to start with (if the read/write is not chunk-aligned)
-+ * Some complete chunks
-+ * An incomplete chunk to end off with
-+ *
-+ * Curve-balls: the first chunk might also be the last chunk.
-+ */
- 
--static int yaffs_Scan(yaffs_Device *dev)
-+int yaffs_file_rd(yaffs_obj_t *in, __u8 *buffer, loff_t offset,
-+			int n_bytes)
- {
--	yaffs_ExtendedTags tags;
--	int blk;
--	int blockIterator;
--	int startIterator;
--	int endIterator;
--	int result;
- 
- 	int chunk;
--	int c;
--	int deleted;
--	yaffs_BlockState state;
--	yaffs_Object *hardList = NULL;
--	yaffs_BlockInfo *bi;
--	__u32 sequenceNumber;
--	yaffs_ObjectHeader *oh;
--	yaffs_Object *in;
--	yaffs_Object *parent;
-+	__u32 start;
-+	int nToCopy;
-+	int n = n_bytes;
-+	int nDone = 0;
-+	yaffs_cache_t *cache;
- 
--	int alloc_failed = 0;
-+	yaffs_dev_t *dev;
- 
--	struct yaffs_ShadowFixerStruct *shadowFixerList = NULL;
-+	dev = in->my_dev;
- 
-+	while (n > 0) {
-+		/* chunk = offset / dev->data_bytes_per_chunk + 1; */
-+		/* start = offset % dev->data_bytes_per_chunk; */
-+		yaffs_addr_to_chunk(dev, offset, &chunk, &start);
-+		chunk++;
- 
--	__u8 *chunkData;
-+		/* OK now check for the curveball where the start and end are in
-+		 * the same chunk.
-+		 */
-+		if ((start + n) < dev->data_bytes_per_chunk)
-+			nToCopy = n;
-+		else
-+			nToCopy = dev->data_bytes_per_chunk - start;
- 
-+		cache = yaffs_find_chunk_cache(in, chunk);
- 
-+		/* If the chunk is already in the cache or it is less than a whole chunk
-+		 * or we're using inband tags then use the cache (if there is caching)
-+		 * else bypass the cache.
-+		 */
-+		if (cache || nToCopy != dev->data_bytes_per_chunk || dev->param.inband_tags) {
-+			if (dev->param.n_caches > 0) {
- 
--	T(YAFFS_TRACE_SCAN,
--	  (TSTR("yaffs_Scan starts  intstartblk %d intendblk %d..." TENDSTR),
--	   dev->internalStartBlock, dev->internalEndBlock));
-+				/* If we can't find the data in the cache, then load it up. */
- 
--	chunkData = yaffs_GetTempBuffer(dev, __LINE__);
-+				if (!cache) {
-+					cache = yaffs_grab_chunk_cache(in->my_dev);
-+					cache->object = in;
-+					cache->chunk_id = chunk;
-+					cache->dirty = 0;
-+					cache->locked = 0;
-+					yaffs_rd_data_obj(in, chunk,
-+								      cache->
-+								      data);
-+					cache->n_bytes = 0;
-+				}
- 
--	dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
-+				yaffs_use_cache(dev, cache, 0);
- 
--	/* Scan all the blocks to determine their state */
--	for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
--		bi = yaffs_GetBlockInfo(dev, blk);
--		yaffs_ClearChunkBits(dev, blk);
--		bi->pagesInUse = 0;
--		bi->softDeletions = 0;
-+				cache->locked = 1;
- 
--		yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);
- 
--		bi->blockState = state;
--		bi->sequenceNumber = sequenceNumber;
-+				memcpy(buffer, &cache->data[start], nToCopy);
- 
--		if (bi->sequenceNumber == YAFFS_SEQUENCE_BAD_BLOCK)
--			bi->blockState = state = YAFFS_BLOCK_STATE_DEAD;
-+				cache->locked = 0;
-+			} else {
-+				/* Read into the local buffer then copy..*/
- 
--		T(YAFFS_TRACE_SCAN_DEBUG,
--		  (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
--		   state, sequenceNumber));
-+				__u8 *localBuffer =
-+				    yaffs_get_temp_buffer(dev, __LINE__);
-+				yaffs_rd_data_obj(in, chunk,
-+							      localBuffer);
- 
--		if (state == YAFFS_BLOCK_STATE_DEAD) {
--			T(YAFFS_TRACE_BAD_BLOCKS,
--			  (TSTR("block %d is bad" TENDSTR), blk));
--		} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
--			T(YAFFS_TRACE_SCAN_DEBUG,
--			  (TSTR("Block empty " TENDSTR)));
--			dev->nErasedBlocks++;
--			dev->nFreeChunks += dev->nChunksPerBlock;
--		}
--	}
-+				memcpy(buffer, &localBuffer[start], nToCopy);
- 
--	startIterator = dev->internalStartBlock;
--	endIterator = dev->internalEndBlock;
- 
--	/* For each block.... */
--	for (blockIterator = startIterator; !alloc_failed && blockIterator <= endIterator;
--	     blockIterator++) {
-+				yaffs_release_temp_buffer(dev, localBuffer,
-+							__LINE__);
-+			}
- 
--		YYIELD();
-+		} else {
- 
--		YYIELD();
-+			/* A full chunk. Read directly into the supplied buffer. */
-+			yaffs_rd_data_obj(in, chunk, buffer);
- 
--		blk = blockIterator;
-+		}
- 
--		bi = yaffs_GetBlockInfo(dev, blk);
--		state = bi->blockState;
-+		n -= nToCopy;
-+		offset += nToCopy;
-+		buffer += nToCopy;
-+		nDone += nToCopy;
- 
--		deleted = 0;
-+	}
- 
--		/* For each chunk in each block that needs scanning....*/
--		for (c = 0; !alloc_failed && c < dev->nChunksPerBlock &&
--		     state == YAFFS_BLOCK_STATE_NEEDS_SCANNING; c++) {
--			/* Read the tags and decide what to do */
--			chunk = blk * dev->nChunksPerBlock + c;
-+	return nDone;
-+}
- 
--			result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
--							&tags);
-+int yaffs_do_file_wr(yaffs_obj_t *in, const __u8 *buffer, loff_t offset,
-+			int n_bytes, int write_trhrough)
-+{
- 
--			/* Let's have a good look at this chunk... */
-+	int chunk;
-+	__u32 start;
-+	int nToCopy;
-+	int n = n_bytes;
-+	int nDone = 0;
-+	int nToWriteBack;
-+	int startOfWrite = offset;
-+	int chunkWritten = 0;
-+	__u32 n_bytesRead;
-+	__u32 chunkStart;
- 
--			if (tags.eccResult == YAFFS_ECC_RESULT_UNFIXED || tags.chunkDeleted) {
--				/* YAFFS1 only...
--				 * A deleted chunk
--				 */
--				deleted++;
--				dev->nFreeChunks++;
--				/*T((" %d %d deleted\n",blk,c)); */
--			} else if (!tags.chunkUsed) {
--				/* An unassigned chunk in the block
--				 * This means that either the block is empty or
--				 * this is the one being allocated from
--				 */
-+	yaffs_dev_t *dev;
- 
--				if (c == 0) {
--					/* We're looking at the first chunk in the block so the block is unused */
--					state = YAFFS_BLOCK_STATE_EMPTY;
--					dev->nErasedBlocks++;
--				} else {
--					/* this is the block being allocated from */
--					T(YAFFS_TRACE_SCAN,
--					  (TSTR
--					   (" Allocating from %d %d" TENDSTR),
--					   blk, c));
--					state = YAFFS_BLOCK_STATE_ALLOCATING;
--					dev->allocationBlock = blk;
--					dev->allocationPage = c;
--					dev->allocationBlockFinder = blk;
--					/* Set it to here to encourage the allocator to go forth from here. */
-+	dev = in->my_dev;
- 
--				}
-+	while (n > 0 && chunkWritten >= 0) {
-+		yaffs_addr_to_chunk(dev, offset, &chunk, &start);
- 
--				dev->nFreeChunks += (dev->nChunksPerBlock - c);
--			} else if (tags.chunkId > 0) {
--				/* chunkId > 0 so it is a data chunk... */
--				unsigned int endpos;
--
--				yaffs_SetChunkBit(dev, blk, c);
--				bi->pagesInUse++;
--
--				in = yaffs_FindOrCreateObjectByNumber(dev,
--								      tags.
--								      objectId,
--								      YAFFS_OBJECT_TYPE_FILE);
--				/* PutChunkIntoFile checks for a clash (two data chunks with
--				 * the same chunkId).
--				 */
-+		if (chunk * dev->data_bytes_per_chunk + start != offset ||
-+				start >= dev->data_bytes_per_chunk) {
-+			T(YAFFS_TRACE_ERROR, (
-+			   TSTR("AddrToChunk of offset %d gives chunk %d start %d"
-+			   TENDSTR),
-+			   (int)offset, chunk, start));
-+		}
-+		chunk++; /* File pos to chunk in file offset */
- 
--				if (!in)
--					alloc_failed = 1;
-+		/* OK now check for the curveball where the start and end are in
-+		 * the same chunk.
-+		 */
- 
--				if (in) {
--					if (!yaffs_PutChunkIntoFile(in, tags.chunkId, chunk, 1))
--						alloc_failed = 1;
--				}
-+		if ((start + n) < dev->data_bytes_per_chunk) {
-+			nToCopy = n;
- 
--				endpos =
--				    (tags.chunkId - 1) * dev->nDataBytesPerChunk +
--				    tags.byteCount;
--				if (in &&
--				    in->variantType == YAFFS_OBJECT_TYPE_FILE
--				    && in->variant.fileVariant.scannedFileSize <
--				    endpos) {
--					in->variant.fileVariant.
--					    scannedFileSize = endpos;
--					if (!dev->useHeaderFileSize) {
--						in->variant.fileVariant.
--						    fileSize =
--						    in->variant.fileVariant.
--						    scannedFileSize;
--					}
-+			/* Now folks, to calculate how many bytes to write back....
-+			 * If we're overwriting and not writing to then end of file then
-+			 * we need to write back as much as was there before.
-+			 */
- 
--				}
--				/* T((" %d %d data %d %d\n",blk,c,tags.objectId,tags.chunkId));   */
--			} else {
--				/* chunkId == 0, so it is an ObjectHeader.
--				 * Thus, we read in the object header and make the object
--				 */
--				yaffs_SetChunkBit(dev, blk, c);
--				bi->pagesInUse++;
-+			chunkStart = ((chunk - 1) * dev->data_bytes_per_chunk);
- 
--				result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk,
--								chunkData,
--								NULL);
--
--				oh = (yaffs_ObjectHeader *) chunkData;
--
--				in = yaffs_FindObjectByNumber(dev,
--							      tags.objectId);
--				if (in && in->variantType != oh->type) {
--					/* This should not happen, but somehow
--					 * Wev'e ended up with an objectId that has been reused but not yet
--					 * deleted, and worse still it has changed type. Delete the old object.
--					 */
-+			if (chunkStart > in->variant.file_variant.file_size)
-+				n_bytesRead = 0; /* Past end of file */
-+			else
-+				n_bytesRead = in->variant.file_variant.file_size - chunkStart;
- 
--					yaffs_DeleteObject(in);
-+			if (n_bytesRead > dev->data_bytes_per_chunk)
-+				n_bytesRead = dev->data_bytes_per_chunk;
- 
--					in = 0;
--				}
-+			nToWriteBack =
-+			    (n_bytesRead >
-+			     (start + n)) ? n_bytesRead : (start + n);
- 
--				in = yaffs_FindOrCreateObjectByNumber(dev,
--								      tags.
--								      objectId,
--								      oh->type);
--
--				if (!in)
--					alloc_failed = 1;
--
--				if (in && oh->shadowsObject > 0) {
--
--					struct yaffs_ShadowFixerStruct *fixer;
--					fixer = YMALLOC(sizeof(struct yaffs_ShadowFixerStruct));
--					if (fixer) {
--						fixer->next = shadowFixerList;
--						shadowFixerList = fixer;
--						fixer->objectId = tags.objectId;
--						fixer->shadowedId = oh->shadowsObject;
--					}
-+			if (nToWriteBack < 0 || nToWriteBack > dev->data_bytes_per_chunk)
-+				YBUG();
-+
-+		} else {
-+			nToCopy = dev->data_bytes_per_chunk - start;
-+			nToWriteBack = dev->data_bytes_per_chunk;
-+		}
-+
-+		if (nToCopy != dev->data_bytes_per_chunk || dev->param.inband_tags) {
-+			/* An incomplete start or end chunk (or maybe both start and end chunk),
-+			 * or we're using inband tags, so we want to use the cache buffers.
-+			 */
-+			if (dev->param.n_caches > 0) {
-+				yaffs_cache_t *cache;
-+				/* If we can't find the data in the cache, then load the cache */
-+				cache = yaffs_find_chunk_cache(in, chunk);
- 
-+				if (!cache
-+				    && yaffs_check_alloc_available(dev, 1)) {
-+					cache = yaffs_grab_chunk_cache(dev);
-+					cache->object = in;
-+					cache->chunk_id = chunk;
-+					cache->dirty = 0;
-+					cache->locked = 0;
-+					yaffs_rd_data_obj(in, chunk,
-+								      cache->data);
-+				} else if (cache &&
-+					!cache->dirty &&
-+					!yaffs_check_alloc_available(dev, 1)) {
-+					/* Drop the cache if it was a read cache item and
-+					 * no space check has been made for it.
-+					 */
-+					 cache = NULL;
- 				}
- 
--				if (in && in->valid) {
--					/* We have already filled this one. We have a duplicate and need to resolve it. */
-+				if (cache) {
-+					yaffs_use_cache(dev, cache, 1);
-+					cache->locked = 1;
- 
--					unsigned existingSerial = in->serial;
--					unsigned newSerial = tags.serialNumber;
- 
--					if (((existingSerial + 1) & 3) == newSerial) {
--						/* Use new one - destroy the exisiting one */
--						yaffs_DeleteChunk(dev,
--								  in->hdrChunk,
--								  1, __LINE__);
--						in->valid = 0;
--					} else {
--						/* Use existing - destroy this one. */
--						yaffs_DeleteChunk(dev, chunk, 1,
--								  __LINE__);
-+					memcpy(&cache->data[start], buffer,
-+					       nToCopy);
-+
-+
-+					cache->locked = 0;
-+					cache->n_bytes = nToWriteBack;
-+
-+					if (write_trhrough) {
-+						chunkWritten =
-+						    yaffs_wr_data_obj
-+						    (cache->object,
-+						     cache->chunk_id,
-+						     cache->data, cache->n_bytes,
-+						     1);
-+						cache->dirty = 0;
- 					}
-+
-+				} else {
-+					chunkWritten = -1;	/* fail the write */
- 				}
-+			} else {
-+				/* An incomplete start or end chunk (or maybe both start and end chunk)
-+				 * Read into the local buffer then copy, then copy over and write back.
-+				 */
- 
--				if (in && !in->valid &&
--				    (tags.objectId == YAFFS_OBJECTID_ROOT ||
--				     tags.objectId == YAFFS_OBJECTID_LOSTNFOUND)) {
--					/* We only load some info, don't fiddle with directory structure */
--					in->valid = 1;
--					in->variantType = oh->type;
-+				__u8 *localBuffer =
-+				    yaffs_get_temp_buffer(dev, __LINE__);
- 
--					in->yst_mode = oh->yst_mode;
--#ifdef CONFIG_YAFFS_WINCE
--					in->win_atime[0] = oh->win_atime[0];
--					in->win_ctime[0] = oh->win_ctime[0];
--					in->win_mtime[0] = oh->win_mtime[0];
--					in->win_atime[1] = oh->win_atime[1];
--					in->win_ctime[1] = oh->win_ctime[1];
--					in->win_mtime[1] = oh->win_mtime[1];
--#else
--					in->yst_uid = oh->yst_uid;
--					in->yst_gid = oh->yst_gid;
--					in->yst_atime = oh->yst_atime;
--					in->yst_mtime = oh->yst_mtime;
--					in->yst_ctime = oh->yst_ctime;
--					in->yst_rdev = oh->yst_rdev;
--#endif
--					in->hdrChunk = chunk;
--					in->serial = tags.serialNumber;
-+				yaffs_rd_data_obj(in, chunk,
-+							      localBuffer);
- 
--				} else if (in && !in->valid) {
--					/* we need to load this info */
- 
--					in->valid = 1;
--					in->variantType = oh->type;
- 
--					in->yst_mode = oh->yst_mode;
--#ifdef CONFIG_YAFFS_WINCE
--					in->win_atime[0] = oh->win_atime[0];
--					in->win_ctime[0] = oh->win_ctime[0];
--					in->win_mtime[0] = oh->win_mtime[0];
--					in->win_atime[1] = oh->win_atime[1];
--					in->win_ctime[1] = oh->win_ctime[1];
--					in->win_mtime[1] = oh->win_mtime[1];
--#else
--					in->yst_uid = oh->yst_uid;
--					in->yst_gid = oh->yst_gid;
--					in->yst_atime = oh->yst_atime;
--					in->yst_mtime = oh->yst_mtime;
--					in->yst_ctime = oh->yst_ctime;
--					in->yst_rdev = oh->yst_rdev;
--#endif
--					in->hdrChunk = chunk;
--					in->serial = tags.serialNumber;
-+				memcpy(&localBuffer[start], buffer, nToCopy);
- 
--					yaffs_SetObjectName(in, oh->name);
--					in->dirty = 0;
-+				chunkWritten =
-+				    yaffs_wr_data_obj(in, chunk,
-+								 localBuffer,
-+								 nToWriteBack,
-+								 0);
- 
--					/* directory stuff...
--					 * hook up to parent
--					 */
-+				yaffs_release_temp_buffer(dev, localBuffer,
-+							__LINE__);
- 
--					parent =
--					    yaffs_FindOrCreateObjectByNumber
--					    (dev, oh->parentObjectId,
--					     YAFFS_OBJECT_TYPE_DIRECTORY);
--					if (!parent)
--						alloc_failed = 1;
--					if (parent && parent->variantType ==
--					    YAFFS_OBJECT_TYPE_UNKNOWN) {
--						/* Set up as a directory */
--						parent->variantType =
--							YAFFS_OBJECT_TYPE_DIRECTORY;
--						YINIT_LIST_HEAD(&parent->variant.
--								directoryVariant.
--								children);
--					} else if (!parent || parent->variantType !=
--						   YAFFS_OBJECT_TYPE_DIRECTORY) {
--						/* Hoosterman, another problem....
--						 * We're trying to use a non-directory as a directory
--						 */
-+			}
- 
--						T(YAFFS_TRACE_ERROR,
--						  (TSTR
--						   ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
--						    TENDSTR)));
--						parent = dev->lostNFoundDir;
--					}
-+		} else {
-+			/* A full chunk. Write directly from the supplied buffer. */
- 
--					yaffs_AddObjectToDirectory(parent, in);
- 
--					if (0 && (parent == dev->deletedDir ||
--						  parent == dev->unlinkedDir)) {
--						in->deleted = 1;	/* If it is unlinked at start up then it wants deleting */
--						dev->nDeletedFiles++;
--					}
--					/* Note re hardlinks.
--					 * Since we might scan a hardlink before its equivalent object is scanned
--					 * we put them all in a list.
--					 * After scanning is complete, we should have all the objects, so we run through this
--					 * list and fix up all the chains.
--					 */
- 
--					switch (in->variantType) {
--					case YAFFS_OBJECT_TYPE_UNKNOWN:
--						/* Todo got a problem */
--						break;
--					case YAFFS_OBJECT_TYPE_FILE:
--						if (dev->useHeaderFileSize)
--
--							in->variant.fileVariant.
--							    fileSize =
--							    oh->fileSize;
--
--						break;
--					case YAFFS_OBJECT_TYPE_HARDLINK:
--						in->variant.hardLinkVariant.
--							equivalentObjectId =
--							oh->equivalentObjectId;
--						in->hardLinks.next =
--							(struct ylist_head *)
--							hardList;
--						hardList = in;
--						break;
--					case YAFFS_OBJECT_TYPE_DIRECTORY:
--						/* Do nothing */
--						break;
--					case YAFFS_OBJECT_TYPE_SPECIAL:
--						/* Do nothing */
--						break;
--					case YAFFS_OBJECT_TYPE_SYMLINK:
--						in->variant.symLinkVariant.alias =
--						    yaffs_CloneString(oh->alias);
--						if (!in->variant.symLinkVariant.alias)
--							alloc_failed = 1;
--						break;
--					}
-+			chunkWritten =
-+			    yaffs_wr_data_obj(in, chunk, buffer,
-+							 dev->data_bytes_per_chunk,
-+							 0);
- 
--/*
--					if (parent == dev->deletedDir) {
--						yaffs_DestroyObject(in);
--						bi->hasShrinkHeader = 1;
--					}
--*/
--				}
--			}
-+			/* Since we've overwritten the cached data, we better invalidate it. */
-+			yaffs_invalidate_chunk_cache(in, chunk);
- 		}
- 
--		if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
--			/* If we got this far while scanning, then the block is fully allocated.*/
--			state = YAFFS_BLOCK_STATE_FULL;
-+		if (chunkWritten >= 0) {
-+			n -= nToCopy;
-+			offset += nToCopy;
-+			buffer += nToCopy;
-+			nDone += nToCopy;
- 		}
- 
--		bi->blockState = state;
-+	}
- 
--		/* Now let's see if it was dirty */
--		if (bi->pagesInUse == 0 &&
--		    !bi->hasShrinkHeader &&
--		    bi->blockState == YAFFS_BLOCK_STATE_FULL) {
--			yaffs_BlockBecameDirty(dev, blk);
--		}
-+	/* Update file object */
- 
--	}
-+	if ((startOfWrite + nDone) > in->variant.file_variant.file_size)
-+		in->variant.file_variant.file_size = (startOfWrite + nDone);
- 
-+	in->dirty = 1;
- 
--	/* Ok, we've done all the scanning.
--	 * Fix up the hard link chains.
--	 * We should now have scanned all the objects, now it's time to add these
--	 * hardlinks.
--	 */
-+	return nDone;
-+}
- 
--	yaffs_HardlinkFixup(dev, hardList);
-+int yaffs_wr_file(yaffs_obj_t *in, const __u8 *buffer, loff_t offset,
-+			int n_bytes, int write_trhrough)
-+{
-+	yaffs2_handle_hole(in,offset);
-+	return yaffs_do_file_wr(in,buffer,offset,n_bytes,write_trhrough);
-+}
- 
--	/* Fix up any shadowed objects */
--	{
--		struct yaffs_ShadowFixerStruct *fixer;
--		yaffs_Object *obj;
--
--		while (shadowFixerList) {
--			fixer = shadowFixerList;
--			shadowFixerList = fixer->next;
--			/* Complete the rename transaction by deleting the shadowed object
--			 * then setting the object header to unshadowed.
--			 */
--			obj = yaffs_FindObjectByNumber(dev, fixer->shadowedId);
--			if (obj)
--				yaffs_DeleteObject(obj);
- 
--			obj = yaffs_FindObjectByNumber(dev, fixer->objectId);
- 
--			if (obj)
--				yaffs_UpdateObjectHeader(obj, NULL, 1, 0, 0);
-+/* ---------------------- File resizing stuff ------------------ */
- 
--			YFREE(fixer);
--		}
--	}
-+static void yaffs_prune_chunks(yaffs_obj_t *in, int new_size)
-+{
- 
--	yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
-+	yaffs_dev_t *dev = in->my_dev;
-+	int oldFileSize = in->variant.file_variant.file_size;
- 
--	if (alloc_failed)
--		return YAFFS_FAIL;
-+	int lastDel = 1 + (oldFileSize - 1) / dev->data_bytes_per_chunk;
-+
-+	int startDel = 1 + (new_size + dev->data_bytes_per_chunk - 1) /
-+	    dev->data_bytes_per_chunk;
-+	int i;
-+	int chunk_id;
- 
--	T(YAFFS_TRACE_SCAN, (TSTR("yaffs_Scan ends" TENDSTR)));
-+	/* Delete backwards so that we don't end up with holes if
-+	 * power is lost part-way through the operation.
-+	 */
-+	for (i = lastDel; i >= startDel; i--) {
-+		/* NB this could be optimised somewhat,
-+		 * eg. could retrieve the tags and write them without
-+		 * using yaffs_chunk_del
-+		 */
- 
-+		chunk_id = yaffs_find_del_file_chunk(in, i, NULL);
-+		if (chunk_id > 0) {
-+			if (chunk_id <
-+			    (dev->internal_start_block * dev->param.chunks_per_block)
-+			    || chunk_id >=
-+			    ((dev->internal_end_block +
-+			      1) * dev->param.chunks_per_block)) {
-+				T(YAFFS_TRACE_ALWAYS,
-+				  (TSTR("Found daft chunk_id %d for %d" TENDSTR),
-+				   chunk_id, i));
-+			} else {
-+				in->n_data_chunks--;
-+				yaffs_chunk_del(dev, chunk_id, 1, __LINE__);
-+			}
-+		}
-+	}
- 
--	return YAFFS_OK;
- }
- 
--static void yaffs_CheckObjectDetailsLoaded(yaffs_Object *in)
--{
--	__u8 *chunkData;
--	yaffs_ObjectHeader *oh;
--	yaffs_Device *dev;
--	yaffs_ExtendedTags tags;
--	int result;
--	int alloc_failed = 0;
- 
--	if (!in)
--		return;
-+void yaffs_resize_file_down( yaffs_obj_t *obj, loff_t new_size)
-+{
-+	int newFullChunks;
-+	__u32 new_sizeOfPartialChunk;
-+	yaffs_dev_t *dev = obj->my_dev;
- 
--	dev = in->myDev;
-+	yaffs_addr_to_chunk(dev, new_size, &newFullChunks, &new_sizeOfPartialChunk);
- 
--#if 0
--	T(YAFFS_TRACE_SCAN, (TSTR("details for object %d %s loaded" TENDSTR),
--		in->objectId,
--		in->lazyLoaded ? "not yet" : "already"));
--#endif
-+	yaffs_prune_chunks(obj, new_size);
- 
--	if (in->lazyLoaded && in->hdrChunk > 0) {
--		in->lazyLoaded = 0;
--		chunkData = yaffs_GetTempBuffer(dev, __LINE__);
-+	if (new_sizeOfPartialChunk != 0) {
-+		int lastChunk = 1 + newFullChunks;
-+		__u8 *localBuffer = yaffs_get_temp_buffer(dev, __LINE__);
- 
--		result = yaffs_ReadChunkWithTagsFromNAND(dev, in->hdrChunk, chunkData, &tags);
--		oh = (yaffs_ObjectHeader *) chunkData;
-+		/* Got to read and rewrite the last chunk with its new size and zero pad */
-+		yaffs_rd_data_obj(obj, lastChunk, localBuffer);
-+		memset(localBuffer + new_sizeOfPartialChunk, 0,
-+			dev->data_bytes_per_chunk - new_sizeOfPartialChunk);
- 
--		in->yst_mode = oh->yst_mode;
--#ifdef CONFIG_YAFFS_WINCE
--		in->win_atime[0] = oh->win_atime[0];
--		in->win_ctime[0] = oh->win_ctime[0];
--		in->win_mtime[0] = oh->win_mtime[0];
--		in->win_atime[1] = oh->win_atime[1];
--		in->win_ctime[1] = oh->win_ctime[1];
--		in->win_mtime[1] = oh->win_mtime[1];
--#else
--		in->yst_uid = oh->yst_uid;
--		in->yst_gid = oh->yst_gid;
--		in->yst_atime = oh->yst_atime;
--		in->yst_mtime = oh->yst_mtime;
--		in->yst_ctime = oh->yst_ctime;
--		in->yst_rdev = oh->yst_rdev;
-+		yaffs_wr_data_obj(obj, lastChunk, localBuffer,
-+					     new_sizeOfPartialChunk, 1);
- 
--#endif
--		yaffs_SetObjectName(in, oh->name);
-+		yaffs_release_temp_buffer(dev, localBuffer, __LINE__);
-+	}
- 
--		if (in->variantType == YAFFS_OBJECT_TYPE_SYMLINK) {
--			in->variant.symLinkVariant.alias =
--						    yaffs_CloneString(oh->alias);
--			if (!in->variant.symLinkVariant.alias)
--				alloc_failed = 1; /* Not returned to caller */
--		}
-+	obj->variant.file_variant.file_size = new_size;
- 
--		yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
--	}
-+	yaffs_prune_tree(dev, &obj->variant.file_variant);
- }
- 
--static int yaffs_ScanBackwards(yaffs_Device *dev)
--{
--	yaffs_ExtendedTags tags;
--	int blk;
--	int blockIterator;
--	int startIterator;
--	int endIterator;
--	int nBlocksToScan = 0;
--
--	int chunk;
--	int result;
--	int c;
--	int deleted;
--	yaffs_BlockState state;
--	yaffs_Object *hardList = NULL;
--	yaffs_BlockInfo *bi;
--	__u32 sequenceNumber;
--	yaffs_ObjectHeader *oh;
--	yaffs_Object *in;
--	yaffs_Object *parent;
--	int nBlocks = dev->internalEndBlock - dev->internalStartBlock + 1;
--	int itsUnlinked;
--	__u8 *chunkData;
- 
--	int fileSize;
--	int isShrink;
--	int foundChunksInBlock;
--	int equivalentObjectId;
--	int alloc_failed = 0;
-+int yaffs_resize_file(yaffs_obj_t *in, loff_t new_size)
-+{
-+	yaffs_dev_t *dev = in->my_dev;
-+	int oldFileSize = in->variant.file_variant.file_size;
- 
-+	yaffs_flush_file_cache(in);
-+	yaffs_invalidate_whole_cache(in);
- 
--	yaffs_BlockIndex *blockIndex = NULL;
--	int altBlockIndex = 0;
-+	yaffs_check_gc(dev,0);
- 
--	if (!dev->isYaffs2) {
--		T(YAFFS_TRACE_SCAN,
--		  (TSTR("yaffs_ScanBackwards is only for YAFFS2!" TENDSTR)));
-+	if (in->variant_type != YAFFS_OBJECT_TYPE_FILE)
- 		return YAFFS_FAIL;
--	}
- 
--	T(YAFFS_TRACE_SCAN,
--	  (TSTR
--	   ("yaffs_ScanBackwards starts  intstartblk %d intendblk %d..."
--	    TENDSTR), dev->internalStartBlock, dev->internalEndBlock));
-+	if (new_size == oldFileSize)
-+		return YAFFS_OK;
-+		
-+	if(new_size > oldFileSize){
-+		yaffs2_handle_hole(in,new_size);
-+		in->variant.file_variant.file_size = new_size;
-+	} else {
-+		/* new_size < oldFileSize */ 
-+		yaffs_resize_file_down(in, new_size);
-+	} 
- 
-+	/* Write a new object header to reflect the resize.
-+	 * show we've shrunk the file, if need be
-+	 * Do this only if the file is not in the deleted directories
-+	 * and is not shadowed.
-+	 */
-+	if (in->parent &&
-+	    !in->is_shadowed &&
-+	    in->parent->obj_id != YAFFS_OBJECTID_UNLINKED &&
-+	    in->parent->obj_id != YAFFS_OBJECTID_DELETED)
-+		yaffs_update_oh(in, NULL, 0, 0, 0, NULL);
- 
--	dev->sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER;
- 
--	blockIndex = YMALLOC(nBlocks * sizeof(yaffs_BlockIndex));
-+	return YAFFS_OK;
-+}
- 
--	if (!blockIndex) {
--		blockIndex = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockIndex));
--		altBlockIndex = 1;
--	}
-+loff_t yaffs_get_file_size(yaffs_obj_t *obj)
-+{
-+	YCHAR *alias = NULL;
-+	obj = yaffs_get_equivalent_obj(obj);
- 
--	if (!blockIndex) {
--		T(YAFFS_TRACE_SCAN,
--		  (TSTR("yaffs_Scan() could not allocate block index!" TENDSTR)));
--		return YAFFS_FAIL;
-+	switch (obj->variant_type) {
-+	case YAFFS_OBJECT_TYPE_FILE:
-+		return obj->variant.file_variant.file_size;
-+	case YAFFS_OBJECT_TYPE_SYMLINK:
-+		alias = obj->variant.symlink_variant.alias;
-+		if(!alias)
-+			return 0;
-+		return yaffs_strnlen(alias,YAFFS_MAX_ALIAS_LENGTH);
-+	default:
-+		return 0;
- 	}
-+}
- 
--	dev->blocksInCheckpoint = 0;
--
--	chunkData = yaffs_GetTempBuffer(dev, __LINE__);
--
--	/* Scan all the blocks to determine their state */
--	for (blk = dev->internalStartBlock; blk <= dev->internalEndBlock; blk++) {
--		bi = yaffs_GetBlockInfo(dev, blk);
--		yaffs_ClearChunkBits(dev, blk);
--		bi->pagesInUse = 0;
--		bi->softDeletions = 0;
--
--		yaffs_QueryInitialBlockState(dev, blk, &state, &sequenceNumber);
- 
--		bi->blockState = state;
--		bi->sequenceNumber = sequenceNumber;
- 
--		if (bi->sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA)
--			bi->blockState = state = YAFFS_BLOCK_STATE_CHECKPOINT;
--		if (bi->sequenceNumber == YAFFS_SEQUENCE_BAD_BLOCK)
--			bi->blockState = state = YAFFS_BLOCK_STATE_DEAD;
-+int yaffs_flush_file(yaffs_obj_t *in, int update_time, int data_sync)
-+{
-+	int retVal;
-+	if (in->dirty) {
-+		yaffs_flush_file_cache(in);
-+		if(data_sync) /* Only sync data */
-+			retVal=YAFFS_OK;
-+		else {
-+			if (update_time) {
-+#ifdef CONFIG_YAFFS_WINCE
-+				yfsd_win_file_time_now(in->win_mtime);
-+#else
- 
--		T(YAFFS_TRACE_SCAN_DEBUG,
--		  (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
--		   state, sequenceNumber));
-+				in->yst_mtime = Y_CURRENT_TIME;
- 
-+#endif
-+			}
- 
--		if (state == YAFFS_BLOCK_STATE_CHECKPOINT) {
--			dev->blocksInCheckpoint++;
-+			retVal = (yaffs_update_oh(in, NULL, 0, 0, 0, NULL) >=
-+				0) ? YAFFS_OK : YAFFS_FAIL;
-+		}
-+	} else {
-+		retVal = YAFFS_OK;
-+	}
- 
--		} else if (state == YAFFS_BLOCK_STATE_DEAD) {
--			T(YAFFS_TRACE_BAD_BLOCKS,
--			  (TSTR("block %d is bad" TENDSTR), blk));
--		} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
--			T(YAFFS_TRACE_SCAN_DEBUG,
--			  (TSTR("Block empty " TENDSTR)));
--			dev->nErasedBlocks++;
--			dev->nFreeChunks += dev->nChunksPerBlock;
--		} else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-+	return retVal;
- 
--			/* Determine the highest sequence number */
--			if (sequenceNumber >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
--			    sequenceNumber < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
-+}
- 
--				blockIndex[nBlocksToScan].seq = sequenceNumber;
--				blockIndex[nBlocksToScan].block = blk;
-+static int yaffs_generic_obj_del(yaffs_obj_t *in)
-+{
- 
--				nBlocksToScan++;
-+	/* First off, invalidate the file's data in the cache, without flushing. */
-+	yaffs_invalidate_whole_cache(in);
- 
--				if (sequenceNumber >= dev->sequenceNumber)
--					dev->sequenceNumber = sequenceNumber;
--			} else {
--				/* TODO: Nasty sequence number! */
--				T(YAFFS_TRACE_SCAN,
--				  (TSTR
--				   ("Block scanning block %d has bad sequence number %d"
--				    TENDSTR), blk, sequenceNumber));
-+	if (in->my_dev->param.is_yaffs2 && (in->parent != in->my_dev->del_dir)) {
-+		/* Move to the unlinked directory so we have a record that it was deleted. */
-+		yaffs_change_obj_name(in, in->my_dev->del_dir, _Y("deleted"), 0, 0);
- 
--			}
--		}
- 	}
- 
--	T(YAFFS_TRACE_SCAN,
--	(TSTR("%d blocks to be sorted..." TENDSTR), nBlocksToScan));
-+	yaffs_remove_obj_from_dir(in);
-+	yaffs_chunk_del(in->my_dev, in->hdr_chunk, 1, __LINE__);
-+	in->hdr_chunk = 0;
- 
-+	yaffs_free_obj(in);
-+	return YAFFS_OK;
- 
-+}
- 
--	YYIELD();
-+/* yaffs_del_file deletes the whole file data
-+ * and the inode associated with the file.
-+ * It does not delete the links associated with the file.
-+ */
-+static int yaffs_unlink_file_if_needed(yaffs_obj_t *in)
-+{
- 
--	/* Sort the blocks */
--#ifndef CONFIG_YAFFS_USE_OWN_SORT
--	{
--		/* Use qsort now. */
--		yaffs_qsort(blockIndex, nBlocksToScan, sizeof(yaffs_BlockIndex), ybicmp);
--	}
--#else
--	{
--		/* Dungy old bubble sort... */
-+	int retVal;
-+	int immediateDeletion = 0;
-+	yaffs_dev_t *dev = in->my_dev;
- 
--		yaffs_BlockIndex temp;
--		int i;
--		int j;
-+	if (!in->my_inode)
-+		immediateDeletion = 1;
- 
--		for (i = 0; i < nBlocksToScan; i++)
--			for (j = i + 1; j < nBlocksToScan; j++)
--				if (blockIndex[i].seq > blockIndex[j].seq) {
--					temp = blockIndex[j];
--					blockIndex[j] = blockIndex[i];
--					blockIndex[i] = temp;
--				}
-+	if (immediateDeletion) {
-+		retVal =
-+		    yaffs_change_obj_name(in, in->my_dev->del_dir,
-+					   _Y("deleted"), 0, 0);
-+		T(YAFFS_TRACE_TRACING,
-+		  (TSTR("yaffs: immediate deletion of file %d" TENDSTR),
-+		   in->obj_id));
-+		in->deleted = 1;
-+		in->my_dev->n_deleted_files++;
-+		if (dev->param.disable_soft_del || dev->param.is_yaffs2)
-+			yaffs_resize_file(in, 0);
-+		yaffs_soft_del_file(in);
-+	} else {
-+		retVal =
-+		    yaffs_change_obj_name(in, in->my_dev->unlinked_dir,
-+					   _Y("unlinked"), 0, 0);
- 	}
--#endif
- 
--	YYIELD();
- 
--	T(YAFFS_TRACE_SCAN, (TSTR("...done" TENDSTR)));
-+	return retVal;
-+}
- 
--	/* Now scan the blocks looking at the data. */
--	startIterator = 0;
--	endIterator = nBlocksToScan - 1;
--	T(YAFFS_TRACE_SCAN_DEBUG,
--	  (TSTR("%d blocks to be scanned" TENDSTR), nBlocksToScan));
-+int yaffs_del_file(yaffs_obj_t *in)
-+{
-+	int retVal = YAFFS_OK;
-+	int deleted; /* Need to cache value on stack if in is freed */
-+	yaffs_dev_t *dev = in->my_dev;
- 
--	/* For each block.... backwards */
--	for (blockIterator = endIterator; !alloc_failed && blockIterator >= startIterator;
--			blockIterator--) {
--		/* Cooperative multitasking! This loop can run for so
--		   long that watchdog timers expire. */
--		YYIELD();
-+	if (dev->param.disable_soft_del || dev->param.is_yaffs2)
-+		yaffs_resize_file(in, 0);
- 
--		/* get the block to scan in the correct order */
--		blk = blockIndex[blockIterator].block;
-+	if (in->n_data_chunks > 0) {
-+		/* Use soft deletion if there is data in the file.
-+		 * That won't be the case if it has been resized to zero.
-+		 */
-+		if (!in->unlinked)
-+			retVal = yaffs_unlink_file_if_needed(in);
- 
--		bi = yaffs_GetBlockInfo(dev, blk);
-+		deleted = in->deleted;
- 
-+		if (retVal == YAFFS_OK && in->unlinked && !in->deleted) {
-+			in->deleted = 1;
-+			deleted = 1;
-+			in->my_dev->n_deleted_files++;
-+			yaffs_soft_del_file(in);
-+		}
-+		return deleted ? YAFFS_OK : YAFFS_FAIL;
-+	} else {
-+		/* The file has no data chunks so we toss it immediately */
-+		yaffs_free_tnode(in->my_dev, in->variant.file_variant.top);
-+		in->variant.file_variant.top = NULL;
-+		yaffs_generic_obj_del(in);
- 
--		state = bi->blockState;
-+		return YAFFS_OK;
-+	}
-+}
- 
--		deleted = 0;
-+static int yaffs_is_non_empty_dir(yaffs_obj_t *obj)
-+{
-+	return (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) &&
-+		!(ylist_empty(&obj->variant.dir_variant.children));
-+}
- 
--		/* For each chunk in each block that needs scanning.... */
--		foundChunksInBlock = 0;
--		for (c = dev->nChunksPerBlock - 1;
--		     !alloc_failed && c >= 0 &&
--		     (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
--		      state == YAFFS_BLOCK_STATE_ALLOCATING); c--) {
--			/* Scan backwards...
--			 * Read the tags and decide what to do
--			 */
-+static int yaffs_del_dir(yaffs_obj_t *obj)
-+{
-+	/* First check that the directory is empty. */
-+	if (yaffs_is_non_empty_dir(obj))
-+		return YAFFS_FAIL;
- 
--			chunk = blk * dev->nChunksPerBlock + c;
-+	return yaffs_generic_obj_del(obj);
-+}
- 
--			result = yaffs_ReadChunkWithTagsFromNAND(dev, chunk, NULL,
--							&tags);
-+static int yaffs_del_symlink(yaffs_obj_t *in)
-+{
-+	if(in->variant.symlink_variant.alias)
-+		YFREE(in->variant.symlink_variant.alias);
-+	in->variant.symlink_variant.alias=NULL;
- 
--			/* Let's have a good look at this chunk... */
-+	return yaffs_generic_obj_del(in);
-+}
- 
--			if (!tags.chunkUsed) {
--				/* An unassigned chunk in the block.
--				 * If there are used chunks after this one, then
--				 * it is a chunk that was skipped due to failing the erased
--				 * check. Just skip it so that it can be deleted.
--				 * But, more typically, We get here when this is an unallocated
--				 * chunk and his means that either the block is empty or
--				 * this is the one being allocated from
--				 */
-+static int yaffs_del_link(yaffs_obj_t *in)
-+{
-+	/* remove this hardlink from the list assocaited with the equivalent
-+	 * object
-+	 */
-+	ylist_del_init(&in->hard_links);
-+	return yaffs_generic_obj_del(in);
-+}
- 
--				if (foundChunksInBlock) {
--					/* This is a chunk that was skipped due to failing the erased check */
--				} else if (c == 0) {
--					/* We're looking at the first chunk in the block so the block is unused */
--					state = YAFFS_BLOCK_STATE_EMPTY;
--					dev->nErasedBlocks++;
--				} else {
--					if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
--					    state == YAFFS_BLOCK_STATE_ALLOCATING) {
--						if (dev->sequenceNumber == bi->sequenceNumber) {
--							/* this is the block being allocated from */
--
--							T(YAFFS_TRACE_SCAN,
--							  (TSTR
--							   (" Allocating from %d %d"
--							    TENDSTR), blk, c));
--
--							state = YAFFS_BLOCK_STATE_ALLOCATING;
--							dev->allocationBlock = blk;
--							dev->allocationPage = c;
--							dev->allocationBlockFinder = blk;
--						} else {
--							/* This is a partially written block that is not
--							 * the current allocation block. This block must have
--							 * had a write failure, so set up for retirement.
--							 */
--
--							 /* bi->needsRetiring = 1; ??? TODO */
--							 bi->gcPrioritise = 1;
--
--							 T(YAFFS_TRACE_ALWAYS,
--							 (TSTR("Partially written block %d detected" TENDSTR),
--							 blk));
--						}
--					}
--				}
-+int yaffs_del_obj(yaffs_obj_t *obj)
-+{
-+int retVal = -1;
-+	switch (obj->variant_type) {
-+	case YAFFS_OBJECT_TYPE_FILE:
-+		retVal = yaffs_del_file(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_DIRECTORY:
-+		if(!ylist_empty(&obj->variant.dir_variant.dirty)){
-+			T(YAFFS_TRACE_BACKGROUND, (TSTR("Remove object %d from dirty directories" TENDSTR),obj->obj_id));
-+			ylist_del_init(&obj->variant.dir_variant.dirty);
-+		}
-+		return yaffs_del_dir(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_SYMLINK:
-+		retVal = yaffs_del_symlink(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_HARDLINK:
-+		retVal = yaffs_del_link(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_SPECIAL:
-+		retVal = yaffs_generic_obj_del(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_UNKNOWN:
-+		retVal = 0;
-+		break;		/* should not happen. */
-+	}
- 
--				dev->nFreeChunks++;
-+	return retVal;
-+}
- 
--			} else if (tags.eccResult == YAFFS_ECC_RESULT_UNFIXED) {
--				T(YAFFS_TRACE_SCAN,
--				  (TSTR(" Unfixed ECC in chunk(%d:%d), chunk ignored"TENDSTR),
--				  blk, c));
--
--				  dev->nFreeChunks++;
--
--			} else if (tags.chunkId > 0) {
--				/* chunkId > 0 so it is a data chunk... */
--				unsigned int endpos;
--				__u32 chunkBase =
--				    (tags.chunkId - 1) * dev->nDataBytesPerChunk;
--
--				foundChunksInBlock = 1;
--
--
--				yaffs_SetChunkBit(dev, blk, c);
--				bi->pagesInUse++;
--
--				in = yaffs_FindOrCreateObjectByNumber(dev,
--								      tags.
--								      objectId,
--								      YAFFS_OBJECT_TYPE_FILE);
--				if (!in) {
--					/* Out of memory */
--					alloc_failed = 1;
--				}
-+static int yaffs_unlink_worker(yaffs_obj_t *obj)
-+{
- 
--				if (in &&
--				    in->variantType == YAFFS_OBJECT_TYPE_FILE
--				    && chunkBase <
--				    in->variant.fileVariant.shrinkSize) {
--					/* This has not been invalidated by a resize */
--					if (!yaffs_PutChunkIntoFile(in, tags.chunkId,
--							       chunk, -1)) {
--						alloc_failed = 1;
--					}
-+	int immediateDeletion = 0;
- 
--					/* File size is calculated by looking at the data chunks if we have not
--					 * seen an object header yet. Stop this practice once we find an object header.
--					 */
--					endpos =
--					    (tags.chunkId -
--					     1) * dev->nDataBytesPerChunk +
--					    tags.byteCount;
--
--					if (!in->valid &&	/* have not got an object header yet */
--					    in->variant.fileVariant.
--					    scannedFileSize < endpos) {
--						in->variant.fileVariant.
--						    scannedFileSize = endpos;
--						in->variant.fileVariant.
--						    fileSize =
--						    in->variant.fileVariant.
--						    scannedFileSize;
--					}
-+	if (!obj->my_inode)
-+		immediateDeletion = 1;
- 
--				} else if (in) {
--					/* This chunk has been invalidated by a resize, so delete */
--					yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
-+	if(obj)
-+		yaffs_update_parent(obj->parent);
- 
--				}
--			} else {
--				/* chunkId == 0, so it is an ObjectHeader.
--				 * Thus, we read in the object header and make the object
--				 */
--				foundChunksInBlock = 1;
-+	if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) {
-+		return yaffs_del_link(obj);
-+	} else if (!ylist_empty(&obj->hard_links)) {
-+		/* Curve ball: We're unlinking an object that has a hardlink.
-+		 *
-+		 * This problem arises because we are not strictly following
-+		 * The Linux link/inode model.
-+		 *
-+		 * We can't really delete the object.
-+		 * Instead, we do the following:
-+		 * - Select a hardlink.
-+		 * - Unhook it from the hard links
-+		 * - Move it from its parent directory (so that the rename can work)
-+		 * - Rename the object to the hardlink's name.
-+		 * - Delete the hardlink
-+		 */
- 
--				yaffs_SetChunkBit(dev, blk, c);
--				bi->pagesInUse++;
-+		yaffs_obj_t *hl;
-+		yaffs_obj_t *parent;
-+		int retVal;
-+		YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
- 
--				oh = NULL;
--				in = NULL;
-+		hl = ylist_entry(obj->hard_links.next, yaffs_obj_t, hard_links);
- 
--				if (tags.extraHeaderInfoAvailable) {
--					in = yaffs_FindOrCreateObjectByNumber
--					    (dev, tags.objectId,
--					     tags.extraObjectType);
--					if (!in)
--						alloc_failed = 1;
--				}
-+		yaffs_get_obj_name(hl, name, YAFFS_MAX_NAME_LENGTH + 1);
-+		parent = hl->parent;
- 
--				if (!in ||
--#ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
--				    !in->valid ||
--#endif
--				    tags.extraShadows ||
--				    (!in->valid &&
--				    (tags.objectId == YAFFS_OBJECTID_ROOT ||
--				     tags.objectId == YAFFS_OBJECTID_LOSTNFOUND))) {
--
--					/* If we don't have  valid info then we need to read the chunk
--					 * TODO In future we can probably defer reading the chunk and
--					 * living with invalid data until needed.
--					 */
-+		ylist_del_init(&hl->hard_links);
- 
--					result = yaffs_ReadChunkWithTagsFromNAND(dev,
--									chunk,
--									chunkData,
--									NULL);
--
--					oh = (yaffs_ObjectHeader *) chunkData;
--
--					if (dev->inbandTags) {
--						/* Fix up the header if they got corrupted by inband tags */
--						oh->shadowsObject = oh->inbandShadowsObject;
--						oh->isShrink = oh->inbandIsShrink;
--					}
-+ 		yaffs_add_obj_to_dir(obj->my_dev->unlinked_dir, hl);
- 
--					if (!in) {
--						in = yaffs_FindOrCreateObjectByNumber(dev, tags.objectId, oh->type);
--						if (!in)
--							alloc_failed = 1;
--					}
-+		retVal = yaffs_change_obj_name(obj,parent, name, 0, 0);
- 
--				}
-+		if (retVal == YAFFS_OK)
-+			retVal = yaffs_generic_obj_del(hl);
- 
--				if (!in) {
--					/* TODO Hoosterman we have a problem! */
--					T(YAFFS_TRACE_ERROR,
--					  (TSTR
--					   ("yaffs tragedy: Could not make object for object  %d at chunk %d during scan"
--					    TENDSTR), tags.objectId, chunk));
--					continue;
--				}
-+		return retVal;
- 
--				if (in->valid) {
--					/* We have already filled this one.
--					 * We have a duplicate that will be discarded, but
--					 * we first have to suck out resize info if it is a file.
--					 */
-+	} else if (immediateDeletion) {
-+		switch (obj->variant_type) {
-+		case YAFFS_OBJECT_TYPE_FILE:
-+			return yaffs_del_file(obj);
-+			break;
-+		case YAFFS_OBJECT_TYPE_DIRECTORY:
-+			ylist_del_init(&obj->variant.dir_variant.dirty);
-+			return yaffs_del_dir(obj);
-+			break;
-+		case YAFFS_OBJECT_TYPE_SYMLINK:
-+			return yaffs_del_symlink(obj);
-+			break;
-+		case YAFFS_OBJECT_TYPE_SPECIAL:
-+			return yaffs_generic_obj_del(obj);
-+			break;
-+		case YAFFS_OBJECT_TYPE_HARDLINK:
-+		case YAFFS_OBJECT_TYPE_UNKNOWN:
-+		default:
-+			return YAFFS_FAIL;
-+		}
-+	} else if(yaffs_is_non_empty_dir(obj))
-+		return YAFFS_FAIL;
-+	else
-+		return yaffs_change_obj_name(obj, obj->my_dev->unlinked_dir,
-+					   _Y("unlinked"), 0, 0);
-+}
- 
--					if ((in->variantType == YAFFS_OBJECT_TYPE_FILE) &&
--					     ((oh &&
--					       oh->type == YAFFS_OBJECT_TYPE_FILE) ||
--					      (tags.extraHeaderInfoAvailable  &&
--					       tags.extraObjectType == YAFFS_OBJECT_TYPE_FILE))) {
--						__u32 thisSize =
--						    (oh) ? oh->fileSize : tags.
--						    extraFileLength;
--						__u32 parentObjectId =
--						    (oh) ? oh->
--						    parentObjectId : tags.
--						    extraParentObjectId;
--
--
--						isShrink =
--						    (oh) ? oh->isShrink : tags.
--						    extraIsShrinkHeader;
- 
--						/* If it is deleted (unlinked at start also means deleted)
--						 * we treat the file size as being zeroed at this point.
--						 */
--						if (parentObjectId ==
--						    YAFFS_OBJECTID_DELETED
--						    || parentObjectId ==
--						    YAFFS_OBJECTID_UNLINKED) {
--							thisSize = 0;
--							isShrink = 1;
--						}
-+static int yaffs_unlink_obj(yaffs_obj_t *obj)
-+{
- 
--						if (isShrink &&
--						    in->variant.fileVariant.
--						    shrinkSize > thisSize) {
--							in->variant.fileVariant.
--							    shrinkSize =
--							    thisSize;
--						}
-+	if (obj && obj->unlink_allowed)
-+		return yaffs_unlink_worker(obj);
- 
--						if (isShrink)
--							bi->hasShrinkHeader = 1;
-+	return YAFFS_FAIL;
- 
--					}
--					/* Use existing - destroy this one. */
--					yaffs_DeleteChunk(dev, chunk, 1, __LINE__);
-+}
-+int yaffs_unlinker(yaffs_obj_t *dir, const YCHAR *name)
-+{
-+	yaffs_obj_t *obj;
- 
--				}
-+	obj = yaffs_find_by_name(dir, name);
-+	return yaffs_unlink_obj(obj);
-+}
- 
--				if (!in->valid && in->variantType !=
--				    (oh ? oh->type : tags.extraObjectType))
--					T(YAFFS_TRACE_ERROR, (
--						TSTR("yaffs tragedy: Bad object type, "
--					    TCONT("%d != %d, for object %d at chunk ")
--					    TCONT("%d during scan")
--						TENDSTR), oh ?
--					    oh->type : tags.extraObjectType,
--					    in->variantType, tags.objectId,
--					    chunk));
--
--				if (!in->valid &&
--				    (tags.objectId == YAFFS_OBJECTID_ROOT ||
--				     tags.objectId ==
--				     YAFFS_OBJECTID_LOSTNFOUND)) {
--					/* We only load some info, don't fiddle with directory structure */
--					in->valid = 1;
-+/*----------------------- Initialisation Scanning ---------------------- */
- 
--					if (oh) {
--						in->variantType = oh->type;
-+void yaffs_handle_shadowed_obj(yaffs_dev_t *dev, int obj_id,
-+				int backward_scanning)
-+{
-+	yaffs_obj_t *obj;
- 
--						in->yst_mode = oh->yst_mode;
--#ifdef CONFIG_YAFFS_WINCE
--						in->win_atime[0] = oh->win_atime[0];
--						in->win_ctime[0] = oh->win_ctime[0];
--						in->win_mtime[0] = oh->win_mtime[0];
--						in->win_atime[1] = oh->win_atime[1];
--						in->win_ctime[1] = oh->win_ctime[1];
--						in->win_mtime[1] = oh->win_mtime[1];
--#else
--						in->yst_uid = oh->yst_uid;
--						in->yst_gid = oh->yst_gid;
--						in->yst_atime = oh->yst_atime;
--						in->yst_mtime = oh->yst_mtime;
--						in->yst_ctime = oh->yst_ctime;
--						in->yst_rdev = oh->yst_rdev;
-+	if (!backward_scanning) {
-+		/* Handle YAFFS1 forward scanning case
-+		 * For YAFFS1 we always do the deletion
-+		 */
- 
--#endif
--					} else {
--						in->variantType = tags.extraObjectType;
--						in->lazyLoaded = 1;
--					}
-+	} else {
-+		/* Handle YAFFS2 case (backward scanning)
-+		 * If the shadowed object exists then ignore.
-+		 */
-+		obj = yaffs_find_by_number(dev, obj_id);
-+		if(obj)
-+			return;
-+	}
- 
--					in->hdrChunk = chunk;
-+	/* Let's create it (if it does not exist) assuming it is a file so that it can do shrinking etc.
-+	 * We put it in unlinked dir to be cleaned up after the scanning
-+	 */
-+	obj =
-+	    yaffs_find_or_create_by_number(dev, obj_id,
-+					     YAFFS_OBJECT_TYPE_FILE);
-+	if (!obj)
-+		return;
-+	obj->is_shadowed = 1;
-+	yaffs_add_obj_to_dir(dev->unlinked_dir, obj);
-+	obj->variant.file_variant.shrink_size = 0;
-+	obj->valid = 1;		/* So that we don't read any other info for this file */
- 
--				} else if (!in->valid) {
--					/* we need to load this info */
-+}
- 
--					in->valid = 1;
--					in->hdrChunk = chunk;
- 
--					if (oh) {
--						in->variantType = oh->type;
-+void yaffs_link_fixup(yaffs_dev_t *dev, yaffs_obj_t *hard_list)
-+{
-+	yaffs_obj_t *hl;
-+	yaffs_obj_t *in;
- 
--						in->yst_mode = oh->yst_mode;
--#ifdef CONFIG_YAFFS_WINCE
--						in->win_atime[0] = oh->win_atime[0];
--						in->win_ctime[0] = oh->win_ctime[0];
--						in->win_mtime[0] = oh->win_mtime[0];
--						in->win_atime[1] = oh->win_atime[1];
--						in->win_ctime[1] = oh->win_ctime[1];
--						in->win_mtime[1] = oh->win_mtime[1];
--#else
--						in->yst_uid = oh->yst_uid;
--						in->yst_gid = oh->yst_gid;
--						in->yst_atime = oh->yst_atime;
--						in->yst_mtime = oh->yst_mtime;
--						in->yst_ctime = oh->yst_ctime;
--						in->yst_rdev = oh->yst_rdev;
--#endif
-+	while (hard_list) {
-+		hl = hard_list;
-+		hard_list = (yaffs_obj_t *) (hard_list->hard_links.next);
-+
-+		in = yaffs_find_by_number(dev,
-+					      hl->variant.hardlink_variant.
-+					      equiv_id);
- 
--						if (oh->shadowsObject > 0)
--							yaffs_HandleShadowedObject(dev,
--									   oh->
--									   shadowsObject,
--									   1);
--
--
--						yaffs_SetObjectName(in, oh->name);
--						parent =
--						    yaffs_FindOrCreateObjectByNumber
--							(dev, oh->parentObjectId,
--							 YAFFS_OBJECT_TYPE_DIRECTORY);
--
--						 fileSize = oh->fileSize;
--						 isShrink = oh->isShrink;
--						 equivalentObjectId = oh->equivalentObjectId;
-+		if (in) {
-+			/* Add the hardlink pointers */
-+			hl->variant.hardlink_variant.equiv_obj = in;
-+			ylist_add(&hl->hard_links, &in->hard_links);
-+		} else {
-+			/* Todo Need to report/handle this better.
-+			 * Got a problem... hardlink to a non-existant object
-+			 */
-+			hl->variant.hardlink_variant.equiv_obj = NULL;
-+			YINIT_LIST_HEAD(&hl->hard_links);
- 
--					} else {
--						in->variantType = tags.extraObjectType;
--						parent =
--						    yaffs_FindOrCreateObjectByNumber
--							(dev, tags.extraParentObjectId,
--							 YAFFS_OBJECT_TYPE_DIRECTORY);
--						 fileSize = tags.extraFileLength;
--						 isShrink = tags.extraIsShrinkHeader;
--						 equivalentObjectId = tags.extraEquivalentObjectId;
--						in->lazyLoaded = 1;
-+		}
-+	}
-+}
- 
--					}
--					in->dirty = 0;
- 
--					if (!parent)
--						alloc_failed = 1;
-+static void yaffs_strip_deleted_objs(yaffs_dev_t *dev)
-+{
-+	/*
-+	*  Sort out state of unlinked and deleted objects after scanning.
-+	*/
-+	struct ylist_head *i;
-+	struct ylist_head *n;
-+	yaffs_obj_t *l;
- 
--					/* directory stuff...
--					 * hook up to parent
--					 */
-+	if (dev->read_only)
-+		return;
- 
--					if (parent && parent->variantType ==
--					    YAFFS_OBJECT_TYPE_UNKNOWN) {
--						/* Set up as a directory */
--						parent->variantType =
--							YAFFS_OBJECT_TYPE_DIRECTORY;
--						YINIT_LIST_HEAD(&parent->variant.
--							directoryVariant.
--							children);
--					} else if (!parent || parent->variantType !=
--						   YAFFS_OBJECT_TYPE_DIRECTORY) {
--						/* Hoosterman, another problem....
--						 * We're trying to use a non-directory as a directory
--						 */
-+	/* Soft delete all the unlinked files */
-+	ylist_for_each_safe(i, n,
-+		&dev->unlinked_dir->variant.dir_variant.children) {
-+		if (i) {
-+			l = ylist_entry(i, yaffs_obj_t, siblings);
-+			yaffs_del_obj(l);
-+		}
-+	}
- 
--						T(YAFFS_TRACE_ERROR,
--						  (TSTR
--						   ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
--						    TENDSTR)));
--						parent = dev->lostNFoundDir;
--					}
-+	ylist_for_each_safe(i, n,
-+		&dev->del_dir->variant.dir_variant.children) {
-+		if (i) {
-+			l = ylist_entry(i, yaffs_obj_t, siblings);
-+			yaffs_del_obj(l);
-+		}
-+	}
- 
--					yaffs_AddObjectToDirectory(parent, in);
-+}
- 
--					itsUnlinked = (parent == dev->deletedDir) ||
--						      (parent == dev->unlinkedDir);
-+/*
-+ * This code iterates through all the objects making sure that they are rooted.
-+ * Any unrooted objects are re-rooted in lost+found.
-+ * An object needs to be in one of:
-+ * - Directly under deleted, unlinked
-+ * - Directly or indirectly under root.
-+ *
-+ * Note:
-+ *  This code assumes that we don't ever change the current relationships between
-+ *  directories:
-+ *   root_dir->parent == unlinked_dir->parent == del_dir->parent == NULL
-+ *   lostNfound->parent == root_dir
-+ *
-+ * This fixes the problem where directories might have inadvertently been deleted
-+ * leaving the object "hanging" without being rooted in the directory tree.
-+ */
-+ 
-+static int yaffs_has_null_parent(yaffs_dev_t *dev, yaffs_obj_t *obj)
-+{
-+	return (obj == dev->del_dir ||
-+		obj == dev->unlinked_dir||
-+		obj == dev->root_dir);
-+}
- 
--					if (isShrink) {
--						/* Mark the block as having a shrinkHeader */
--						bi->hasShrinkHeader = 1;
--					}
-+static void yaffs_fix_hanging_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_obj_t *parent;
-+	int i;
-+	struct ylist_head *lh;
-+	struct ylist_head *n;
-+	int depthLimit;
-+	int hanging;
- 
--					/* Note re hardlinks.
--					 * Since we might scan a hardlink before its equivalent object is scanned
--					 * we put them all in a list.
--					 * After scanning is complete, we should have all the objects, so we run
--					 * through this list and fix up all the chains.
--					 */
-+	if (dev->read_only)
-+		return;
- 
--					switch (in->variantType) {
--					case YAFFS_OBJECT_TYPE_UNKNOWN:
--						/* Todo got a problem */
--						break;
--					case YAFFS_OBJECT_TYPE_FILE:
--
--						if (in->variant.fileVariant.
--						    scannedFileSize < fileSize) {
--							/* This covers the case where the file size is greater
--							 * than where the data is
--							 * This will happen if the file is resized to be larger
--							 * than its current data extents.
--							 */
--							in->variant.fileVariant.fileSize = fileSize;
--							in->variant.fileVariant.scannedFileSize =
--							    in->variant.fileVariant.fileSize;
--						}
-+	/* Iterate through the objects in each hash entry,
-+	 * looking at each object.
-+	 * Make sure it is rooted.
-+	 */
- 
--						if (isShrink &&
--						    in->variant.fileVariant.shrinkSize > fileSize) {
--							in->variant.fileVariant.shrinkSize = fileSize;
--						}
-+	for (i = 0; i <  YAFFS_NOBJECT_BUCKETS; i++) {
-+		ylist_for_each_safe(lh, n, &dev->obj_bucket[i].list) {
-+			if (lh) {
-+				obj = ylist_entry(lh, yaffs_obj_t, hash_link);
-+				parent= obj->parent;
-+				
-+				if(yaffs_has_null_parent(dev,obj)){
-+					/* These directories are not hanging */
-+					hanging = 0;
-+				}
-+				else if(!parent || parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-+					hanging = 1;
-+				else if(yaffs_has_null_parent(dev,parent))
-+					hanging = 0;
-+				else {
-+					/*
-+					 * Need to follow the parent chain to see if it is hanging.
-+					 */
-+					hanging = 0;
-+					depthLimit=100;
- 
--						break;
--					case YAFFS_OBJECT_TYPE_HARDLINK:
--						if (!itsUnlinked) {
--							in->variant.hardLinkVariant.equivalentObjectId =
--								equivalentObjectId;
--							in->hardLinks.next =
--								(struct ylist_head *) hardList;
--							hardList = in;
--						}
--						break;
--					case YAFFS_OBJECT_TYPE_DIRECTORY:
--						/* Do nothing */
--						break;
--					case YAFFS_OBJECT_TYPE_SPECIAL:
--						/* Do nothing */
--						break;
--					case YAFFS_OBJECT_TYPE_SYMLINK:
--						if (oh) {
--							in->variant.symLinkVariant.alias =
--								yaffs_CloneString(oh->alias);
--							if (!in->variant.symLinkVariant.alias)
--								alloc_failed = 1;
--						}
--						break;
-+					while(parent != dev->root_dir &&
-+						parent->parent &&
-+						parent->parent->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY &&
-+						depthLimit > 0){
-+						parent = parent->parent;
-+						depthLimit--;
- 					}
--
-+					if(parent != dev->root_dir)
-+						hanging = 1;
-+				}
-+				if(hanging){
-+					T(YAFFS_TRACE_SCAN,
-+					  (TSTR("Hanging object %d moved to lost and found" TENDSTR),
-+					  	obj->obj_id));
-+					yaffs_add_obj_to_dir(dev->lost_n_found,obj);
- 				}
--
- 			}
-+		}
-+	}
-+}
- 
--		} /* End of scanning for each chunk */
- 
--		if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
--			/* If we got this far while scanning, then the block is fully allocated. */
--			state = YAFFS_BLOCK_STATE_FULL;
--		}
-+/*
-+ * Delete directory contents for cleaning up lost and found.
-+ */
-+static void yaffs_del_dir_contents(yaffs_obj_t *dir)
-+{
-+	yaffs_obj_t *obj;
-+	struct ylist_head *lh;
-+	struct ylist_head *n;
- 
--		bi->blockState = state;
-+	if(dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
-+		YBUG();
-+	
-+	ylist_for_each_safe(lh, n, &dir->variant.dir_variant.children) {
-+		if (lh) {
-+			obj = ylist_entry(lh, yaffs_obj_t, siblings);
-+			if(obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
-+				yaffs_del_dir_contents(obj);
-+
-+			T(YAFFS_TRACE_SCAN,
-+				(TSTR("Deleting lost_found object %d" TENDSTR),
-+				obj->obj_id));
- 
--		/* Now let's see if it was dirty */
--		if (bi->pagesInUse == 0 &&
--		    !bi->hasShrinkHeader &&
--		    bi->blockState == YAFFS_BLOCK_STATE_FULL) {
--			yaffs_BlockBecameDirty(dev, blk);
-+			/* Need to use UnlinkObject since Delete would not handle
-+			 * hardlinked objects correctly.
-+			 */
-+			yaffs_unlink_obj(obj); 
- 		}
--
- 	}
-+			
-+}
- 
--	if (altBlockIndex)
--		YFREE_ALT(blockIndex);
--	else
--		YFREE(blockIndex);
-+static void yaffs_empty_l_n_f(yaffs_dev_t *dev)
-+{
-+	yaffs_del_dir_contents(dev->lost_n_found);
-+}
- 
--	/* Ok, we've done all the scanning.
--	 * Fix up the hard link chains.
--	 * We should now have scanned all the objects, now it's time to add these
--	 * hardlinks.
--	 */
--	yaffs_HardlinkFixup(dev, hardList);
-+static void yaffs_check_obj_details_loaded(yaffs_obj_t *in)
-+{
-+	__u8 *chunkData;
-+	yaffs_obj_header *oh;
-+	yaffs_dev_t *dev;
-+	yaffs_ext_tags tags;
-+	int result;
-+	int alloc_failed = 0;
- 
-+	if (!in)
-+		return;
- 
--	yaffs_ReleaseTempBuffer(dev, chunkData, __LINE__);
-+	dev = in->my_dev;
- 
--	if (alloc_failed)
--		return YAFFS_FAIL;
-+#if 0
-+	T(YAFFS_TRACE_SCAN, (TSTR("details for object %d %s loaded" TENDSTR),
-+		in->obj_id,
-+		in->lazy_loaded ? "not yet" : "already"));
-+#endif
- 
--	T(YAFFS_TRACE_SCAN, (TSTR("yaffs_ScanBackwards ends" TENDSTR)));
-+	if (in->lazy_loaded && in->hdr_chunk > 0) {
-+		in->lazy_loaded = 0;
-+		chunkData = yaffs_get_temp_buffer(dev, __LINE__);
- 
--	return YAFFS_OK;
--}
-+		result = yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, chunkData, &tags);
-+		oh = (yaffs_obj_header *) chunkData;
- 
--/*------------------------------  Directory Functions ----------------------------- */
-+		in->yst_mode = oh->yst_mode;
-+#ifdef CONFIG_YAFFS_WINCE
-+		in->win_atime[0] = oh->win_atime[0];
-+		in->win_ctime[0] = oh->win_ctime[0];
-+		in->win_mtime[0] = oh->win_mtime[0];
-+		in->win_atime[1] = oh->win_atime[1];
-+		in->win_ctime[1] = oh->win_ctime[1];
-+		in->win_mtime[1] = oh->win_mtime[1];
-+#else
-+		in->yst_uid = oh->yst_uid;
-+		in->yst_gid = oh->yst_gid;
-+		in->yst_atime = oh->yst_atime;
-+		in->yst_mtime = oh->yst_mtime;
-+		in->yst_ctime = oh->yst_ctime;
-+		in->yst_rdev = oh->yst_rdev;
- 
--static void yaffs_VerifyObjectInDirectory(yaffs_Object *obj)
--{
--	struct ylist_head *lh;
--	yaffs_Object *listObj;
-+#endif
-+		yaffs_set_obj_name_from_oh(in, oh);
- 
--	int count = 0;
-+		if (in->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
-+			in->variant.symlink_variant.alias =
-+						    yaffs_clone_str(oh->alias);
-+			if (!in->variant.symlink_variant.alias)
-+				alloc_failed = 1; /* Not returned to caller */
-+		}
- 
--	if (!obj) {
--		T(YAFFS_TRACE_ALWAYS, (TSTR("No object to verify" TENDSTR)));
--		YBUG();
--		return;
-+		yaffs_release_temp_buffer(dev, chunkData, __LINE__);
- 	}
-+}
- 
--	if (yaffs_SkipVerification(obj->myDev))
--		return;
-+/*------------------------------  Directory Functions ----------------------------- */
- 
--	if (!obj->parent) {
--		T(YAFFS_TRACE_ALWAYS, (TSTR("Object does not have parent" TENDSTR)));
--		YBUG();
-+/*
-+ *yaffs_update_parent() handles fixing a directories mtime and ctime when a new
-+ * link (ie. name) is created or deleted in the directory.
-+ *
-+ * ie.
-+ *   create dir/a : update dir's mtime/ctime
-+ *   rm dir/a:   update dir's mtime/ctime
-+ *   modify dir/a: don't update dir's mtimme/ctime
-+ *
-+ * This can be handled immediately or defered. Defering helps reduce the number
-+ * of updates when many files in a directory are changed within a brief period.
-+ *
-+ * If the directory updating is defered then yaffs_update_dirty_dirs must be
-+ * called periodically.
-+ */
-+ 
-+static void yaffs_update_parent(yaffs_obj_t *obj)
-+{
-+	yaffs_dev_t *dev;
-+	if(!obj)
- 		return;
--	}
--
--	if (obj->parent->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
--		T(YAFFS_TRACE_ALWAYS, (TSTR("Parent is not directory" TENDSTR)));
--		YBUG();
--	}
--
--	/* Iterate through the objects in each hash entry */
-+#ifndef CONFIG_YAFFS_WINCE
- 
--	ylist_for_each(lh, &obj->parent->variant.directoryVariant.children) {
--		if (lh) {
--			listObj = ylist_entry(lh, yaffs_Object, siblings);
--			yaffs_VerifyObject(listObj);
--			if (obj == listObj)
--				count++;
-+	dev = obj->my_dev;
-+	obj->dirty = 1;
-+	obj->yst_mtime = obj->yst_ctime = Y_CURRENT_TIME;
-+	if(dev->param.defered_dir_update){
-+		struct ylist_head *link = &obj->variant.dir_variant.dirty; 
-+	
-+		if(ylist_empty(link)){
-+			ylist_add(link,&dev->dirty_dirs);
-+			T(YAFFS_TRACE_BACKGROUND, (TSTR("Added object %d to dirty directories" TENDSTR),obj->obj_id));
- 		}
--	 }
- 
--	if (count != 1) {
--		T(YAFFS_TRACE_ALWAYS, (TSTR("Object in directory %d times" TENDSTR), count));
--		YBUG();
--	}
-+	} else
-+		yaffs_update_oh(obj, NULL, 0, 0, 0, NULL);
-+#endif
- }
- 
--static void yaffs_VerifyDirectory(yaffs_Object *directory)
-+void yaffs_update_dirty_dirs(yaffs_dev_t *dev)
- {
--	struct ylist_head *lh;
--	yaffs_Object *listObj;
--
--	if (!directory) {
--		YBUG();
--		return;
--	}
-+	struct ylist_head *link;
-+	yaffs_obj_t *obj;
-+	yaffs_dir_s *dS;
-+	yaffs_obj_variant *oV;
- 
--	if (yaffs_SkipFullVerification(directory->myDev))
--		return;
-+	T(YAFFS_TRACE_BACKGROUND, (TSTR("Update dirty directories" TENDSTR)));
- 
--	if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
--		T(YAFFS_TRACE_ALWAYS, (TSTR("Directory has wrong type: %d" TENDSTR), directory->variantType));
--		YBUG();
--	}
-+	while(!ylist_empty(&dev->dirty_dirs)){
-+		link = dev->dirty_dirs.next;
-+		ylist_del_init(link);
-+		
-+		dS=ylist_entry(link,yaffs_dir_s,dirty);
-+		oV = ylist_entry(dS,yaffs_obj_variant,dir_variant);
-+		obj = ylist_entry(oV,yaffs_obj_t,variant);
- 
--	/* Iterate through the objects in each hash entry */
-+		T(YAFFS_TRACE_BACKGROUND, (TSTR("Update directory %d" TENDSTR), obj->obj_id));
- 
--	ylist_for_each(lh, &directory->variant.directoryVariant.children) {
--		if (lh) {
--			listObj = ylist_entry(lh, yaffs_Object, siblings);
--			if (listObj->parent != directory) {
--				T(YAFFS_TRACE_ALWAYS, (TSTR("Object in directory list has wrong parent %p" TENDSTR), listObj->parent));
--				YBUG();
--			}
--			yaffs_VerifyObjectInDirectory(listObj);
--		}
-+		if(obj->dirty)
-+			yaffs_update_oh(obj, NULL, 0, 0, 0, NULL);
- 	}
- }
- 
--
--static void yaffs_RemoveObjectFromDirectory(yaffs_Object *obj)
-+static void yaffs_remove_obj_from_dir(yaffs_obj_t *obj)
- {
--	yaffs_Device *dev = obj->myDev;
--	yaffs_Object *parent;
-+	yaffs_dev_t *dev = obj->my_dev;
-+	yaffs_obj_t *parent;
- 
--	yaffs_VerifyObjectInDirectory(obj);
-+	yaffs_verify_obj_in_dir(obj);
- 	parent = obj->parent;
- 
--	yaffs_VerifyDirectory(parent);
-+	yaffs_verify_dir(parent);
- 
--	if (dev && dev->removeObjectCallback)
--		dev->removeObjectCallback(obj);
-+	if (dev && dev->param.remove_obj_fn)
-+		dev->param.remove_obj_fn(obj);
- 
- 
- 	ylist_del_init(&obj->siblings);
- 	obj->parent = NULL;
--
--	yaffs_VerifyDirectory(parent);
-+	
-+	yaffs_verify_dir(parent);
- }
- 
--
--static void yaffs_AddObjectToDirectory(yaffs_Object *directory,
--					yaffs_Object *obj)
-+void yaffs_add_obj_to_dir(yaffs_obj_t *directory,
-+					yaffs_obj_t *obj)
- {
- 	if (!directory) {
- 		T(YAFFS_TRACE_ALWAYS,
-@@ -6699,7 +4495,7 @@ static void yaffs_AddObjectToDirectory(y
- 		YBUG();
- 		return;
- 	}
--	if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+	if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
- 		   ("tragedy: Trying to add an object to a non-directory"
-@@ -6713,27 +4509,27 @@ static void yaffs_AddObjectToDirectory(y
- 	}
- 
- 
--	yaffs_VerifyDirectory(directory);
-+	yaffs_verify_dir(directory);
- 
--	yaffs_RemoveObjectFromDirectory(obj);
-+	yaffs_remove_obj_from_dir(obj);
- 
- 
- 	/* Now add it */
--	ylist_add(&obj->siblings, &directory->variant.directoryVariant.children);
-+	ylist_add(&obj->siblings, &directory->variant.dir_variant.children);
- 	obj->parent = directory;
- 
--	if (directory == obj->myDev->unlinkedDir
--			|| directory == obj->myDev->deletedDir) {
-+	if (directory == obj->my_dev->unlinked_dir
-+			|| directory == obj->my_dev->del_dir) {
- 		obj->unlinked = 1;
--		obj->myDev->nUnlinkedFiles++;
--		obj->renameAllowed = 0;
-+		obj->my_dev->n_unlinked_files++;
-+		obj->rename_allowed = 0;
- 	}
- 
--	yaffs_VerifyDirectory(directory);
--	yaffs_VerifyObjectInDirectory(obj);
-+	yaffs_verify_dir(directory);
-+	yaffs_verify_obj_in_dir(obj);
- }
- 
--yaffs_Object *yaffs_FindObjectByName(yaffs_Object *directory,
-+yaffs_obj_t *yaffs_find_by_name(yaffs_obj_t *directory,
- 				     const YCHAR *name)
- {
- 	int sum;
-@@ -6741,7 +4537,7 @@ yaffs_Object *yaffs_FindObjectByName(yaf
- 	struct ylist_head *i;
- 	YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1];
- 
--	yaffs_Object *l;
-+	yaffs_obj_t *l;
- 
- 	if (!name)
- 		return NULL;
-@@ -6749,39 +4545,39 @@ yaffs_Object *yaffs_FindObjectByName(yaf
- 	if (!directory) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
--		   ("tragedy: yaffs_FindObjectByName: null pointer directory"
-+		   ("tragedy: yaffs_find_by_name: null pointer directory"
- 		    TENDSTR)));
- 		YBUG();
- 		return NULL;
- 	}
--	if (directory->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+	if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
--		   ("tragedy: yaffs_FindObjectByName: non-directory" TENDSTR)));
-+		   ("tragedy: yaffs_find_by_name: non-directory" TENDSTR)));
- 		YBUG();
- 	}
- 
--	sum = yaffs_CalcNameSum(name);
-+	sum = yaffs_calc_name_sum(name);
- 
--	ylist_for_each(i, &directory->variant.directoryVariant.children) {
-+	ylist_for_each(i, &directory->variant.dir_variant.children) {
- 		if (i) {
--			l = ylist_entry(i, yaffs_Object, siblings);
-+			l = ylist_entry(i, yaffs_obj_t, siblings);
- 
- 			if (l->parent != directory)
- 				YBUG();
- 
--			yaffs_CheckObjectDetailsLoaded(l);
-+			yaffs_check_obj_details_loaded(l);
- 
- 			/* Special case for lost-n-found */
--			if (l->objectId == YAFFS_OBJECTID_LOSTNFOUND) {
-+			if (l->obj_id == YAFFS_OBJECTID_LOSTNFOUND) {
- 				if (yaffs_strcmp(name, YAFFS_LOSTNFOUND_NAME) == 0)
- 					return l;
--			} else if (yaffs_SumCompare(l->sum, sum) || l->hdrChunk <= 0) {
-+			} else if (yaffs_sum_cmp(l->sum, sum) || l->hdr_chunk <= 0) {
- 				/* LostnFound chunk called Objxxx
- 				 * Do a real check
- 				 */
--				yaffs_GetObjectName(l, buffer,
--						    YAFFS_MAX_NAME_LENGTH);
-+				yaffs_get_obj_name(l, buffer,
-+						    YAFFS_MAX_NAME_LENGTH + 1);
- 				if (yaffs_strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH) == 0)
- 					return l;
- 			}
-@@ -6793,31 +4589,31 @@ yaffs_Object *yaffs_FindObjectByName(yaf
- 
- 
- #if 0
--int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,
--					int (*fn) (yaffs_Object *))
-+int yaffs_ApplyToDirectoryChildren(yaffs_obj_t *the_dir,
-+					int (*fn) (yaffs_obj_t *))
- {
- 	struct ylist_head *i;
--	yaffs_Object *l;
-+	yaffs_obj_t *l;
- 
--	if (!theDir) {
-+	if (!the_dir) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
--		   ("tragedy: yaffs_FindObjectByName: null pointer directory"
-+		   ("tragedy: yaffs_find_by_name: null pointer directory"
- 		    TENDSTR)));
- 		YBUG();
- 		return YAFFS_FAIL;
- 	}
--	if (theDir->variantType != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+	if (the_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
--		   ("tragedy: yaffs_FindObjectByName: non-directory" TENDSTR)));
-+		   ("tragedy: yaffs_find_by_name: non-directory" TENDSTR)));
- 		YBUG();
- 		return YAFFS_FAIL;
- 	}
- 
--	ylist_for_each(i, &theDir->variant.directoryVariant.children) {
-+	ylist_for_each(i, &the_dir->variant.dir_variant.children) {
- 		if (i) {
--			l = ylist_entry(i, yaffs_Object, siblings);
-+			l = ylist_entry(i, yaffs_obj_t, siblings);
- 			if (l && !fn(l))
- 				return YAFFS_FAIL;
- 		}
-@@ -6832,82 +4628,175 @@ int yaffs_ApplyToDirectoryChildren(yaffs
-  * actual object.
-  */
- 
--yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj)
-+yaffs_obj_t *yaffs_get_equivalent_obj(yaffs_obj_t *obj)
- {
--	if (obj && obj->variantType == YAFFS_OBJECT_TYPE_HARDLINK) {
-+	if (obj && obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) {
- 		/* We want the object id of the equivalent object, not this one */
--		obj = obj->variant.hardLinkVariant.equivalentObject;
--		yaffs_CheckObjectDetailsLoaded(obj);
-+		obj = obj->variant.hardlink_variant.equiv_obj;
-+		yaffs_check_obj_details_loaded(obj);
- 	}
- 	return obj;
- }
- 
--int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize)
--{
--	memset(name, 0, buffSize * sizeof(YCHAR));
--
--	yaffs_CheckObjectDetailsLoaded(obj);
-+/*
-+ *  A note or two on object names.
-+ *  * If the object name is missing, we then make one up in the form objnnn
-+ *
-+ *  * ASCII names are stored in the object header's name field from byte zero
-+ *  * Unicode names are historically stored starting from byte zero.
-+ *
-+ * Then there are automatic Unicode names...
-+ * The purpose of these is to save names in a way that can be read as
-+ * ASCII or Unicode names as appropriate, thus allowing a Unicode and ASCII
-+ * system to share files.
-+ *
-+ * These automatic unicode are stored slightly differently...
-+ *  - If the name can fit in the ASCII character space then they are saved as 
-+ *    ascii names as per above.
-+ *  - If the name needs Unicode then the name is saved in Unicode
-+ *    starting at oh->name[1].
- 
--	if (obj->objectId == YAFFS_OBJECTID_LOSTNFOUND) {
--		yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffSize - 1);
--	} else if (obj->hdrChunk <= 0) {
-+ */
-+static void yaffs_fix_null_name(yaffs_obj_t * obj,YCHAR * name, int buffer_size)
-+{
-+	/* Create an object name if we could not find one. */
-+	if(yaffs_strnlen(name,YAFFS_MAX_NAME_LENGTH) == 0){
- 		YCHAR locName[20];
- 		YCHAR numString[20];
- 		YCHAR *x = &numString[19];
--		unsigned v = obj->objectId;
-+		unsigned v = obj->obj_id;
- 		numString[19] = 0;
--		while (v > 0) {
-+		while(v>0){
- 			x--;
- 			*x = '0' + (v % 10);
- 			v /= 10;
- 		}
- 		/* make up a name */
- 		yaffs_strcpy(locName, YAFFS_LOSTNFOUND_PREFIX);
--		yaffs_strcat(locName, x);
--		yaffs_strncpy(name, locName, buffSize - 1);
-+		yaffs_strcat(locName,x);
-+		yaffs_strncpy(name, locName, buffer_size - 1);
-+	}
-+}
-+
-+static void yaffs_load_name_from_oh(yaffs_dev_t *dev,YCHAR *name, const YCHAR *ohName, int bufferSize)
-+{
-+#ifdef CONFIG_YAFFS_AUTO_UNICODE
-+	if(dev->param.auto_unicode){
-+		if(*ohName){
-+			/* It is an ASCII name, so do an ASCII to unicode conversion */
-+			const char *asciiOhName = (const char *)ohName;
-+			int n = bufferSize - 1;
-+			while(n > 0 && *asciiOhName){
-+				*name = *asciiOhName;
-+				name++;
-+				asciiOhName++;
-+				n--;
-+			}
-+		} else 
-+			yaffs_strncpy(name,ohName+1, bufferSize -1);
-+	} else
-+#endif
-+		yaffs_strncpy(name, ohName, bufferSize - 1);
-+}
-+
-+
-+static void yaffs_load_oh_from_name(yaffs_dev_t *dev, YCHAR *ohName, const YCHAR *name)
-+{
-+#ifdef CONFIG_YAFFS_AUTO_UNICODE
-+
-+	int isAscii;
-+	YCHAR *w;
-+
-+	if(dev->param.auto_unicode){
-+
-+		isAscii = 1;
-+		w = name;
-+	
-+		/* Figure out if the name will fit in ascii character set */
-+		while(isAscii && *w){
-+			if((*w) & 0xff00)
-+				isAscii = 0;
-+			w++;
-+		}
- 
-+		if(isAscii){
-+			/* It is an ASCII name, so do a unicode to ascii conversion */
-+			char *asciiOhName = (char *)ohName;
-+			int n = YAFFS_MAX_NAME_LENGTH  - 1;
-+			while(n > 0 && *name){
-+				*asciiOhName= *name;
-+				name++;
-+				asciiOhName++;
-+				n--;
-+			}
-+		} else{
-+			/* It is a unicode name, so save starting at the second YCHAR */
-+			*ohName = 0;
-+			yaffs_strncpy(ohName+1,name, YAFFS_MAX_NAME_LENGTH -2);
-+		}
- 	}
-+	else 
-+#endif
-+		yaffs_strncpy(ohName,name, YAFFS_MAX_NAME_LENGTH - 1);
-+
-+}
-+
-+int yaffs_get_obj_name(yaffs_obj_t * obj, YCHAR * name, int buffer_size)
-+{
-+	memset(name, 0, buffer_size * sizeof(YCHAR));
-+	
-+	yaffs_check_obj_details_loaded(obj);
-+
-+	if (obj->obj_id == YAFFS_OBJECTID_LOSTNFOUND) {
-+		yaffs_strncpy(name, YAFFS_LOSTNFOUND_NAME, buffer_size - 1);
-+	} 
- #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
--	else if (obj->shortName[0])
--		yaffs_strcpy(name, obj->shortName);
-+	else if (obj->short_name[0]) {
-+		yaffs_strcpy(name, obj->short_name);
-+	}
- #endif
--	else {
-+	else if(obj->hdr_chunk > 0) {
- 		int result;
--		__u8 *buffer = yaffs_GetTempBuffer(obj->myDev, __LINE__);
-+		__u8 *buffer = yaffs_get_temp_buffer(obj->my_dev, __LINE__);
- 
--		yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *) buffer;
-+		yaffs_obj_header *oh = (yaffs_obj_header *) buffer;
- 
--		memset(buffer, 0, obj->myDev->nDataBytesPerChunk);
-+		memset(buffer, 0, obj->my_dev->data_bytes_per_chunk);
- 
--		if (obj->hdrChunk > 0) {
--			result = yaffs_ReadChunkWithTagsFromNAND(obj->myDev,
--							obj->hdrChunk, buffer,
-+		if (obj->hdr_chunk > 0) {
-+			result = yaffs_rd_chunk_tags_nand(obj->my_dev,
-+							obj->hdr_chunk, buffer,
- 							NULL);
- 		}
--		yaffs_strncpy(name, oh->name, buffSize - 1);
-+		yaffs_load_name_from_oh(obj->my_dev,name,oh->name,buffer_size);
- 
--		yaffs_ReleaseTempBuffer(obj->myDev, buffer, __LINE__);
-+		yaffs_release_temp_buffer(obj->my_dev, buffer, __LINE__);
- 	}
- 
--	return yaffs_strlen(name);
-+	yaffs_fix_null_name(obj,name,buffer_size);
-+
-+	return yaffs_strnlen(name,YAFFS_MAX_NAME_LENGTH);
- }
- 
--int yaffs_GetObjectFileLength(yaffs_Object *obj)
-+
-+int yaffs_get_obj_length(yaffs_obj_t *obj)
- {
- 	/* Dereference any hard linking */
--	obj = yaffs_GetEquivalentObject(obj);
-+	obj = yaffs_get_equivalent_obj(obj);
- 
--	if (obj->variantType == YAFFS_OBJECT_TYPE_FILE)
--		return obj->variant.fileVariant.fileSize;
--	if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
--		return yaffs_strlen(obj->variant.symLinkVariant.alias);
--	else {
-+	if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
-+		return obj->variant.file_variant.file_size;
-+	if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK){
-+		if(!obj->variant.symlink_variant.alias)
-+			return 0;
-+		return yaffs_strnlen(obj->variant.symlink_variant.alias,YAFFS_MAX_ALIAS_LENGTH);
-+	} else {
- 		/* Only a directory should drop through to here */
--		return obj->myDev->nDataBytesPerChunk;
-+		return obj->my_dev->data_bytes_per_chunk;
- 	}
- }
- 
--int yaffs_GetObjectLinkCount(yaffs_Object *obj)
-+int yaffs_get_obj_link_count(yaffs_obj_t *obj)
- {
- 	int count = 0;
- 	struct ylist_head *i;
-@@ -6915,24 +4804,24 @@ int yaffs_GetObjectLinkCount(yaffs_Objec
- 	if (!obj->unlinked)
- 		count++;		/* the object itself */
- 
--	ylist_for_each(i, &obj->hardLinks)
-+	ylist_for_each(i, &obj->hard_links)
- 		count++;		/* add the hard links; */
- 
- 	return count;
- }
- 
--int yaffs_GetObjectInode(yaffs_Object *obj)
-+int yaffs_get_obj_inode(yaffs_obj_t *obj)
- {
--	obj = yaffs_GetEquivalentObject(obj);
-+	obj = yaffs_get_equivalent_obj(obj);
- 
--	return obj->objectId;
-+	return obj->obj_id;
- }
- 
--unsigned yaffs_GetObjectType(yaffs_Object *obj)
-+unsigned yaffs_get_obj_type(yaffs_obj_t *obj)
- {
--	obj = yaffs_GetEquivalentObject(obj);
-+	obj = yaffs_get_equivalent_obj(obj);
- 
--	switch (obj->variantType) {
-+	switch (obj->variant_type) {
- 	case YAFFS_OBJECT_TYPE_FILE:
- 		return DT_REG;
- 		break;
-@@ -6960,18 +4849,18 @@ unsigned yaffs_GetObjectType(yaffs_Objec
- 	}
- }
- 
--YCHAR *yaffs_GetSymlinkAlias(yaffs_Object *obj)
-+YCHAR *yaffs_get_symlink_alias(yaffs_obj_t *obj)
- {
--	obj = yaffs_GetEquivalentObject(obj);
--	if (obj->variantType == YAFFS_OBJECT_TYPE_SYMLINK)
--		return yaffs_CloneString(obj->variant.symLinkVariant.alias);
-+	obj = yaffs_get_equivalent_obj(obj);
-+	if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK)
-+		return yaffs_clone_str(obj->variant.symlink_variant.alias);
- 	else
--		return yaffs_CloneString(_Y(""));
-+		return yaffs_clone_str(_Y(""));
- }
- 
- #ifndef CONFIG_YAFFS_WINCE
- 
--int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr)
-+int yaffs_set_attribs(yaffs_obj_t *obj, struct iattr *attr)
- {
- 	unsigned int valid = attr->ia_valid;
- 
-@@ -6990,14 +4879,14 @@ int yaffs_SetAttributes(yaffs_Object *ob
- 		obj->yst_mtime = Y_TIME_CONVERT(attr->ia_mtime);
- 
- 	if (valid & ATTR_SIZE)
--		yaffs_ResizeFile(obj, attr->ia_size);
-+		yaffs_resize_file(obj, attr->ia_size);
- 
--	yaffs_UpdateObjectHeader(obj, NULL, 1, 0, 0);
-+	yaffs_update_oh(obj, NULL, 1, 0, 0, NULL);
- 
- 	return YAFFS_OK;
- 
- }
--int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr)
-+int yaffs_get_attribs(yaffs_obj_t *obj, struct iattr *attr)
- {
- 	unsigned int valid = 0;
- 
-@@ -7015,7 +4904,7 @@ int yaffs_GetAttributes(yaffs_Object *ob
- 	Y_TIME_CONVERT(attr->ia_mtime) = obj->yst_mtime;
- 	valid |= ATTR_MTIME;
- 
--	attr->ia_size = yaffs_GetFileSize(obj);
-+	attr->ia_size = yaffs_get_file_size(obj);
- 	valid |= ATTR_SIZE;
- 
- 	attr->ia_valid = valid;
-@@ -7025,20 +4914,137 @@ int yaffs_GetAttributes(yaffs_Object *ob
- 
- #endif
- 
-+
-+static int yaffs_do_xattrib_mod(yaffs_obj_t *obj, int set, const YCHAR *name, const void *value, int size, int flags)
-+{
-+	yaffs_xattr_mod xmod;
-+
-+	int result;
-+
-+	xmod.set = set;
-+	xmod.name = name;
-+	xmod.data = value;
-+	xmod.size =  size;
-+	xmod.flags = flags;
-+	xmod.result = -ENOSPC;
-+
-+	result = yaffs_update_oh(obj, NULL, 0, 0, 0, &xmod);
-+
-+	if(result > 0)
-+		return xmod.result;
-+	else
-+		return -ENOSPC;
-+}
-+
-+static int yaffs_apply_xattrib_mod(yaffs_obj_t *obj, char *buffer, yaffs_xattr_mod *xmod)
-+{
-+	int retval = 0;
-+	int x_offs = sizeof(yaffs_obj_header);
-+	yaffs_dev_t *dev = obj->my_dev;
-+	int x_size = dev->data_bytes_per_chunk - sizeof(yaffs_obj_header);
-+
-+	char * x_buffer = buffer + x_offs;
-+
-+	if(xmod->set)
-+		retval = nval_set(x_buffer, x_size, xmod->name, xmod->data, xmod->size, xmod->flags);
-+	else
-+		retval = nval_del(x_buffer, x_size, xmod->name);
-+
-+	obj->has_xattr = nval_hasvalues(x_buffer, x_size);
-+	obj->xattr_known = 1;
-+
-+	xmod->result = retval;
-+
-+	return retval;
-+}
-+
-+static int yaffs_do_xattrib_fetch(yaffs_obj_t *obj, const YCHAR *name, void *value, int size)
-+{
-+	char *buffer = NULL;
-+	int result;
-+	yaffs_ext_tags tags;
-+	yaffs_dev_t *dev = obj->my_dev;
-+	int x_offs = sizeof(yaffs_obj_header);
-+	int x_size = dev->data_bytes_per_chunk - sizeof(yaffs_obj_header);
-+
-+	char * x_buffer;
-+
-+	int retval = 0;
-+
-+	if(obj->hdr_chunk < 1)
-+		return -ENODATA;
-+
-+	/* If we know that the object has no xattribs then don't do all the
-+	 * reading and parsing.
-+	 */
-+	if(obj->xattr_known && !obj->has_xattr){
-+		if(name)
-+			return -ENODATA;
-+		else
-+			return 0;
-+	}
-+
-+	buffer = (char *) yaffs_get_temp_buffer(dev, __LINE__);
-+	if(!buffer)
-+		return -ENOMEM;
-+
-+	result = yaffs_rd_chunk_tags_nand(dev,obj->hdr_chunk, (__u8 *)buffer, &tags);
-+
-+	if(result != YAFFS_OK)
-+		retval = -ENOENT;
-+	else{
-+		x_buffer =  buffer + x_offs;
-+
-+		if (!obj->xattr_known){
-+			obj->has_xattr = nval_hasvalues(x_buffer, x_size);
-+			obj->xattr_known = 1;
-+		}
-+
-+		if(name)
-+			retval = nval_get(x_buffer, x_size, name, value, size);
-+		else
-+			retval = nval_list(x_buffer, x_size, value,size);
-+	}
-+	yaffs_release_temp_buffer(dev,(__u8 *)buffer,__LINE__);
-+	return retval;
-+}
-+
-+int yaffs_set_xattrib(yaffs_obj_t *obj, const YCHAR *name, const void * value, int size, int flags)
-+{
-+	return yaffs_do_xattrib_mod(obj, 1, name, value, size, flags);
-+}
-+
-+int yaffs_remove_xattrib(yaffs_obj_t *obj, const YCHAR *name)
-+{
-+	return yaffs_do_xattrib_mod(obj, 0, name, NULL, 0, 0);
-+}
-+
-+int yaffs_get_xattrib(yaffs_obj_t *obj, const YCHAR *name, void *value, int size)
-+{
-+	return yaffs_do_xattrib_fetch(obj, name, value, size);
-+}
-+
-+int yaffs_list_xattrib(yaffs_obj_t *obj, char *buffer, int size)
-+{
-+	return yaffs_do_xattrib_fetch(obj, NULL, buffer,size);
-+}
-+
-+
-+
- #if 0
--int yaffs_DumpObject(yaffs_Object *obj)
-+int yaffs_dump_obj(yaffs_obj_t *obj)
- {
- 	YCHAR name[257];
- 
--	yaffs_GetObjectName(obj, name, 256);
-+	yaffs_get_obj_name(obj, name, YAFFS_MAX_NAME_LENGTH + 1);
- 
- 	T(YAFFS_TRACE_ALWAYS,
- 	  (TSTR
- 	   ("Object %d, inode %d \"%s\"\n dirty %d valid %d serial %d sum %d"
- 	    " chunk %d type %d size %d\n"
--	    TENDSTR), obj->objectId, yaffs_GetObjectInode(obj), name,
--	   obj->dirty, obj->valid, obj->serial, obj->sum, obj->hdrChunk,
--	   yaffs_GetObjectType(obj), yaffs_GetObjectFileLength(obj)));
-+	    TENDSTR), obj->obj_id, yaffs_get_obj_inode(obj), name,
-+	   obj->dirty, obj->valid, obj->serial, obj->sum, obj->hdr_chunk,
-+	   yaffs_get_obj_type(obj), yaffs_get_obj_length(obj)));
- 
- 	return YAFFS_OK;
- }
-@@ -7046,72 +5052,74 @@ int yaffs_DumpObject(yaffs_Object *obj)
- 
- /*---------------------------- Initialisation code -------------------------------------- */
- 
--static int yaffs_CheckDevFunctions(const yaffs_Device *dev)
-+static int yaffs_cehck_dev_fns(const yaffs_dev_t *dev)
- {
- 
- 	/* Common functions, gotta have */
--	if (!dev->eraseBlockInNAND || !dev->initialiseNAND)
-+	if (!dev->param.erase_fn || !dev->param.initialise_flash_fn)
- 		return 0;
- 
- #ifdef CONFIG_YAFFS_YAFFS2
- 
- 	/* Can use the "with tags" style interface for yaffs1 or yaffs2 */
--	if (dev->writeChunkWithTagsToNAND &&
--	    dev->readChunkWithTagsFromNAND &&
--	    !dev->writeChunkToNAND &&
--	    !dev->readChunkFromNAND &&
--	    dev->markNANDBlockBad && dev->queryNANDBlock)
-+	if (dev->param.write_chunk_tags_fn &&
-+	    dev->param.read_chunk_tags_fn &&
-+	    !dev->param.write_chunk_fn &&
-+	    !dev->param.read_chunk_fn &&
-+	    dev->param.bad_block_fn &&
-+	    dev->param.query_block_fn)
- 		return 1;
- #endif
- 
- 	/* Can use the "spare" style interface for yaffs1 */
--	if (!dev->isYaffs2 &&
--	    !dev->writeChunkWithTagsToNAND &&
--	    !dev->readChunkWithTagsFromNAND &&
--	    dev->writeChunkToNAND &&
--	    dev->readChunkFromNAND &&
--	    !dev->markNANDBlockBad && !dev->queryNANDBlock)
-+	if (!dev->param.is_yaffs2 &&
-+	    !dev->param.write_chunk_tags_fn &&
-+	    !dev->param.read_chunk_tags_fn &&
-+	    dev->param.write_chunk_fn &&
-+	    dev->param.read_chunk_fn &&
-+	    !dev->param.bad_block_fn &&
-+	    !dev->param.query_block_fn)
- 		return 1;
- 
--	return 0;		/* bad */
-+	return 0;	/* bad */
- }
- 
- 
--static int yaffs_CreateInitialDirectories(yaffs_Device *dev)
-+static int yaffs_create_initial_dir(yaffs_dev_t *dev)
- {
- 	/* Initialise the unlinked, deleted, root and lost and found directories */
- 
--	dev->lostNFoundDir = dev->rootDir =  NULL;
--	dev->unlinkedDir = dev->deletedDir = NULL;
-+	dev->lost_n_found = dev->root_dir =  NULL;
-+	dev->unlinked_dir = dev->del_dir = NULL;
- 
--	dev->unlinkedDir =
--	    yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR);
-+	dev->unlinked_dir =
-+	    yaffs_create_fake_dir(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR);
- 
--	dev->deletedDir =
--	    yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_DELETED, S_IFDIR);
-+	dev->del_dir =
-+	    yaffs_create_fake_dir(dev, YAFFS_OBJECTID_DELETED, S_IFDIR);
- 
--	dev->rootDir =
--	    yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_ROOT,
-+	dev->root_dir =
-+	    yaffs_create_fake_dir(dev, YAFFS_OBJECTID_ROOT,
- 				      YAFFS_ROOT_MODE | S_IFDIR);
--	dev->lostNFoundDir =
--	    yaffs_CreateFakeDirectory(dev, YAFFS_OBJECTID_LOSTNFOUND,
-+	dev->lost_n_found =
-+	    yaffs_create_fake_dir(dev, YAFFS_OBJECTID_LOSTNFOUND,
- 				      YAFFS_LOSTNFOUND_MODE | S_IFDIR);
- 
--	if (dev->lostNFoundDir && dev->rootDir && dev->unlinkedDir && dev->deletedDir) {
--		yaffs_AddObjectToDirectory(dev->rootDir, dev->lostNFoundDir);
-+	if (dev->lost_n_found && dev->root_dir && dev->unlinked_dir && dev->del_dir) {
-+		yaffs_add_obj_to_dir(dev->root_dir, dev->lost_n_found);
- 		return YAFFS_OK;
- 	}
- 
- 	return YAFFS_FAIL;
- }
- 
--int yaffs_GutsInitialise(yaffs_Device *dev)
-+int yaffs_guts_initialise(yaffs_dev_t *dev)
- {
- 	int init_failed = 0;
- 	unsigned x;
- 	int bits;
- 
--	T(YAFFS_TRACE_TRACING, (TSTR("yaffs: yaffs_GutsInitialise()" TENDSTR)));
-+	T(YAFFS_TRACE_TRACING, (TSTR("yaffs: yaffs_guts_initialise()" TENDSTR)));
- 
- 	/* Check stuff that must be set */
- 
-@@ -7120,52 +5128,52 @@ int yaffs_GutsInitialise(yaffs_Device *d
- 		return YAFFS_FAIL;
- 	}
- 
--	dev->internalStartBlock = dev->startBlock;
--	dev->internalEndBlock = dev->endBlock;
--	dev->blockOffset = 0;
--	dev->chunkOffset = 0;
--	dev->nFreeChunks = 0;
--
--	dev->gcBlock = -1;
--
--	if (dev->startBlock == 0) {
--		dev->internalStartBlock = dev->startBlock + 1;
--		dev->internalEndBlock = dev->endBlock + 1;
--		dev->blockOffset = 1;
--		dev->chunkOffset = dev->nChunksPerBlock;
-+	dev->internal_start_block = dev->param.start_block;
-+	dev->internal_end_block = dev->param.end_block;
-+	dev->block_offset = 0;
-+	dev->chunk_offset = 0;
-+	dev->n_free_chunks = 0;
-+
-+	dev->gc_block = 0;
-+
-+	if (dev->param.start_block == 0) {
-+		dev->internal_start_block = dev->param.start_block + 1;
-+		dev->internal_end_block = dev->param.end_block + 1;
-+		dev->block_offset = 1;
-+		dev->chunk_offset = dev->param.chunks_per_block;
- 	}
- 
- 	/* Check geometry parameters. */
- 
--	if ((!dev->inbandTags && dev->isYaffs2 && dev->totalBytesPerChunk < 1024) ||
--	    (!dev->isYaffs2 && dev->totalBytesPerChunk < 512) ||
--	    (dev->inbandTags && !dev->isYaffs2) ||
--	     dev->nChunksPerBlock < 2 ||
--	     dev->nReservedBlocks < 2 ||
--	     dev->internalStartBlock <= 0 ||
--	     dev->internalEndBlock <= 0 ||
--	     dev->internalEndBlock <= (dev->internalStartBlock + dev->nReservedBlocks + 2)) {	/* otherwise it is too small */
-+	if ((!dev->param.inband_tags && dev->param.is_yaffs2 && dev->param.total_bytes_per_chunk < 1024) ||
-+	    (!dev->param.is_yaffs2 && dev->param.total_bytes_per_chunk < 512) ||
-+	    (dev->param.inband_tags && !dev->param.is_yaffs2) ||
-+	     dev->param.chunks_per_block < 2 ||
-+	     dev->param.n_reserved_blocks < 2 ||
-+	     dev->internal_start_block <= 0 ||
-+	     dev->internal_end_block <= 0 ||
-+	     dev->internal_end_block <= (dev->internal_start_block + dev->param.n_reserved_blocks + 2)) {	/* otherwise it is too small */
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
--		   ("yaffs: NAND geometry problems: chunk size %d, type is yaffs%s, inbandTags %d "
--		    TENDSTR), dev->totalBytesPerChunk, dev->isYaffs2 ? "2" : "", dev->inbandTags));
-+		   ("yaffs: NAND geometry problems: chunk size %d, type is yaffs%s, inband_tags %d "
-+		    TENDSTR), dev->param.total_bytes_per_chunk, dev->param.is_yaffs2 ? "2" : "", dev->param.inband_tags));
- 		return YAFFS_FAIL;
- 	}
- 
--	if (yaffs_InitialiseNAND(dev) != YAFFS_OK) {
-+	if (yaffs_init_nand(dev) != YAFFS_OK) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR("yaffs: InitialiseNAND failed" TENDSTR)));
- 		return YAFFS_FAIL;
- 	}
- 
- 	/* Sort out space for inband tags, if required */
--	if (dev->inbandTags)
--		dev->nDataBytesPerChunk = dev->totalBytesPerChunk - sizeof(yaffs_PackedTags2TagsPart);
-+	if (dev->param.inband_tags)
-+		dev->data_bytes_per_chunk = dev->param.total_bytes_per_chunk - sizeof(yaffs_PackedTags2TagsPart);
- 	else
--		dev->nDataBytesPerChunk = dev->totalBytesPerChunk;
-+		dev->data_bytes_per_chunk = dev->param.total_bytes_per_chunk;
- 
- 	/* Got the right mix of functions? */
--	if (!yaffs_CheckDevFunctions(dev)) {
-+	if (!yaffs_cehck_dev_fns(dev)) {
- 		/* Function missing */
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR
-@@ -7175,13 +5183,13 @@ int yaffs_GutsInitialise(yaffs_Device *d
- 	}
- 
- 	/* This is really a compilation check. */
--	if (!yaffs_CheckStructures()) {
-+	if (!yaffs_check_structures()) {
- 		T(YAFFS_TRACE_ALWAYS,
--		  (TSTR("yaffs_CheckStructures failed\n" TENDSTR)));
-+		  (TSTR("yaffs_check_structures failed\n" TENDSTR)));
- 		return YAFFS_FAIL;
- 	}
- 
--	if (dev->isMounted) {
-+	if (dev->is_mounted) {
- 		T(YAFFS_TRACE_ALWAYS,
- 		  (TSTR("yaffs: device already mounted\n" TENDSTR)));
- 		return YAFFS_FAIL;
-@@ -7189,59 +5197,62 @@ int yaffs_GutsInitialise(yaffs_Device *d
- 
- 	/* Finished with most checks. One or two more checks happen later on too. */
- 
--	dev->isMounted = 1;
-+	dev->is_mounted = 1;
- 
- 	/* OK now calculate a few things for the device */
- 
- 	/*
- 	 *  Calculate all the chunk size manipulation numbers:
- 	 */
--	x = dev->nDataBytesPerChunk;
--	/* We always use dev->chunkShift and dev->chunkDiv */
--	dev->chunkShift = Shifts(x);
--	x >>= dev->chunkShift;
--	dev->chunkDiv = x;
--	/* We only use chunk mask if chunkDiv is 1 */
--	dev->chunkMask = (1<<dev->chunkShift) - 1;
-+	x = dev->data_bytes_per_chunk;
-+	/* We always use dev->chunk_shift and dev->chunk_div */
-+	dev->chunk_shift = Shifts(x);
-+	x >>= dev->chunk_shift;
-+	dev->chunk_div = x;
-+	/* We only use chunk mask if chunk_div is 1 */
-+	dev->chunk_mask = (1<<dev->chunk_shift) - 1;
- 
- 	/*
--	 * Calculate chunkGroupBits.
--	 * We need to find the next power of 2 > than internalEndBlock
-+	 * Calculate chunk_grp_bits.
-+	 * We need to find the next power of 2 > than internal_end_block
- 	 */
- 
--	x = dev->nChunksPerBlock * (dev->internalEndBlock + 1);
-+	x = dev->param.chunks_per_block * (dev->internal_end_block + 1);
- 
- 	bits = ShiftsGE(x);
- 
- 	/* Set up tnode width if wide tnodes are enabled. */
--	if (!dev->wideTnodesDisabled) {
-+	if (!dev->param.wide_tnodes_disabled) {
- 		/* bits must be even so that we end up with 32-bit words */
- 		if (bits & 1)
- 			bits++;
- 		if (bits < 16)
--			dev->tnodeWidth = 16;
-+			dev->tnode_width = 16;
- 		else
--			dev->tnodeWidth = bits;
-+			dev->tnode_width = bits;
- 	} else
--		dev->tnodeWidth = 16;
-+		dev->tnode_width = 16;
- 
--	dev->tnodeMask = (1<<dev->tnodeWidth)-1;
-+	dev->tnode_mask = (1<<dev->tnode_width)-1;
- 
- 	/* Level0 Tnodes are 16 bits or wider (if wide tnodes are enabled),
- 	 * so if the bitwidth of the
- 	 * chunk range we're using is greater than 16 we need
--	 * to figure out chunk shift and chunkGroupSize
-+	 * to figure out chunk shift and chunk_grp_size
- 	 */
- 
--	if (bits <= dev->tnodeWidth)
--		dev->chunkGroupBits = 0;
-+	if (bits <= dev->tnode_width)
-+		dev->chunk_grp_bits = 0;
- 	else
--		dev->chunkGroupBits = bits - dev->tnodeWidth;
-+		dev->chunk_grp_bits = bits - dev->tnode_width;
- 
-+	dev->tnode_size = (dev->tnode_width * YAFFS_NTNODES_LEVEL0)/8;
-+	if(dev->tnode_size < sizeof(yaffs_tnode_t))
-+		dev->tnode_size = sizeof(yaffs_tnode_t);
- 
--	dev->chunkGroupSize = 1 << dev->chunkGroupBits;
-+	dev->chunk_grp_size = 1 << dev->chunk_grp_bits;
- 
--	if (dev->nChunksPerBlock < dev->chunkGroupSize) {
-+	if (dev->param.chunks_per_block < dev->chunk_grp_size) {
- 		/* We have a problem because the soft delete won't work if
- 		 * the chunk group size > chunks per block.
- 		 * This can be remedied by using larger "virtual blocks".
-@@ -7255,85 +5266,89 @@ int yaffs_GutsInitialise(yaffs_Device *d
- 	/* OK, we've finished verifying the device, lets continue with initialisation */
- 
- 	/* More device initialisation */
--	dev->garbageCollections = 0;
--	dev->passiveGarbageCollections = 0;
--	dev->currentDirtyChecker = 0;
--	dev->bufferedBlock = -1;
--	dev->doingBufferedBlockRewrite = 0;
--	dev->nDeletedFiles = 0;
--	dev->nBackgroundDeletions = 0;
--	dev->nUnlinkedFiles = 0;
--	dev->eccFixed = 0;
--	dev->eccUnfixed = 0;
--	dev->tagsEccFixed = 0;
--	dev->tagsEccUnfixed = 0;
--	dev->nErasureFailures = 0;
--	dev->nErasedBlocks = 0;
--	dev->isDoingGC = 0;
--	dev->hasPendingPrioritisedGCs = 1; /* Assume the worst for now, will get fixed on first GC */
-+	dev->all_gcs = 0;
-+	dev->passive_gc_count = 0;
-+	dev->oldest_dirty_gc_count = 0;
-+	dev->bg_gcs = 0;
-+	dev->gc_block_finder = 0;
-+	dev->buffered_block = -1;
-+	dev->doing_buffered_block_rewrite = 0;
-+	dev->n_deleted_files = 0;
-+	dev->n_bg_deletions = 0;
-+	dev->n_unlinked_files = 0;
-+	dev->n_ecc_fixed = 0;
-+	dev->n_ecc_unfixed = 0;
-+	dev->n_tags_ecc_fixed = 0;
-+	dev->n_tags_ecc_unfixed = 0;
-+	dev->n_erase_failures = 0;
-+	dev->n_erased_blocks = 0;
-+	dev->gc_disable= 0;
-+	dev->has_pending_prioritised_gc = 1; /* Assume the worst for now, will get fixed on first GC */
-+	YINIT_LIST_HEAD(&dev->dirty_dirs);
-+	dev->oldest_dirty_seq = 0;
-+	dev->oldest_dirty_block = 0;
- 
- 	/* Initialise temporary buffers and caches. */
--	if (!yaffs_InitialiseTempBuffers(dev))
-+	if (!yaffs_init_tmp_buffers(dev))
- 		init_failed = 1;
- 
--	dev->srCache = NULL;
--	dev->gcCleanupList = NULL;
-+	dev->cache = NULL;
-+	dev->gc_cleanup_list = NULL;
- 
- 
- 	if (!init_failed &&
--	    dev->nShortOpCaches > 0) {
-+	    dev->param.n_caches > 0) {
- 		int i;
- 		void *buf;
--		int srCacheBytes = dev->nShortOpCaches * sizeof(yaffs_ChunkCache);
-+		int cacheBytes = dev->param.n_caches * sizeof(yaffs_cache_t);
- 
--		if (dev->nShortOpCaches > YAFFS_MAX_SHORT_OP_CACHES)
--			dev->nShortOpCaches = YAFFS_MAX_SHORT_OP_CACHES;
-+		if (dev->param.n_caches > YAFFS_MAX_SHORT_OP_CACHES)
-+			dev->param.n_caches = YAFFS_MAX_SHORT_OP_CACHES;
- 
--		dev->srCache =  YMALLOC(srCacheBytes);
-+		dev->cache =  YMALLOC(cacheBytes);
- 
--		buf = (__u8 *) dev->srCache;
-+		buf = (__u8 *) dev->cache;
- 
--		if (dev->srCache)
--			memset(dev->srCache, 0, srCacheBytes);
-+		if (dev->cache)
-+			memset(dev->cache, 0, cacheBytes);
- 
--		for (i = 0; i < dev->nShortOpCaches && buf; i++) {
--			dev->srCache[i].object = NULL;
--			dev->srCache[i].lastUse = 0;
--			dev->srCache[i].dirty = 0;
--			dev->srCache[i].data = buf = YMALLOC_DMA(dev->totalBytesPerChunk);
-+		for (i = 0; i < dev->param.n_caches && buf; i++) {
-+			dev->cache[i].object = NULL;
-+			dev->cache[i].last_use = 0;
-+			dev->cache[i].dirty = 0;
-+			dev->cache[i].data = buf = YMALLOC_DMA(dev->param.total_bytes_per_chunk);
- 		}
- 		if (!buf)
- 			init_failed = 1;
- 
--		dev->srLastUse = 0;
-+		dev->cache_last_use = 0;
- 	}
- 
--	dev->cacheHits = 0;
-+	dev->cache_hits = 0;
- 
- 	if (!init_failed) {
--		dev->gcCleanupList = YMALLOC(dev->nChunksPerBlock * sizeof(__u32));
--		if (!dev->gcCleanupList)
-+		dev->gc_cleanup_list = YMALLOC(dev->param.chunks_per_block * sizeof(__u32));
-+		if (!dev->gc_cleanup_list)
- 			init_failed = 1;
- 	}
- 
--	if (dev->isYaffs2)
--		dev->useHeaderFileSize = 1;
-+	if (dev->param.is_yaffs2)
-+		dev->param.use_header_file_size = 1;
- 
--	if (!init_failed && !yaffs_InitialiseBlocks(dev))
-+	if (!init_failed && !yaffs_init_blocks(dev))
- 		init_failed = 1;
- 
--	yaffs_InitialiseTnodes(dev);
--	yaffs_InitialiseObjects(dev);
-+	yaffs_init_tnodes_and_objs(dev);
- 
--	if (!init_failed && !yaffs_CreateInitialDirectories(dev))
-+	if (!init_failed && !yaffs_create_initial_dir(dev))
- 		init_failed = 1;
- 
- 
- 	if (!init_failed) {
- 		/* Now scan the flash. */
--		if (dev->isYaffs2) {
--			if (yaffs_CheckpointRestore(dev)) {
--				yaffs_CheckObjectDetailsLoaded(dev->rootDir);
-+		if (dev->param.is_yaffs2) {
-+			if (yaffs2_checkpt_restore(dev)) {
-+				yaffs_check_obj_details_loaded(dev->root_dir);
- 				T(YAFFS_TRACE_ALWAYS,
- 				  (TSTR("yaffs: restored from checkpoint" TENDSTR)));
- 			} else {
-@@ -7341,128 +5356,129 @@ int yaffs_GutsInitialise(yaffs_Device *d
- 				/* Clean up the mess caused by an aborted checkpoint load
- 				 * and scan backwards.
- 				 */
--				yaffs_DeinitialiseBlocks(dev);
--				yaffs_DeinitialiseTnodes(dev);
--				yaffs_DeinitialiseObjects(dev);
-+				yaffs_deinit_blocks(dev);
- 
-+				yaffs_deinit_tnodes_and_objs(dev);
- 
--				dev->nErasedBlocks = 0;
--				dev->nFreeChunks = 0;
--				dev->allocationBlock = -1;
--				dev->allocationPage = -1;
--				dev->nDeletedFiles = 0;
--				dev->nUnlinkedFiles = 0;
--				dev->nBackgroundDeletions = 0;
--				dev->oldestDirtySequence = 0;
-+				dev->n_erased_blocks = 0;
-+				dev->n_free_chunks = 0;
-+				dev->alloc_block = -1;
-+				dev->alloc_page = -1;
-+				dev->n_deleted_files = 0;
-+				dev->n_unlinked_files = 0;
-+				dev->n_bg_deletions = 0;
- 
--				if (!init_failed && !yaffs_InitialiseBlocks(dev))
-+				if (!init_failed && !yaffs_init_blocks(dev))
- 					init_failed = 1;
- 
--				yaffs_InitialiseTnodes(dev);
--				yaffs_InitialiseObjects(dev);
-+				yaffs_init_tnodes_and_objs(dev);
- 
--				if (!init_failed && !yaffs_CreateInitialDirectories(dev))
-+				if (!init_failed && !yaffs_create_initial_dir(dev))
- 					init_failed = 1;
- 
--				if (!init_failed && !yaffs_ScanBackwards(dev))
-+				if (!init_failed && !yaffs2_scan_backwards(dev))
- 					init_failed = 1;
- 			}
--		} else if (!yaffs_Scan(dev))
-+		} else if (!yaffs1_scan(dev))
- 				init_failed = 1;
- 
--		yaffs_StripDeletedObjects(dev);
-+		yaffs_strip_deleted_objs(dev);
-+		yaffs_fix_hanging_objs(dev);
-+		if(dev->param.empty_lost_n_found)
-+			yaffs_empty_l_n_f(dev);
- 	}
- 
- 	if (init_failed) {
- 		/* Clean up the mess */
- 		T(YAFFS_TRACE_TRACING,
--		  (TSTR("yaffs: yaffs_GutsInitialise() aborted.\n" TENDSTR)));
-+		  (TSTR("yaffs: yaffs_guts_initialise() aborted.\n" TENDSTR)));
- 
--		yaffs_Deinitialise(dev);
-+		yaffs_deinitialise(dev);
- 		return YAFFS_FAIL;
- 	}
- 
- 	/* Zero out stats */
--	dev->nPageReads = 0;
--	dev->nPageWrites = 0;
--	dev->nBlockErasures = 0;
--	dev->nGCCopies = 0;
--	dev->nRetriedWrites = 0;
--
--	dev->nRetiredBlocks = 0;
--
--	yaffs_VerifyFreeChunks(dev);
--	yaffs_VerifyBlocks(dev);
--
-+	dev->n_page_reads = 0;
-+	dev->n_page_writes = 0;
-+	dev->n_erasures = 0;
-+	dev->n_gc_copies = 0;
-+	dev->n_retired_writes = 0;
-+
-+	dev->n_retired_blocks = 0;
-+
-+	yaffs_verify_free_chunks(dev);
-+	yaffs_verify_blocks(dev);
-+
-+	/* Clean up any aborted checkpoint data */
-+	if(!dev->is_checkpointed && dev->blocks_in_checkpt > 0)
-+		yaffs2_checkpt_invalidate(dev);
- 
- 	T(YAFFS_TRACE_TRACING,
--	  (TSTR("yaffs: yaffs_GutsInitialise() done.\n" TENDSTR)));
-+	  (TSTR("yaffs: yaffs_guts_initialise() done.\n" TENDSTR)));
- 	return YAFFS_OK;
- 
- }
- 
--void yaffs_Deinitialise(yaffs_Device *dev)
-+void yaffs_deinitialise(yaffs_dev_t *dev)
- {
--	if (dev->isMounted) {
-+	if (dev->is_mounted) {
- 		int i;
- 
--		yaffs_DeinitialiseBlocks(dev);
--		yaffs_DeinitialiseTnodes(dev);
--		yaffs_DeinitialiseObjects(dev);
--		if (dev->nShortOpCaches > 0 &&
--		    dev->srCache) {
-+		yaffs_deinit_blocks(dev);
-+		yaffs_deinit_tnodes_and_objs(dev);
-+		if (dev->param.n_caches > 0 &&
-+		    dev->cache) {
- 
--			for (i = 0; i < dev->nShortOpCaches; i++) {
--				if (dev->srCache[i].data)
--					YFREE(dev->srCache[i].data);
--				dev->srCache[i].data = NULL;
-+			for (i = 0; i < dev->param.n_caches; i++) {
-+				if (dev->cache[i].data)
-+					YFREE(dev->cache[i].data);
-+				dev->cache[i].data = NULL;
- 			}
- 
--			YFREE(dev->srCache);
--			dev->srCache = NULL;
-+			YFREE(dev->cache);
-+			dev->cache = NULL;
- 		}
- 
--		YFREE(dev->gcCleanupList);
-+		YFREE(dev->gc_cleanup_list);
- 
- 		for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
--			YFREE(dev->tempBuffer[i].buffer);
-+			YFREE(dev->temp_buffer[i].buffer);
- 
--		dev->isMounted = 0;
-+		dev->is_mounted = 0;
- 
--		if (dev->deinitialiseNAND)
--			dev->deinitialiseNAND(dev);
-+		if (dev->param.deinitialise_flash_fn)
-+			dev->param.deinitialise_flash_fn(dev);
- 	}
- }
- 
--static int yaffs_CountFreeChunks(yaffs_Device *dev)
-+int yaffs_count_free_chunks(yaffs_dev_t *dev)
- {
--	int nFree;
-+	int nFree=0;
- 	int b;
- 
--	yaffs_BlockInfo *blk;
--
--	for (nFree = 0, b = dev->internalStartBlock; b <= dev->internalEndBlock;
--			b++) {
--		blk = yaffs_GetBlockInfo(dev, b);
-+	yaffs_block_info_t *blk;
- 
--		switch (blk->blockState) {
-+	blk = dev->block_info;
-+	for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) {
-+		switch (blk->block_state) {
- 		case YAFFS_BLOCK_STATE_EMPTY:
- 		case YAFFS_BLOCK_STATE_ALLOCATING:
- 		case YAFFS_BLOCK_STATE_COLLECTING:
- 		case YAFFS_BLOCK_STATE_FULL:
- 			nFree +=
--			    (dev->nChunksPerBlock - blk->pagesInUse +
--			     blk->softDeletions);
-+			    (dev->param.chunks_per_block - blk->pages_in_use +
-+			     blk->soft_del_pages);
- 			break;
- 		default:
- 			break;
- 		}
-+		blk++;
- 	}
- 
- 	return nFree;
- }
- 
--int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev)
-+int yaffs_get_n_free_chunks(yaffs_dev_t *dev)
- {
- 	/* This is what we report to the outside world */
- 
-@@ -7472,30 +5488,28 @@ int yaffs_GetNumberOfFreeChunks(yaffs_De
- 	int i;
- 
- #if 1
--	nFree = dev->nFreeChunks;
-+	nFree = dev->n_free_chunks;
- #else
--	nFree = yaffs_CountFreeChunks(dev);
-+	nFree = yaffs_count_free_chunks(dev);
- #endif
- 
--	nFree += dev->nDeletedFiles;
-+	nFree += dev->n_deleted_files;
- 
- 	/* Now count the number of dirty chunks in the cache and subtract those */
- 
--	for (nDirtyCacheChunks = 0, i = 0; i < dev->nShortOpCaches; i++) {
--		if (dev->srCache[i].dirty)
-+	for (nDirtyCacheChunks = 0, i = 0; i < dev->param.n_caches; i++) {
-+		if (dev->cache[i].dirty)
- 			nDirtyCacheChunks++;
- 	}
- 
- 	nFree -= nDirtyCacheChunks;
- 
--	nFree -= ((dev->nReservedBlocks + 1) * dev->nChunksPerBlock);
-+	nFree -= ((dev->param.n_reserved_blocks + 1) * dev->param.chunks_per_block);
- 
- 	/* Now we figure out how much to reserve for the checkpoint and report that... */
--	blocksForCheckpoint = yaffs_CalcCheckpointBlocksRequired(dev) - dev->blocksInCheckpoint;
--	if (blocksForCheckpoint < 0)
--		blocksForCheckpoint = 0;
-+	blocksForCheckpoint = yaffs_calc_checkpt_blocks_required(dev);
- 
--	nFree -= (blocksForCheckpoint * dev->nChunksPerBlock);
-+	nFree -= (blocksForCheckpoint * dev->param.chunks_per_block);
- 
- 	if (nFree < 0)
- 		nFree = 0;
-@@ -7504,49 +5518,27 @@ int yaffs_GetNumberOfFreeChunks(yaffs_De
- 
- }
- 
--static int yaffs_freeVerificationFailures;
--
--static void yaffs_VerifyFreeChunks(yaffs_Device *dev)
--{
--	int counted;
--	int difference;
--
--	if (yaffs_SkipVerification(dev))
--		return;
--
--	counted = yaffs_CountFreeChunks(dev);
--
--	difference = dev->nFreeChunks - counted;
--
--	if (difference) {
--		T(YAFFS_TRACE_ALWAYS,
--		  (TSTR("Freechunks verification failure %d %d %d" TENDSTR),
--		   dev->nFreeChunks, counted, difference));
--		yaffs_freeVerificationFailures++;
--	}
--}
- 
- /*---------------------------------------- YAFFS test code ----------------------*/
- 
--#define yaffs_CheckStruct(structure, syze, name) \
-+#define yaffs_check_struct(structure, syze, name) \
- 	do { \
- 		if (sizeof(structure) != syze) { \
- 			T(YAFFS_TRACE_ALWAYS, (TSTR("%s should be %d but is %d\n" TENDSTR),\
--				name, syze, sizeof(structure))); \
-+				name, syze, (int) sizeof(structure))); \
- 			return YAFFS_FAIL; \
- 		} \
- 	} while (0)
- 
--static int yaffs_CheckStructures(void)
-+static int yaffs_check_structures(void)
- {
--/*      yaffs_CheckStruct(yaffs_Tags,8,"yaffs_Tags"); */
--/*      yaffs_CheckStruct(yaffs_TagsUnion,8,"yaffs_TagsUnion"); */
--/*      yaffs_CheckStruct(yaffs_Spare,16,"yaffs_Spare"); */
--#ifndef CONFIG_YAFFS_TNODE_LIST_DEBUG
--	yaffs_CheckStruct(yaffs_Tnode, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_Tnode");
--#endif
-+/*      yaffs_check_struct(yaffs_tags_t,8,"yaffs_tags_t"); */
-+/*      yaffs_check_struct(yaffs_tags_union_t,8,"yaffs_tags_union_t"); */
-+/*      yaffs_check_struct(yaffs_spare,16,"yaffs_spare"); */
-+/*	yaffs_check_struct(yaffs_tnode_t, 2 * YAFFS_NTNODES_LEVEL0, "yaffs_tnode_t"); */
-+
- #ifndef CONFIG_YAFFS_WINCE
--	yaffs_CheckStruct(yaffs_ObjectHeader, 512, "yaffs_ObjectHeader");
-+	yaffs_check_struct(yaffs_obj_header, 512, "yaffs_obj_header");
- #endif
- 	return YAFFS_OK;
- }
---- a/fs/yaffs2/yaffs_guts.h
-+++ b/fs/yaffs2/yaffs_guts.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -16,8 +16,9 @@
- #ifndef __YAFFS_GUTS_H__
- #define __YAFFS_GUTS_H__
- 
--#include "devextras.h"
- #include "yportenv.h"
-+#include "devextras.h"
-+#include "yaffs_list.h"
- 
- #define YAFFS_OK	1
- #define YAFFS_FAIL  0
-@@ -52,7 +53,6 @@
- 
- #define YAFFS_MAX_CHUNK_ID		0x000FFFFF
- 
--#define YAFFS_UNUSED_OBJECT_ID		0x0003FFFF
- 
- #define YAFFS_ALLOCATION_NOBJECTS	100
- #define YAFFS_ALLOCATION_NTNODES	100
-@@ -62,8 +62,9 @@
- 
- 
- #define YAFFS_OBJECT_SPACE		0x40000
-+#define YAFFS_MAX_OBJECT_ID		(YAFFS_OBJECT_SPACE -1)
- 
--#define YAFFS_CHECKPOINT_VERSION 	3
-+#define YAFFS_CHECKPOINT_VERSION 	4
- 
- #ifdef CONFIG_YAFFS_UNICODE
- #define YAFFS_MAX_NAME_LENGTH		127
-@@ -81,12 +82,11 @@
- #define YAFFS_OBJECTID_UNLINKED		3
- #define YAFFS_OBJECTID_DELETED		4
- 
--/* Sseudo object ids for checkpointing */
-+/* Pseudo object ids for checkpointing */
- #define YAFFS_OBJECTID_SB_HEADER	0x10
- #define YAFFS_OBJECTID_CHECKPOINT_DATA	0x20
- #define YAFFS_SEQUENCE_CHECKPOINT_DATA  0x21
- 
--/* */
- 
- #define YAFFS_MAX_SHORT_OP_CACHES	20
- 
-@@ -113,18 +113,14 @@
- 
- /* ChunkCache is used for short read/write operations.*/
- typedef struct {
--	struct yaffs_ObjectStruct *object;
--	int chunkId;
--	int lastUse;
-+	struct yaffs_obj_s *object;
-+	int chunk_id;
-+	int last_use;
- 	int dirty;
--	int nBytes;		/* Only valid if the cache is dirty */
-+	int n_bytes;		/* Only valid if the cache is dirty */
- 	int locked;		/* Can't push out or flush while locked. */
--#ifdef CONFIG_YAFFS_YAFFS2
- 	__u8 *data;
--#else
--	__u8 data[YAFFS_BYTES_PER_CHUNK];
--#endif
--} yaffs_ChunkCache;
-+} yaffs_cache_t;
- 
- 
- 
-@@ -135,18 +131,18 @@ typedef struct {
- 
- #ifndef CONFIG_YAFFS_NO_YAFFS1
- typedef struct {
--	unsigned chunkId:20;
--	unsigned serialNumber:2;
--	unsigned byteCountLSB:10;
--	unsigned objectId:18;
-+	unsigned chunk_id:20;
-+	unsigned serial_number:2;
-+	unsigned n_bytes_lsb:10;
-+	unsigned obj_id:18;
- 	unsigned ecc:12;
--	unsigned byteCountMSB:2;
--} yaffs_Tags;
-+	unsigned n_bytes_msb:2;
-+} yaffs_tags_t;
- 
- typedef union {
--	yaffs_Tags asTags;
--	__u8 asBytes[8];
--} yaffs_TagsUnion;
-+	yaffs_tags_t as_tags;
-+	__u8 as_bytes[8];
-+} yaffs_tags_union_t;
- 
- #endif
- 
-@@ -157,7 +153,7 @@ typedef enum {
- 	YAFFS_ECC_RESULT_NO_ERROR,
- 	YAFFS_ECC_RESULT_FIXED,
- 	YAFFS_ECC_RESULT_UNFIXED
--} yaffs_ECCResult;
-+} yaffs_ecc_result;
- 
- typedef enum {
- 	YAFFS_OBJECT_TYPE_UNKNOWN,
-@@ -166,64 +162,64 @@ typedef enum {
- 	YAFFS_OBJECT_TYPE_DIRECTORY,
- 	YAFFS_OBJECT_TYPE_HARDLINK,
- 	YAFFS_OBJECT_TYPE_SPECIAL
--} yaffs_ObjectType;
-+} yaffs_obj_type;
- 
- #define YAFFS_OBJECT_TYPE_MAX YAFFS_OBJECT_TYPE_SPECIAL
- 
- typedef struct {
- 
--	unsigned validMarker0;
--	unsigned chunkUsed;	/*  Status of the chunk: used or unused */
--	unsigned objectId;	/* If 0 then this is not part of an object (unused) */
--	unsigned chunkId;	/* If 0 then this is a header, else a data chunk */
--	unsigned byteCount;	/* Only valid for data chunks */
-+	unsigned validity1;
-+	unsigned chunk_used;	/*  Status of the chunk: used or unused */
-+	unsigned obj_id;	/* If 0 then this is not part of an object (unused) */
-+	unsigned chunk_id;	/* If 0 then this is a header, else a data chunk */
-+	unsigned n_bytes;	/* Only valid for data chunks */
- 
- 	/* The following stuff only has meaning when we read */
--	yaffs_ECCResult eccResult;
--	unsigned blockBad;
-+	yaffs_ecc_result ecc_result;
-+	unsigned block_bad;
- 
- 	/* YAFFS 1 stuff */
--	unsigned chunkDeleted;	/* The chunk is marked deleted */
--	unsigned serialNumber;	/* Yaffs1 2-bit serial number */
-+	unsigned is_deleted;	/* The chunk is marked deleted */
-+	unsigned serial_number;	/* Yaffs1 2-bit serial number */
- 
- 	/* YAFFS2 stuff */
--	unsigned sequenceNumber;	/* The sequence number of this block */
-+	unsigned seq_number;	/* The sequence number of this block */
- 
- 	/* Extra info if this is an object header (YAFFS2 only) */
- 
--	unsigned extraHeaderInfoAvailable;	/* There is extra info available if this is not zero */
--	unsigned extraParentObjectId;	/* The parent object */
--	unsigned extraIsShrinkHeader;	/* Is it a shrink header? */
--	unsigned extraShadows;		/* Does this shadow another object? */
-+	unsigned extra_available;	/* There is extra info available if this is not zero */
-+	unsigned extra_parent_id;	/* The parent object */
-+	unsigned extra_is_shrink;	/* Is it a shrink header? */
-+	unsigned extra_shadows;		/* Does this shadow another object? */
- 
--	yaffs_ObjectType extraObjectType;	/* What object type? */
-+	yaffs_obj_type extra_obj_type;	/* What object type? */
- 
--	unsigned extraFileLength;		/* Length if it is a file */
--	unsigned extraEquivalentObjectId;	/* Equivalent object Id if it is a hard link */
-+	unsigned extra_length;		/* Length if it is a file */
-+	unsigned extra_equiv_id;	/* Equivalent object Id if it is a hard link */
- 
--	unsigned validMarker1;
-+	unsigned validty1;
- 
--} yaffs_ExtendedTags;
-+} yaffs_ext_tags;
- 
- /* Spare structure for YAFFS1 */
- typedef struct {
--	__u8 tagByte0;
--	__u8 tagByte1;
--	__u8 tagByte2;
--	__u8 tagByte3;
--	__u8 pageStatus;	/* set to 0 to delete the chunk */
--	__u8 blockStatus;
--	__u8 tagByte4;
--	__u8 tagByte5;
-+	__u8 tb0;
-+	__u8 tb1;
-+	__u8 tb2;
-+	__u8 tb3;
-+	__u8 page_status;	/* set to 0 to delete the chunk */
-+	__u8 block_status;
-+	__u8 tb4;
-+	__u8 tb5;
- 	__u8 ecc1[3];
--	__u8 tagByte6;
--	__u8 tagByte7;
-+	__u8 tb6;
-+	__u8 tb7;
- 	__u8 ecc2[3];
--} yaffs_Spare;
-+} yaffs_spare;
- 
- /*Special structure for passing through to mtd */
--struct yaffs_NANDSpare {
--	yaffs_Spare spare;
-+struct yaffs_nand_spare {
-+	yaffs_spare spare;
- 	int eccres1;
- 	int eccres2;
- };
-@@ -234,6 +230,8 @@ typedef enum {
- 	YAFFS_BLOCK_STATE_UNKNOWN = 0,
- 
- 	YAFFS_BLOCK_STATE_SCANNING,
-+        /* Being scanned */
-+
- 	YAFFS_BLOCK_STATE_NEEDS_SCANNING,
- 	/* The block might have something on it (ie it is allocating or full, perhaps empty)
- 	 * but it needs to be scanned to determine its true state.
-@@ -249,67 +247,69 @@ typedef enum {
- 	/* This block is partially allocated.
- 	 * At least one page holds valid data.
- 	 * This is the one currently being used for page
--	 * allocation. Should never be more than one of these
-+	 * allocation. Should never be more than one of these.
-+         * If a block is only partially allocated at mount it is treated as full.
- 	 */
- 
- 	YAFFS_BLOCK_STATE_FULL,
- 	/* All the pages in this block have been allocated.
-+         * If a block was only partially allocated when mounted we treat
-+         * it as fully allocated.
- 	 */
- 
- 	YAFFS_BLOCK_STATE_DIRTY,
--	/* All pages have been allocated and deleted.
-+	/* The block was full and now all chunks have been deleted.
- 	 * Erase me, reuse me.
- 	 */
- 
- 	YAFFS_BLOCK_STATE_CHECKPOINT,
--	/* This block is assigned to holding checkpoint data.
--	 */
-+	/* This block is assigned to holding checkpoint data. */
- 
- 	YAFFS_BLOCK_STATE_COLLECTING,
- 	/* This block is being garbage collected */
- 
- 	YAFFS_BLOCK_STATE_DEAD
- 	/* This block has failed and is not in use */
--} yaffs_BlockState;
-+} yaffs_block_state_t;
- 
- #define	YAFFS_NUMBER_OF_BLOCK_STATES (YAFFS_BLOCK_STATE_DEAD + 1)
- 
- 
- typedef struct {
- 
--	int softDeletions:10;	/* number of soft deleted pages */
--	int pagesInUse:10;	/* number of pages in use */
--	unsigned blockState:4;	/* One of the above block states. NB use unsigned because enum is sometimes an int */
--	__u32 needsRetiring:1;	/* Data has failed on this block, need to get valid data off */
-+	int soft_del_pages:10;	/* number of soft deleted pages */
-+	int pages_in_use:10;	/* number of pages in use */
-+	unsigned block_state:4;	/* One of the above block states. NB use unsigned because enum is sometimes an int */
-+	__u32 needs_retiring:1;	/* Data has failed on this block, need to get valid data off */
- 				/* and retire the block. */
--	__u32 skipErasedCheck:1; /* If this is set we can skip the erased check on this block */
--	__u32 gcPrioritise:1; 	/* An ECC check or blank check has failed on this block.
-+	__u32 skip_erased_check:1; /* If this is set we can skip the erased check on this block */
-+	__u32 gc_prioritise:1; 	/* An ECC check or blank check has failed on this block.
- 				   It should be prioritised for GC */
--	__u32 chunkErrorStrikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
-+	__u32 chunk_error_strikes:3; /* How many times we've had ecc etc failures on this block and tried to reuse it */
- 
- #ifdef CONFIG_YAFFS_YAFFS2
--	__u32 hasShrinkHeader:1; /* This block has at least one shrink object header */
--	__u32 sequenceNumber;	 /* block sequence number for yaffs2 */
-+	__u32 has_shrink_hdr:1; /* This block has at least one shrink object header */
-+	__u32 seq_number;	 /* block sequence number for yaffs2 */
- #endif
- 
--} yaffs_BlockInfo;
-+} yaffs_block_info_t;
- 
- /* -------------------------- Object structure -------------------------------*/
- /* This is the object structure as stored on NAND */
- 
- typedef struct {
--	yaffs_ObjectType type;
-+	yaffs_obj_type type;
- 
- 	/* Apply to everything  */
--	int parentObjectId;
--	__u16 sum__NoLongerUsed;        /* checksum of name. No longer used */
-+	int parent_obj_id;
-+	__u16 sum_no_longer_used;        /* checksum of name. No longer used */
- 	YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
- 
- 	/* The following apply to directories, files, symlinks - not hard links */
- 	__u32 yst_mode;         /* protection */
- 
- #ifdef CONFIG_YAFFS_WINCE
--	__u32 notForWinCE[5];
-+	__u32 not_for_wince[5];
- #else
- 	__u32 yst_uid;
- 	__u32 yst_gid;
-@@ -319,10 +319,10 @@ typedef struct {
- #endif
- 
- 	/* File size  applies to files only */
--	int fileSize;
-+	int file_size;
- 
- 	/* Equivalent object id applies to hard links only. */
--	int equivalentObjectId;
-+	int equiv_id;
- 
- 	/* Alias is for symlinks only. */
- 	YCHAR alias[YAFFS_MAX_ALIAS_LENGTH + 1];
-@@ -334,40 +334,29 @@ typedef struct {
- 	__u32 win_atime[2];
- 	__u32 win_mtime[2];
- #else
--	__u32 roomToGrow[6];
-+	__u32 room_to_grow[6];
- 
- #endif
--	__u32 inbandShadowsObject;
--	__u32 inbandIsShrink;
-+	__u32 inband_shadowed_obj_id;
-+	__u32 inband_is_shrink;
- 
--	__u32 reservedSpace[2];
--	int shadowsObject;	/* This object header shadows the specified object if > 0 */
-+	__u32 reserved[2];
-+	int shadows_obj;	/* This object header shadows the specified object if > 0 */
- 
--	/* isShrink applies to object headers written when we shrink the file (ie resize) */
--	__u32 isShrink;
-+	/* is_shrink applies to object headers written when we shrink the file (ie resize) */
-+	__u32 is_shrink;
- 
--} yaffs_ObjectHeader;
-+} yaffs_obj_header;
- 
- /*--------------------------- Tnode -------------------------- */
- 
--union yaffs_Tnode_union {
--#ifdef CONFIG_YAFFS_TNODE_LIST_DEBUG
--	union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL + 1];
--#else
--	union yaffs_Tnode_union *internal[YAFFS_NTNODES_INTERNAL];
--#endif
--/*	__u16 level0[YAFFS_NTNODES_LEVEL0]; */
-+union yaffs_tnode_union {
-+	union yaffs_tnode_union *internal[YAFFS_NTNODES_INTERNAL];
- 
- };
- 
--typedef union yaffs_Tnode_union yaffs_Tnode;
-+typedef union yaffs_tnode_union yaffs_tnode_t;
- 
--struct yaffs_TnodeList_struct {
--	struct yaffs_TnodeList_struct *next;
--	yaffs_Tnode *tnodes;
--};
--
--typedef struct yaffs_TnodeList_struct yaffs_TnodeList;
- 
- /*------------------------  Object -----------------------------*/
- /* An object can be one of:
-@@ -378,82 +367,85 @@ typedef struct yaffs_TnodeList_struct ya
-  */
- 
- typedef struct {
--	__u32 fileSize;
--	__u32 scannedFileSize;
--	__u32 shrinkSize;
--	int topLevel;
--	yaffs_Tnode *top;
--} yaffs_FileStructure;
-+	__u32 file_size;
-+	__u32 scanned_size;
-+	__u32 shrink_size;
-+	int top_level;
-+	yaffs_tnode_t *top;
-+} yaffs_file_s;
- 
- typedef struct {
- 	struct ylist_head children;     /* list of child links */
--} yaffs_DirectoryStructure;
-+	struct ylist_head dirty;	/* Entry for list of dirty directories */
-+} yaffs_dir_s;
- 
- typedef struct {
- 	YCHAR *alias;
--} yaffs_SymLinkStructure;
-+} yaffs_symlink_t;
- 
- typedef struct {
--	struct yaffs_ObjectStruct *equivalentObject;
--	__u32 equivalentObjectId;
--} yaffs_HardLinkStructure;
-+	struct yaffs_obj_s *equiv_obj;
-+	__u32 equiv_id;
-+} yaffs_hard_link_s;
- 
- typedef union {
--	yaffs_FileStructure fileVariant;
--	yaffs_DirectoryStructure directoryVariant;
--	yaffs_SymLinkStructure symLinkVariant;
--	yaffs_HardLinkStructure hardLinkVariant;
--} yaffs_ObjectVariant;
-+	yaffs_file_s file_variant;
-+	yaffs_dir_s dir_variant;
-+	yaffs_symlink_t symlink_variant;
-+	yaffs_hard_link_s hardlink_variant;
-+} yaffs_obj_variant;
-+
-+
- 
--struct yaffs_ObjectStruct {
-+struct yaffs_obj_s {
- 	__u8 deleted:1;		/* This should only apply to unlinked files. */
--	__u8 softDeleted:1;	/* it has also been soft deleted */
-+	__u8 soft_del:1;	/* it has also been soft deleted */
- 	__u8 unlinked:1;	/* An unlinked file. The file should be in the unlinked directory.*/
- 	__u8 fake:1;		/* A fake object has no presence on NAND. */
--	__u8 renameAllowed:1;	/* Some objects are not allowed to be renamed. */
--	__u8 unlinkAllowed:1;
-+	__u8 rename_allowed:1;	/* Some objects are not allowed to be renamed. */
-+	__u8 unlink_allowed:1;
- 	__u8 dirty:1;		/* the object needs to be written to flash */
- 	__u8 valid:1;		/* When the file system is being loaded up, this
- 				 * object might be created before the data
- 				 * is available (ie. file data records appear before the header).
- 				 */
--	__u8 lazyLoaded:1;	/* This object has been lazy loaded and is missing some detail */
-+	__u8 lazy_loaded:1;	/* This object has been lazy loaded and is missing some detail */
- 
--	__u8 deferedFree:1;	/* For Linux kernel. Object is removed from NAND, but is
-+	__u8 defered_free:1;	/* For Linux kernel. Object is removed from NAND, but is
- 				 * still in the inode cache. Free of object is defered.
- 				 * until the inode is released.
- 				 */
--	__u8 beingCreated:1;	/* This object is still being created so skip some checks. */
-+	__u8 being_created:1;	/* This object is still being created so skip some checks. */
-+	__u8 is_shadowed:1;	/* This object is shadowed on the way to being renamed. */
-+
-+	__u8 xattr_known:1;	/* We know if this has object has xattribs or not. */
-+	__u8 has_xattr:1;	/* This object has xattribs. Valid if xattr_known. */
- 
- 	__u8 serial;		/* serial number of chunk in NAND. Cached here */
- 	__u16 sum;		/* sum of the name to speed searching */
- 
--	struct yaffs_DeviceStruct *myDev;       /* The device I'm on */
-+	struct yaffs_dev_s *my_dev;       /* The device I'm on */
- 
--	struct ylist_head hashLink;     /* list of objects in this hash bucket */
-+	struct ylist_head hash_link;     /* list of objects in this hash bucket */
- 
--	struct ylist_head hardLinks;    /* all the equivalent hard linked objects */
-+	struct ylist_head hard_links;    /* all the equivalent hard linked objects */
- 
- 	/* directory structure stuff */
- 	/* also used for linking up the free list */
--	struct yaffs_ObjectStruct *parent;
-+	struct yaffs_obj_s *parent;
- 	struct ylist_head siblings;
- 
- 	/* Where's my object header in NAND? */
--	int hdrChunk;
-+	int hdr_chunk;
- 
--	int nDataChunks;	/* Number of data chunks attached to the file. */
-+	int n_data_chunks;	/* Number of data chunks attached to the file. */
- 
--	__u32 objectId;		/* the object id value */
-+	__u32 obj_id;		/* the object id value */
- 
- 	__u32 yst_mode;
- 
- #ifdef CONFIG_YAFFS_SHORT_NAMES_IN_RAM
--	YCHAR shortName[YAFFS_SHORT_NAME_LENGTH + 1];
--#endif
--
--#ifndef __KERNEL__
--	__u32 inUse;
-+	YCHAR short_name[YAFFS_SHORT_NAME_LENGTH + 1];
- #endif
- 
- #ifdef CONFIG_YAFFS_WINCE
-@@ -470,53 +462,43 @@ struct yaffs_ObjectStruct {
- 
- 	__u32 yst_rdev;
- 
--#ifdef __KERNEL__
--	struct inode *myInode;
-+	void *my_inode;
- 
--#endif
-+	yaffs_obj_type variant_type;
- 
--	yaffs_ObjectType variantType;
-+	yaffs_obj_variant variant;
- 
--	yaffs_ObjectVariant variant;
--
--};
--
--typedef struct yaffs_ObjectStruct yaffs_Object;
--
--struct yaffs_ObjectList_struct {
--	yaffs_Object *objects;
--	struct yaffs_ObjectList_struct *next;
- };
- 
--typedef struct yaffs_ObjectList_struct yaffs_ObjectList;
-+typedef struct yaffs_obj_s yaffs_obj_t;
- 
- typedef struct {
- 	struct ylist_head list;
- 	int count;
--} yaffs_ObjectBucket;
-+} yaffs_obj_bucket;
- 
- 
--/* yaffs_CheckpointObject holds the definition of an object as dumped
-+/* yaffs_checkpt_obj_t holds the definition of an object as dumped
-  * by checkpointing.
-  */
- 
- typedef struct {
--	int structType;
--	__u32 objectId;
--	__u32 parentId;
--	int hdrChunk;
--	yaffs_ObjectType variantType:3;
-+	int struct_type;
-+	__u32 obj_id;
-+	__u32 parent_id;
-+	int hdr_chunk;
-+	yaffs_obj_type variant_type:3;
- 	__u8 deleted:1;
--	__u8 softDeleted:1;
-+	__u8 soft_del:1;
- 	__u8 unlinked:1;
- 	__u8 fake:1;
--	__u8 renameAllowed:1;
--	__u8 unlinkAllowed:1;
-+	__u8 rename_allowed:1;
-+	__u8 unlink_allowed:1;
- 	__u8 serial;
- 
--	int nDataChunks;
--	__u32 fileSizeOrEquivalentObjectId;
--} yaffs_CheckpointObject;
-+	int n_data_chunks;
-+	__u32 size_or_equiv_obj;
-+} yaffs_checkpt_obj_t;
- 
- /*--------------------- Temporary buffers ----------------
-  *
-@@ -526,379 +508,462 @@ typedef struct {
- typedef struct {
- 	__u8 *buffer;
- 	int line;	/* track from whence this buffer was allocated */
--	int maxLine;
--} yaffs_TempBuffer;
-+	int max_line;
-+} yaffs_buffer_t;
- 
- /*----------------- Device ---------------------------------*/
- 
--struct yaffs_DeviceStruct {
--	struct ylist_head devList;
--	const char *name;
--
--	/* Entry parameters set up way early. Yaffs sets up the rest.*/
--	int nDataBytesPerChunk;	/* Should be a power of 2 >= 512 */
--	int nChunksPerBlock;	/* does not need to be a power of 2 */
--	int spareBytesPerChunk;	/* spare area size */
--	int startBlock;		/* Start block we're allowed to use */
--	int endBlock;		/* End block we're allowed to use */
--	int nReservedBlocks;	/* We want this tuneable so that we can reduce */
--				/* reserved blocks on NOR and RAM. */
--
- 
--	/* Stuff used by the shared space checkpointing mechanism */
--	/* If this value is zero, then this mechanism is disabled */
-+struct yaffs_param_s {
-+	const YCHAR *name;
- 
--/*	int nCheckpointReservedBlocks; */ /* Blocks to reserve for checkpoint data */
-+	/*
-+         * Entry parameters set up way early. Yaffs sets up the rest.
-+         * The structure should be zeroed out before use so that unused
-+         * and defualt values are zero.
-+         */
-+
-+	int inband_tags;          /* Use unband tags */
-+	__u32 total_bytes_per_chunk; /* Should be >= 512, does not need to be a power of 2 */
-+	int chunks_per_block;	/* does not need to be a power of 2 */
-+	int spare_bytes_per_chunk;	/* spare area size */
-+	int start_block;		/* Start block we're allowed to use */
-+	int end_block;		/* End block we're allowed to use */
-+	int n_reserved_blocks;	/* We want this tuneable so that we can reduce */
-+				/* reserved blocks on NOR and RAM. */
- 
- 
--	int nShortOpCaches;	/* If <= 0, then short op caching is disabled, else
--				 * the number of short op caches (don't use too many)
-+	int n_caches;	/* If <= 0, then short op caching is disabled, else
-+				 * the number of short op caches (don't use too many).
-+                                 * 10 to 20 is a good bet.
- 				 */
-+	int use_nand_ecc;		/* Flag to decide whether or not to use NANDECC on data (yaffs1) */
-+	int no_tags_ecc;		/* Flag to decide whether or not to do ECC on packed tags (yaffs2) */ 
- 
--	int useHeaderFileSize;	/* Flag to determine if we should use file sizes from the header */
-+	int is_yaffs2;           /* Use yaffs2 mode on this device */
- 
--	int useNANDECC;		/* Flag to decide whether or not to use NANDECC */
-+	int empty_lost_n_found;  /* Auto-empty lost+found directory on mount */
- 
--	void *genericDevice;	/* Pointer to device context
--				 * On an mtd this holds the mtd pointer.
--				 */
--	void *superBlock;
-+	int refresh_period;	/* How often we should check to do a block refresh */
-+
-+	/* Checkpoint control. Can be set before or after initialisation */
-+	__u8 skip_checkpt_rd;
-+	__u8 skip_checkpt_wr;
-+
-+	int enable_xattr;	/* Enable xattribs */
- 
- 	/* NAND access functions (Must be set before calling YAFFS)*/
- 
--	int (*writeChunkToNAND) (struct yaffs_DeviceStruct *dev,
--					int chunkInNAND, const __u8 *data,
--					const yaffs_Spare *spare);
--	int (*readChunkFromNAND) (struct yaffs_DeviceStruct *dev,
--					int chunkInNAND, __u8 *data,
--					yaffs_Spare *spare);
--	int (*eraseBlockInNAND) (struct yaffs_DeviceStruct *dev,
--					int blockInNAND);
--	int (*initialiseNAND) (struct yaffs_DeviceStruct *dev);
--	int (*deinitialiseNAND) (struct yaffs_DeviceStruct *dev);
-+	int (*write_chunk_fn) (struct yaffs_dev_s *dev,
-+					int nand_chunk, const __u8 *data,
-+					const yaffs_spare *spare);
-+	int (*read_chunk_fn) (struct yaffs_dev_s *dev,
-+					int nand_chunk, __u8 *data,
-+					yaffs_spare *spare);
-+	int (*erase_fn) (struct yaffs_dev_s *dev,
-+					int flash_block);
-+	int (*initialise_flash_fn) (struct yaffs_dev_s *dev);
-+	int (*deinitialise_flash_fn) (struct yaffs_dev_s *dev);
- 
- #ifdef CONFIG_YAFFS_YAFFS2
--	int (*writeChunkWithTagsToNAND) (struct yaffs_DeviceStruct *dev,
--					 int chunkInNAND, const __u8 *data,
--					 const yaffs_ExtendedTags *tags);
--	int (*readChunkWithTagsFromNAND) (struct yaffs_DeviceStruct *dev,
--					  int chunkInNAND, __u8 *data,
--					  yaffs_ExtendedTags *tags);
--	int (*markNANDBlockBad) (struct yaffs_DeviceStruct *dev, int blockNo);
--	int (*queryNANDBlock) (struct yaffs_DeviceStruct *dev, int blockNo,
--			       yaffs_BlockState *state, __u32 *sequenceNumber);
--#endif
--
--	int isYaffs2;
--
--	/* The removeObjectCallback function must be supplied by OS flavours that
--	 * need it. The Linux kernel does not use this, but yaffs direct does use
--	 * it to implement the faster readdir
-+	int (*write_chunk_tags_fn) (struct yaffs_dev_s *dev,
-+					 int nand_chunk, const __u8 *data,
-+					 const yaffs_ext_tags *tags);
-+	int (*read_chunk_tags_fn) (struct yaffs_dev_s *dev,
-+					  int nand_chunk, __u8 *data,
-+					  yaffs_ext_tags *tags);
-+	int (*bad_block_fn) (struct yaffs_dev_s *dev, int block_no);
-+	int (*query_block_fn) (struct yaffs_dev_s *dev, int block_no,
-+			       yaffs_block_state_t *state, __u32 *seq_number);
-+#endif
-+
-+	/* The remove_obj_fn function must be supplied by OS flavours that
-+	 * need it.
-+         * yaffs direct uses it to implement the faster readdir.
-+         * Linux uses it to protect the directory during unlocking.
- 	 */
--	void (*removeObjectCallback)(struct yaffs_ObjectStruct *obj);
-+	void (*remove_obj_fn)(struct yaffs_obj_s *obj);
- 
--	/* Callback to mark the superblock dirsty */
--	void (*markSuperBlockDirty)(void *superblock);
-+	/* Callback to mark the superblock dirty */
-+	void (*sb_dirty_fn)(struct yaffs_dev_s *dev);
-+	
-+	/*  Callback to control garbage collection. */
-+	unsigned (*gc_control)(struct yaffs_dev_s *dev);
-+
-+        /* Debug control flags. Don't use unless you know what you're doing */
-+	int use_header_file_size;	/* Flag to determine if we should use file sizes from the header */
-+	int disable_lazy_load;	/* Disable lazy loading on this device */
-+	int wide_tnodes_disabled; /* Set to disable wide tnodes */
-+	int disable_soft_del;  /* yaffs 1 only: Set to disable the use of softdeletion. */
-+	
-+	int defered_dir_update; /* Set to defer directory updates */
- 
--	int wideTnodesDisabled; /* Set to disable wide tnodes */
-+#ifdef CONFIG_YAFFS_AUTO_UNICODE
-+	int auto_unicode;
-+#endif
-+	int always_check_erased; /* Force chunk erased check always on */
-+};
- 
--	YCHAR *pathDividers;	/* String of legal path dividers */
-+typedef struct yaffs_param_s yaffs_param_t;
- 
-+struct yaffs_dev_s {
-+	struct yaffs_param_s param;
- 
--	/* End of stuff that must be set before initialisation. */
-+        /* Context storage. Holds extra OS specific data for this device */
- 
--	/* Checkpoint control. Can be set before or after initialisation */
--	__u8 skipCheckpointRead;
--	__u8 skipCheckpointWrite;
-+	void *os_context;
-+	void *driver_context;
-+
-+	struct ylist_head dev_list;
- 
- 	/* Runtime parameters. Set up by YAFFS. */
-+	int data_bytes_per_chunk;	
- 
--	__u16 chunkGroupBits;	/* 0 for devices <= 32MB. else log2(nchunks) - 16 */
--	__u16 chunkGroupSize;	/* == 2^^chunkGroupBits */
-+        /* Non-wide tnode stuff */
-+	__u16 chunk_grp_bits;	/* Number of bits that need to be resolved if
-+                                 * the tnodes are not wide enough.
-+                                 */
-+	__u16 chunk_grp_size;	/* == 2^^chunk_grp_bits */
- 
- 	/* Stuff to support wide tnodes */
--	__u32 tnodeWidth;
--	__u32 tnodeMask;
-+	__u32 tnode_width;
-+	__u32 tnode_mask;
-+	__u32 tnode_size;
- 
- 	/* Stuff for figuring out file offset to chunk conversions */
--	__u32 chunkShift; /* Shift value */
--	__u32 chunkDiv;   /* Divisor after shifting: 1 for power-of-2 sizes */
--	__u32 chunkMask;  /* Mask to use for power-of-2 case */
--
--	/* Stuff to handle inband tags */
--	int inbandTags;
--	__u32 totalBytesPerChunk;
--
--#ifdef __KERNEL__
--
--	struct semaphore sem;	/* Semaphore for waiting on erasure.*/
--	struct semaphore grossLock;	/* Gross locking semaphore */
--	__u8 *spareBuffer;	/* For mtdif2 use. Don't know the size of the buffer
--				 * at compile time so we have to allocate it.
--				 */
--	void (*putSuperFunc) (struct super_block *sb);
--#endif
-+	__u32 chunk_shift; /* Shift value */
-+	__u32 chunk_div;   /* Divisor after shifting: 1 for power-of-2 sizes */
-+	__u32 chunk_mask;  /* Mask to use for power-of-2 case */
- 
--	int isMounted;
- 
--	int isCheckpointed;
-+
-+	int is_mounted;
-+	int read_only;
-+	int is_checkpointed;
- 
- 
- 	/* Stuff to support block offsetting to support start block zero */
--	int internalStartBlock;
--	int internalEndBlock;
--	int blockOffset;
--	int chunkOffset;
-+	int internal_start_block;
-+	int internal_end_block;
-+	int block_offset;
-+	int chunk_offset;
- 
- 
- 	/* Runtime checkpointing stuff */
--	int checkpointPageSequence;   /* running sequence number of checkpoint pages */
--	int checkpointByteCount;
--	int checkpointByteOffset;
--	__u8 *checkpointBuffer;
--	int checkpointOpenForWrite;
--	int blocksInCheckpoint;
--	int checkpointCurrentChunk;
--	int checkpointCurrentBlock;
--	int checkpointNextBlock;
--	int *checkpointBlockList;
--	int checkpointMaxBlocks;
--	__u32 checkpointSum;
--	__u32 checkpointXor;
-+	int checkpt_page_seq;   /* running sequence number of checkpoint pages */
-+	int checkpt_byte_count;
-+	int checkpt_byte_offs;
-+	__u8 *checkpt_buffer;
-+	int checkpt_open_write;
-+	int blocks_in_checkpt;
-+	int checkpt_cur_chunk;
-+	int checkpt_cur_block;
-+	int checkpt_next_block;
-+	int *checkpt_block_list;
-+	int checkpt_max_blocks;
-+	__u32 checkpt_sum;
-+	__u32 checkpt_xor;
- 
--	int nCheckpointBlocksRequired; /* Number of blocks needed to store current checkpoint set */
-+	int checkpoint_blocks_required; /* Number of blocks needed to store current checkpoint set */
- 
- 	/* Block Info */
--	yaffs_BlockInfo *blockInfo;
--	__u8 *chunkBits;	/* bitmap of chunks in use */
--	unsigned blockInfoAlt:1;	/* was allocated using alternative strategy */
--	unsigned chunkBitsAlt:1;	/* was allocated using alternative strategy */
--	int chunkBitmapStride;	/* Number of bytes of chunkBits per block.
--				 * Must be consistent with nChunksPerBlock.
-+	yaffs_block_info_t *block_info;
-+	__u8 *chunk_bits;	/* bitmap of chunks in use */
-+	unsigned block_info_alt:1;	/* was allocated using alternative strategy */
-+	unsigned chunk_bits_alt:1;	/* was allocated using alternative strategy */
-+	int chunk_bit_stride;	/* Number of bytes of chunk_bits per block.
-+				 * Must be consistent with chunks_per_block.
- 				 */
- 
--	int nErasedBlocks;
--	int allocationBlock;	/* Current block being allocated off */
--	__u32 allocationPage;
--	int allocationBlockFinder;	/* Used to search for next allocation block */
--
--	/* Runtime state */
--	int nTnodesCreated;
--	yaffs_Tnode *freeTnodes;
--	int nFreeTnodes;
--	yaffs_TnodeList *allocatedTnodeList;
--
--	int isDoingGC;
--	int gcBlock;
--	int gcChunk;
--
--	int nObjectsCreated;
--	yaffs_Object *freeObjects;
--	int nFreeObjects;
--
--	int nHardLinks;
--
--	yaffs_ObjectList *allocatedObjectList;
--
--	yaffs_ObjectBucket objectBucket[YAFFS_NOBJECT_BUCKETS];
--
--	int nFreeChunks;
--
--	int currentDirtyChecker;	/* Used to find current dirtiest block */
--
--	__u32 *gcCleanupList;	/* objects to delete at the end of a GC. */
--	int nonAggressiveSkip;	/* GC state/mode */
--
--	/* Statistcs */
--	int nPageWrites;
--	int nPageReads;
--	int nBlockErasures;
--	int nErasureFailures;
--	int nGCCopies;
--	int garbageCollections;
--	int passiveGarbageCollections;
--	int nRetriedWrites;
--	int nRetiredBlocks;
--	int eccFixed;
--	int eccUnfixed;
--	int tagsEccFixed;
--	int tagsEccUnfixed;
--	int nDeletions;
--	int nUnmarkedDeletions;
--
--	int hasPendingPrioritisedGCs; /* We think this device might have pending prioritised gcs */
-+	int n_erased_blocks;
-+	int alloc_block;	/* Current block being allocated off */
-+	__u32 alloc_page;
-+	int alloc_block_finder;	/* Used to search for next allocation block */
-+
-+	/* Object and Tnode memory management */
-+	void *allocator;
-+	int n_obj;
-+	int n_tnodes;
-+
-+	int n_hardlinks;
-+
-+	yaffs_obj_bucket obj_bucket[YAFFS_NOBJECT_BUCKETS];
-+	__u32 bucket_finder;
-+
-+	int n_free_chunks;
-+
-+	/* Garbage collection control */
-+	__u32 *gc_cleanup_list;	/* objects to delete at the end of a GC. */
-+	__u32 n_clean_ups;
-+
-+	unsigned has_pending_prioritised_gc; /* We think this device might have pending prioritised gcs */
-+	unsigned gc_disable;
-+	unsigned gc_block_finder;
-+	unsigned gc_dirtiest;
-+	unsigned gc_pages_in_use;
-+	unsigned gc_not_done;
-+	unsigned gc_block;
-+	unsigned gc_chunk;
-+	unsigned gc_skip;
- 
- 	/* Special directories */
--	yaffs_Object *rootDir;
--	yaffs_Object *lostNFoundDir;
-+	yaffs_obj_t *root_dir;
-+	yaffs_obj_t *lost_n_found;
- 
- 	/* Buffer areas for storing data to recover from write failures TODO
--	 *      __u8            bufferedData[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK];
--	 *      yaffs_Spare bufferedSpare[YAFFS_CHUNKS_PER_BLOCK];
-+	 *      __u8            buffered_data[YAFFS_CHUNKS_PER_BLOCK][YAFFS_BYTES_PER_CHUNK];
-+	 *      yaffs_spare buffered_spare[YAFFS_CHUNKS_PER_BLOCK];
- 	 */
- 
--	int bufferedBlock;	/* Which block is buffered here? */
--	int doingBufferedBlockRewrite;
--
--	yaffs_ChunkCache *srCache;
--	int srLastUse;
-+	int buffered_block;	/* Which block is buffered here? */
-+	int doing_buffered_block_rewrite;
- 
--	int cacheHits;
-+	yaffs_cache_t *cache;
-+	int cache_last_use;
- 
- 	/* Stuff for background deletion and unlinked files.*/
--	yaffs_Object *unlinkedDir;	/* Directory where unlinked and deleted files live. */
--	yaffs_Object *deletedDir;	/* Directory where deleted objects are sent to disappear. */
--	yaffs_Object *unlinkedDeletion;	/* Current file being background deleted.*/
--	int nDeletedFiles;		/* Count of files awaiting deletion;*/
--	int nUnlinkedFiles;		/* Count of unlinked files. */
--	int nBackgroundDeletions;	/* Count of background deletions. */
--
-+	yaffs_obj_t *unlinked_dir;	/* Directory where unlinked and deleted files live. */
-+	yaffs_obj_t *del_dir;	/* Directory where deleted objects are sent to disappear. */
-+	yaffs_obj_t *unlinked_deletion;	/* Current file being background deleted.*/
-+	int n_deleted_files;		/* Count of files awaiting deletion;*/
-+	int n_unlinked_files;		/* Count of unlinked files. */
-+	int n_bg_deletions;	/* Count of background deletions. */
- 
- 	/* Temporary buffer management */
--	yaffs_TempBuffer tempBuffer[YAFFS_N_TEMP_BUFFERS];
--	int maxTemp;
--	int tempInUse;
--	int unmanagedTempAllocations;
--	int unmanagedTempDeallocations;
-+	yaffs_buffer_t temp_buffer[YAFFS_N_TEMP_BUFFERS];
-+	int max_temp;
-+	int temp_in_use;
-+	int unmanaged_buffer_allocs;
-+	int unmanaged_buffer_deallocs;
- 
- 	/* yaffs2 runtime stuff */
--	unsigned sequenceNumber;	/* Sequence number of currently allocating block */
--	unsigned oldestDirtySequence;
-+	unsigned seq_number;	/* Sequence number of currently allocating block */
-+	unsigned oldest_dirty_seq;
-+	unsigned oldest_dirty_block;
-+
-+	/* Block refreshing */
-+	int refresh_skip;	/* A skip down counter. Refresh happens when this gets to zero. */
-+
-+	/* Dirty directory handling */
-+	struct ylist_head dirty_dirs; /* List of dirty directories */
-+
-+
-+	/* Statistcs */
-+	__u32 n_page_writes;
-+	__u32 n_page_reads;
-+	__u32 n_erasures;
-+	__u32 n_erase_failures;
-+	__u32 n_gc_copies;
-+	__u32 all_gcs;
-+	__u32 passive_gc_count;
-+	__u32 oldest_dirty_gc_count;
-+	__u32 n_gc_blocks;
-+	__u32 bg_gcs;
-+	__u32 n_retired_writes;
-+	__u32 n_retired_blocks;
-+	__u32 n_ecc_fixed;
-+	__u32 n_ecc_unfixed;
-+	__u32 n_tags_ecc_fixed;
-+	__u32 n_tags_ecc_unfixed;
-+	__u32 n_deletions;
-+	__u32 n_unmarked_deletions;
-+	__u32 refresh_count;
-+	__u32 cache_hits;
- 
- };
- 
--typedef struct yaffs_DeviceStruct yaffs_Device;
-+typedef struct yaffs_dev_s yaffs_dev_t;
- 
- /* The static layout of block usage etc is stored in the super block header */
- typedef struct {
- 	int StructType;
- 	int version;
--	int checkpointStartBlock;
--	int checkpointEndBlock;
--	int startBlock;
--	int endBlock;
-+	int checkpt_start_block;
-+	int checkpt_end_block;
-+	int start_block;
-+	int end_block;
- 	int rfu[100];
--} yaffs_SuperBlockHeader;
-+} yaffs_sb_header;
- 
- /* The CheckpointDevice structure holds the device information that changes at runtime and
-  * must be preserved over unmount/mount cycles.
-  */
- typedef struct {
--	int structType;
--	int nErasedBlocks;
--	int allocationBlock;	/* Current block being allocated off */
--	__u32 allocationPage;
--	int nFreeChunks;
--
--	int nDeletedFiles;		/* Count of files awaiting deletion;*/
--	int nUnlinkedFiles;		/* Count of unlinked files. */
--	int nBackgroundDeletions;	/* Count of background deletions. */
-+	int struct_type;
-+	int n_erased_blocks;
-+	int alloc_block;	/* Current block being allocated off */
-+	__u32 alloc_page;
-+	int n_free_chunks;
-+
-+	int n_deleted_files;		/* Count of files awaiting deletion;*/
-+	int n_unlinked_files;		/* Count of unlinked files. */
-+	int n_bg_deletions;	/* Count of background deletions. */
- 
- 	/* yaffs2 runtime stuff */
--	unsigned sequenceNumber;	/* Sequence number of currently allocating block */
--	unsigned oldestDirtySequence;
-+	unsigned seq_number;	/* Sequence number of currently allocating block */
- 
--} yaffs_CheckpointDevice;
-+} yaffs_checkpt_dev_t;
- 
- 
- typedef struct {
--	int structType;
-+	int struct_type;
- 	__u32 magic;
- 	__u32 version;
- 	__u32 head;
--} yaffs_CheckpointValidity;
-+} yaffs_checkpt_validty_t;
-+
-+
-+struct yaffs_shadow_fixer_s {
-+	int obj_id;
-+	int shadowed_id;
-+	struct yaffs_shadow_fixer_s *next;
-+};
-+
-+/* Structure for doing xattr modifications */
-+typedef struct {
-+	int set; /* If 0 then this is a deletion */
-+	const YCHAR *name;
-+	const void *data;
-+	int size;
-+	int flags;
-+	int result;
-+}yaffs_xattr_mod;
- 
- 
- /*----------------------- YAFFS Functions -----------------------*/
- 
--int yaffs_GutsInitialise(yaffs_Device *dev);
--void yaffs_Deinitialise(yaffs_Device *dev);
-+int yaffs_guts_initialise(yaffs_dev_t *dev);
-+void yaffs_deinitialise(yaffs_dev_t *dev);
- 
--int yaffs_GetNumberOfFreeChunks(yaffs_Device *dev);
-+int yaffs_get_n_free_chunks(yaffs_dev_t *dev);
- 
--int yaffs_RenameObject(yaffs_Object *oldDir, const YCHAR *oldName,
--		       yaffs_Object *newDir, const YCHAR *newName);
-+int yaffs_rename_obj(yaffs_obj_t *old_dir, const YCHAR *old_name,
-+		       yaffs_obj_t *new_dir, const YCHAR *new_name);
- 
--int yaffs_Unlink(yaffs_Object *dir, const YCHAR *name);
--int yaffs_DeleteObject(yaffs_Object *obj);
-+int yaffs_unlinker(yaffs_obj_t *dir, const YCHAR *name);
-+int yaffs_del_obj(yaffs_obj_t *obj);
- 
--int yaffs_GetObjectName(yaffs_Object *obj, YCHAR *name, int buffSize);
--int yaffs_GetObjectFileLength(yaffs_Object *obj);
--int yaffs_GetObjectInode(yaffs_Object *obj);
--unsigned yaffs_GetObjectType(yaffs_Object *obj);
--int yaffs_GetObjectLinkCount(yaffs_Object *obj);
-+int yaffs_get_obj_name(yaffs_obj_t *obj, YCHAR *name, int buffer_size);
-+int yaffs_get_obj_length(yaffs_obj_t *obj);
-+int yaffs_get_obj_inode(yaffs_obj_t *obj);
-+unsigned yaffs_get_obj_type(yaffs_obj_t *obj);
-+int yaffs_get_obj_link_count(yaffs_obj_t *obj);
- 
--int yaffs_SetAttributes(yaffs_Object *obj, struct iattr *attr);
--int yaffs_GetAttributes(yaffs_Object *obj, struct iattr *attr);
-+int yaffs_set_attribs(yaffs_obj_t *obj, struct iattr *attr);
-+int yaffs_get_attribs(yaffs_obj_t *obj, struct iattr *attr);
- 
- /* File operations */
--int yaffs_ReadDataFromFile(yaffs_Object *obj, __u8 *buffer, loff_t offset,
--				int nBytes);
--int yaffs_WriteDataToFile(yaffs_Object *obj, const __u8 *buffer, loff_t offset,
--				int nBytes, int writeThrough);
--int yaffs_ResizeFile(yaffs_Object *obj, loff_t newSize);
-+int yaffs_file_rd(yaffs_obj_t *obj, __u8 *buffer, loff_t offset,
-+				int n_bytes);
-+int yaffs_wr_file(yaffs_obj_t *obj, const __u8 *buffer, loff_t offset,
-+				int n_bytes, int write_trhrough);
-+int yaffs_resize_file(yaffs_obj_t *obj, loff_t new_size);
- 
--yaffs_Object *yaffs_MknodFile(yaffs_Object *parent, const YCHAR *name,
-+yaffs_obj_t *yaffs_create_file(yaffs_obj_t *parent, const YCHAR *name,
- 				__u32 mode, __u32 uid, __u32 gid);
--int yaffs_FlushFile(yaffs_Object *obj, int updateTime);
-+
-+int yaffs_flush_file(yaffs_obj_t *obj, int update_time, int data_sync);
- 
- /* Flushing and checkpointing */
--void yaffs_FlushEntireDeviceCache(yaffs_Device *dev);
-+void yaffs_flush_whole_cache(yaffs_dev_t *dev);
- 
--int yaffs_CheckpointSave(yaffs_Device *dev);
--int yaffs_CheckpointRestore(yaffs_Device *dev);
-+int yaffs_checkpoint_save(yaffs_dev_t *dev);
-+int yaffs_checkpoint_restore(yaffs_dev_t *dev);
- 
- /* Directory operations */
--yaffs_Object *yaffs_MknodDirectory(yaffs_Object *parent, const YCHAR *name,
-+yaffs_obj_t *yaffs_create_dir(yaffs_obj_t *parent, const YCHAR *name,
- 				__u32 mode, __u32 uid, __u32 gid);
--yaffs_Object *yaffs_FindObjectByName(yaffs_Object *theDir, const YCHAR *name);
--int yaffs_ApplyToDirectoryChildren(yaffs_Object *theDir,
--				   int (*fn) (yaffs_Object *));
-+yaffs_obj_t *yaffs_find_by_name(yaffs_obj_t *the_dir, const YCHAR *name);
-+int yaffs_ApplyToDirectoryChildren(yaffs_obj_t *the_dir,
-+				   int (*fn) (yaffs_obj_t *));
- 
--yaffs_Object *yaffs_FindObjectByNumber(yaffs_Device *dev, __u32 number);
-+yaffs_obj_t *yaffs_find_by_number(yaffs_dev_t *dev, __u32 number);
- 
- /* Link operations */
--yaffs_Object *yaffs_Link(yaffs_Object *parent, const YCHAR *name,
--			 yaffs_Object *equivalentObject);
-+yaffs_obj_t *yaffs_link_obj(yaffs_obj_t *parent, const YCHAR *name,
-+			 yaffs_obj_t *equiv_obj);
- 
--yaffs_Object *yaffs_GetEquivalentObject(yaffs_Object *obj);
-+yaffs_obj_t *yaffs_get_equivalent_obj(yaffs_obj_t *obj);
- 
- /* Symlink operations */
--yaffs_Object *yaffs_MknodSymLink(yaffs_Object *parent, const YCHAR *name,
-+yaffs_obj_t *yaffs_create_symlink(yaffs_obj_t *parent, const YCHAR *name,
- 				 __u32 mode, __u32 uid, __u32 gid,
- 				 const YCHAR *alias);
--YCHAR *yaffs_GetSymlinkAlias(yaffs_Object *obj);
-+YCHAR *yaffs_get_symlink_alias(yaffs_obj_t *obj);
- 
- /* Special inodes (fifos, sockets and devices) */
--yaffs_Object *yaffs_MknodSpecial(yaffs_Object *parent, const YCHAR *name,
-+yaffs_obj_t *yaffs_create_special(yaffs_obj_t *parent, const YCHAR *name,
- 				 __u32 mode, __u32 uid, __u32 gid, __u32 rdev);
- 
-+
-+int yaffs_set_xattrib(yaffs_obj_t *obj, const YCHAR *name, const void * value, int size, int flags);
-+int yaffs_get_xattrib(yaffs_obj_t *obj, const YCHAR *name, void *value, int size);
-+int yaffs_list_xattrib(yaffs_obj_t *obj, char *buffer, int size);
-+int yaffs_remove_xattrib(yaffs_obj_t *obj, const YCHAR *name);
-+
- /* Special directories */
--yaffs_Object *yaffs_Root(yaffs_Device *dev);
--yaffs_Object *yaffs_LostNFound(yaffs_Device *dev);
-+yaffs_obj_t *yaffs_root(yaffs_dev_t *dev);
-+yaffs_obj_t *yaffs_lost_n_found(yaffs_dev_t *dev);
- 
- #ifdef CONFIG_YAFFS_WINCE
- /* CONFIG_YAFFS_WINCE special stuff */
--void yfsd_WinFileTimeNow(__u32 target[2]);
-+void yfsd_win_file_time_now(__u32 target[2]);
- #endif
- 
--#ifdef __KERNEL__
-+void yaffs_handle_defered_free(yaffs_obj_t *obj);
- 
--void yaffs_HandleDeferedFree(yaffs_Object *obj);
--#endif
-+void yaffs_update_dirty_dirs(yaffs_dev_t *dev);
-+
-+int yaffs_bg_gc(yaffs_dev_t *dev, unsigned urgency);
- 
- /* Debug dump  */
--int yaffs_DumpObject(yaffs_Object *obj);
-+int yaffs_dump_obj(yaffs_obj_t *obj);
- 
--void yaffs_GutsTest(yaffs_Device *dev);
-+void yaffs_guts_test(yaffs_dev_t *dev);
- 
--/* A few useful functions */
--void yaffs_InitialiseTags(yaffs_ExtendedTags *tags);
--void yaffs_DeleteChunk(yaffs_Device *dev, int chunkId, int markNAND, int lyn);
--int yaffs_CheckFF(__u8 *buffer, int nBytes);
--void yaffs_HandleChunkError(yaffs_Device *dev, yaffs_BlockInfo *bi);
-+/* A few useful functions to be used within the core files*/
-+void yaffs_chunk_del(yaffs_dev_t *dev, int chunk_id, int mark_flash, int lyn);
-+int yaffs_check_ff(__u8 *buffer, int n_bytes);
-+void yaffs_handle_chunk_error(yaffs_dev_t *dev, yaffs_block_info_t *bi);
-+
-+__u8 *yaffs_get_temp_buffer(yaffs_dev_t *dev, int line_no);
-+void yaffs_release_temp_buffer(yaffs_dev_t *dev, __u8 *buffer, int line_no);
-+
-+yaffs_obj_t *yaffs_find_or_create_by_number(yaffs_dev_t *dev,
-+					        int number,
-+					        yaffs_obj_type type);
-+int yaffs_put_chunk_in_file(yaffs_obj_t *in, int inode_chunk,
-+			        int nand_chunk, int in_scan);
-+void yaffs_set_obj_name(yaffs_obj_t *obj, const YCHAR *name);
-+void yaffs_set_obj_name_from_oh(yaffs_obj_t *obj, const yaffs_obj_header *oh);
-+void yaffs_add_obj_to_dir(yaffs_obj_t *directory,
-+					yaffs_obj_t *obj);
-+YCHAR *yaffs_clone_str(const YCHAR *str);
-+void yaffs_link_fixup(yaffs_dev_t *dev, yaffs_obj_t *hard_list);
-+void yaffs_block_became_dirty(yaffs_dev_t *dev, int block_no);
-+int yaffs_update_oh(yaffs_obj_t *in, const YCHAR *name,
-+				int force, int is_shrink, int shadows,
-+                                yaffs_xattr_mod *xop);
-+void yaffs_handle_shadowed_obj(yaffs_dev_t *dev, int obj_id,
-+				int backward_scanning);
-+int yaffs_check_alloc_available(yaffs_dev_t *dev, int n_chunks);
-+yaffs_tnode_t *yaffs_get_tnode(yaffs_dev_t *dev);
-+yaffs_tnode_t *yaffs_add_find_tnode_0(yaffs_dev_t *dev,
-+					yaffs_file_s *file_struct,
-+					__u32 chunk_id,
-+					yaffs_tnode_t *passed_tn);
-+
-+int yaffs_do_file_wr(yaffs_obj_t *in, const __u8 *buffer, loff_t offset,
-+			int n_bytes, int write_trhrough);
-+void yaffs_resize_file_down( yaffs_obj_t *obj, loff_t new_size);
-+void yaffs_skip_rest_of_block(yaffs_dev_t *dev);
-+
-+int yaffs_count_free_chunks(yaffs_dev_t *dev);
-+
-+yaffs_tnode_t *yaffs_find_tnode_0(yaffs_dev_t *dev,
-+				yaffs_file_s *file_struct,
-+				__u32 chunk_id);
- 
--__u8 *yaffs_GetTempBuffer(yaffs_Device *dev, int lineNo);
--void yaffs_ReleaseTempBuffer(yaffs_Device *dev, __u8 *buffer, int lineNo);
-+__u32 yaffs_get_group_base(yaffs_dev_t *dev, yaffs_tnode_t *tn, unsigned pos);
- 
- #endif
---- a/fs/yaffs2/yaffsinterface.h
-+++ b/fs/yaffs2/yaffsinterface.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -16,6 +16,6 @@
- #ifndef __YAFFSINTERFACE_H__
- #define __YAFFSINTERFACE_H__
- 
--int yaffs_Initialise(unsigned nBlocks);
-+int yaffs_initialise(unsigned nBlocks);
- 
- #endif
---- /dev/null
-+++ b/fs/yaffs2/yaffs_linux_allocator.c
-@@ -0,0 +1,200 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ *
-+ * Note: Tis code is currently unused. Being checked in in case it becomes useful.
-+ */
-+
-+
-+#include "yaffs_allocator.h"
-+#include "yaffs_guts.h"
-+#include "yaffs_trace.h"
-+#include "yportenv.h"
-+#include "yaffs_linux.h"
-+/*
-+ * Start out with the same allocator as yaffs direct.
-+ * Todo: Change to Linux slab allocator.
-+ */
-+
-+
-+
-+#define NAMELEN  20
-+struct yaffs_AllocatorStruct {
-+	char tnode_name[NAMELEN+1];
-+	char object_name[NAMELEN+1];
-+	struct kmem_cache *tnode_cache;
-+	struct kmem_cache *object_cache;
-+};
-+
-+typedef struct yaffs_AllocatorStruct yaffs_Allocator;
-+
-+int mount_id;
-+
-+void yaffs_deinit_raw_tnodes_and_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator = (yaffs_Allocator *)dev->allocator;
-+
-+	T(YAFFS_TRACE_ALLOCATE,(TSTR("Deinitialising yaffs allocator\n")));
-+
-+	if(allocator){
-+		if(allocator->tnode_cache){
-+			kmem_cache_destroy(allocator->tnode_cache);
-+			allocator->tnode_cache = NULL;
-+		} else {
-+			T(YAFFS_TRACE_ALWAYS,
-+				(TSTR("NULL tnode cache\n")));
-+			YBUG();
-+		}
-+
-+		if(allocator->object_cache){
-+			kmem_cache_destroy(allocator->object_cache);
-+			allocator->object_cache = NULL;
-+		} else {
-+			T(YAFFS_TRACE_ALWAYS,
-+				(TSTR("NULL object cache\n")));
-+			YBUG();
-+		}
-+
-+		YFREE(allocator);
-+
-+	} else {
-+		T(YAFFS_TRACE_ALWAYS,
-+			(TSTR("Deinitialising NULL allocator\n")));
-+		YBUG();
-+	}
-+	dev->allocator = NULL;
-+}
-+
-+
-+static void fake_ctor0(void *data){data = data;}
-+static void fake_ctor1(void *data){data = data;}
-+static void fake_ctor2(void *data){data = data;}
-+static void fake_ctor3(void *data){data = data;}
-+static void fake_ctor4(void *data){data = data;}
-+static void fake_ctor5(void *data){data = data;}
-+static void fake_ctor6(void *data){data = data;}
-+static void fake_ctor7(void *data){data = data;}
-+static void fake_ctor8(void *data){data = data;}
-+static void fake_ctor9(void *data){data = data;}
-+
-+static void (*fake_ctor_list[10]) (void *) = {
-+	fake_ctor0,
-+	fake_ctor1,
-+	fake_ctor2,
-+	fake_ctor3,
-+	fake_ctor4,
-+	fake_ctor5,
-+	fake_ctor6,
-+	fake_ctor7,
-+	fake_ctor8,
-+	fake_ctor9,
-+};
-+
-+void yaffs_init_raw_tnodes_and_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator;
-+	unsigned mount_id = yaffs_dev_to_lc(dev)->mount_id;
-+
-+	T(YAFFS_TRACE_ALLOCATE,(TSTR("Initialising yaffs allocator\n")));
-+
-+	if(dev->allocator)
-+		YBUG();
-+	else if(mount_id >= 10){
-+		T(YAFFS_TRACE_ALWAYS,(TSTR("Bad mount_id %u\n"),mount_id));
-+	} else {
-+		 allocator = YMALLOC(sizeof(yaffs_Allocator));
-+		 memset(allocator,0,sizeof(yaffs_Allocator));
-+		 dev->allocator = allocator;
-+
-+		if(!dev->allocator){
-+			T(YAFFS_TRACE_ALWAYS,
-+				(TSTR("yaffs allocator creation failed\n")));
-+			YBUG();
-+			return;
-+
-+		}
-+
-+		sprintf(allocator->tnode_name,"yaffs_t_%u",mount_id);
-+		sprintf(allocator->object_name,"yaffs_o_%u",mount_id);
-+
-+		allocator->tnode_cache =
-+			kmem_cache_create(allocator->tnode_name,
-+				dev->tnode_size,
-+				0, 0,
-+				fake_ctor_list[mount_id]);
-+		if(allocator->tnode_cache)
-+			T(YAFFS_TRACE_ALLOCATE,
-+				(TSTR("tnode cache \"%s\" %p\n"),
-+				allocator->tnode_name,allocator->tnode_cache));
-+		else {
-+			T(YAFFS_TRACE_ALWAYS,
-+				(TSTR("yaffs cache creation failed\n")));
-+			YBUG();
-+		}
-+
-+
-+		allocator->object_cache = 
-+			kmem_cache_create(allocator->object_name,
-+				sizeof(yaffs_obj_t),
-+				0, 0,
-+				fake_ctor_list[mount_id]);
-+
-+		if(allocator->object_cache)
-+			T(YAFFS_TRACE_ALLOCATE,
-+				(TSTR("object cache \"%s\" %p\n"),
-+				allocator->object_name,allocator->object_cache));
-+
-+		else {
-+			T(YAFFS_TRACE_ALWAYS,
-+				(TSTR("yaffs cache creation failed\n")));
-+			YBUG();
-+		}
-+	} 
-+}
-+
-+
-+yaffs_tnode_t *yaffs_alloc_raw_tnode(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+	if(!allocator || !allocator->tnode_cache){
-+		YBUG();
-+		return NULL;
-+	}
-+	return kmem_cache_alloc(allocator->tnode_cache, GFP_NOFS);
-+}
-+
-+void yaffs_free_raw_tnode(yaffs_dev_t *dev, yaffs_tnode_t *tn)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+	kmem_cache_free(allocator->tnode_cache,tn);
-+}
-+
-+yaffs_obj_t *yaffs_alloc_raw_obj(yaffs_dev_t *dev)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+	if(!allocator){
-+		YBUG();
-+		return NULL;
-+	}
-+	if(!allocator->object_cache){
-+		YBUG();
-+		return NULL;
-+	}
-+	return kmem_cache_alloc(allocator->object_cache, GFP_NOFS);
-+}
-+
-+void yaffs_free_raw_obj(yaffs_dev_t *dev, yaffs_obj_t *obj)
-+{
-+	yaffs_Allocator *allocator = dev->allocator;
-+	kmem_cache_free(allocator->object_cache,obj);
-+}
---- /dev/null
-+++ b/fs/yaffs2/yaffs_linux.h
-@@ -0,0 +1,43 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+#ifndef __YAFFS_LINUX_H__
-+#define __YAFFS_LINUX_H__
-+
-+#include "devextras.h"
-+#include "yportenv.h"
-+
-+struct yaffs_LinuxContext {
-+	struct ylist_head	contextList; /* List of these we have mounted */
-+	struct yaffs_dev_s *dev;
-+	struct super_block * superBlock;
-+	struct task_struct *bgThread; /* Background thread for this device */
-+	int bgRunning;
-+        struct semaphore grossLock;     /* Gross locking semaphore */
-+	__u8 *spareBuffer;      /* For mtdif2 use. Don't know the size of the buffer
-+				 * at compile time so we have to allocate it.
-+				 */
-+	struct ylist_head searchContexts;
-+	void (*putSuperFunc)(struct super_block *sb);
-+
-+	struct task_struct *readdirProcess;
-+	unsigned mount_id;
-+};
-+
-+#define yaffs_dev_to_lc(dev) ((struct yaffs_LinuxContext *)((dev)->os_context))
-+#define yaffs_dev_to_mtd(dev) ((struct mtd_info *)((dev)->driver_context))
-+
-+#endif
-+
---- /dev/null
-+++ b/fs/yaffs2/yaffs_list.h
-@@ -0,0 +1,127 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+/*
-+ * This file is just holds extra declarations of macros that would normally
-+ * be providesd in the Linux kernel. These macros have been written from
-+ * scratch but are functionally equivalent to the Linux ones.
-+ *
-+ */
-+
-+#ifndef __YAFFS_LIST_H__
-+#define __YAFFS_LIST_H__
-+
-+
-+#include "yportenv.h"
-+
-+/*
-+ * This is a simple doubly linked list implementation that matches the
-+ * way the Linux kernel doubly linked list implementation works.
-+ */
-+
-+struct ylist_head {
-+	struct ylist_head *next; /* next in chain */
-+	struct ylist_head *prev; /* previous in chain */
-+};
-+
-+
-+/* Initialise a static list */
-+#define YLIST_HEAD(name) \
-+struct ylist_head name = { &(name), &(name)}
-+
-+
-+
-+/* Initialise a list head to an empty list */
-+#define YINIT_LIST_HEAD(p) \
-+do { \
-+	(p)->next = (p);\
-+	(p)->prev = (p); \
-+} while (0)
-+
-+
-+/* Add an element to a list */
-+static Y_INLINE void ylist_add(struct ylist_head *newEntry,
-+				struct ylist_head *list)
-+{
-+	struct ylist_head *listNext = list->next;
-+
-+	list->next = newEntry;
-+	newEntry->prev = list;
-+	newEntry->next = listNext;
-+	listNext->prev = newEntry;
-+
-+}
-+
-+static Y_INLINE void ylist_add_tail(struct ylist_head *newEntry,
-+				 struct ylist_head *list)
-+{
-+	struct ylist_head *listPrev = list->prev;
-+
-+	list->prev = newEntry;
-+	newEntry->next = list;
-+	newEntry->prev = listPrev;
-+	listPrev->next = newEntry;
-+
-+}
-+
-+
-+/* Take an element out of its current list, with or without
-+ * reinitialising the links.of the entry*/
-+static Y_INLINE void ylist_del(struct ylist_head *entry)
-+{
-+	struct ylist_head *listNext = entry->next;
-+	struct ylist_head *listPrev = entry->prev;
-+
-+	listNext->prev = listPrev;
-+	listPrev->next = listNext;
-+
-+}
-+
-+static Y_INLINE void ylist_del_init(struct ylist_head *entry)
-+{
-+	ylist_del(entry);
-+	entry->next = entry->prev = entry;
-+}
-+
-+
-+/* Test if the list is empty */
-+static Y_INLINE int ylist_empty(struct ylist_head *entry)
-+{
-+	return (entry->next == entry);
-+}
-+
-+
-+/* ylist_entry takes a pointer to a list entry and offsets it to that
-+ * we can find a pointer to the object it is embedded in.
-+ */
-+
-+
-+#define ylist_entry(entry, type, member) \
-+	((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))
-+
-+
-+/* ylist_for_each and list_for_each_safe  iterate over lists.
-+ * ylist_for_each_safe uses temporary storage to make the list delete safe
-+ */
-+
-+#define ylist_for_each(itervar, list) \
-+	for (itervar = (list)->next; itervar != (list); itervar = itervar->next)
-+
-+#define ylist_for_each_safe(itervar, saveVar, list) \
-+	for (itervar = (list)->next, saveVar = (list)->next->next; \
-+		itervar != (list); itervar = saveVar, saveVar = saveVar->next)
-+
-+
-+#endif
---- a/fs/yaffs2/yaffs_mtdif1.c
-+++ b/fs/yaffs2/yaffs_mtdif1.c
-@@ -2,7 +2,7 @@
-  * YAFFS: Yet another FFS. A NAND-flash specific file system.
-  * yaffs_mtdif1.c  NAND mtd interface functions for small-page NAND.
-  *
-- * Copyright (C) 2002 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * This program is free software; you can redistribute it and/or modify
-@@ -18,15 +18,17 @@
-  *
-  * These functions are invoked via function pointers in yaffs_nand.c.
-  * This replaces functionality provided by functions in yaffs_mtdif.c
-- * and the yaffs_TagsCompatability functions in yaffs_tagscompat.c that are
-+ * and the yaffs_tags_tCompatability functions in yaffs_tagscompat.c that are
-  * called in yaffs_mtdif.c when the function pointers are NULL.
-- * We assume the MTD layer is performing ECC (useNANDECC is true).
-+ * We assume the MTD layer is performing ECC (use_nand_ecc is true).
-  */
- 
- #include "yportenv.h"
-+#include "yaffs_trace.h"
- #include "yaffs_guts.h"
- #include "yaffs_packedtags1.h"
--#include "yaffs_tagscompat.h"	/* for yaffs_CalcTagsECC */
-+#include "yaffs_tagscompat.h"	/* for yaffs_calc_tags_ecc */
-+#include "yaffs_linux.h"
- 
- #include "linux/kernel.h"
- #include "linux/version.h"
-@@ -36,8 +38,6 @@
- /* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
- #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 
--const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.10 2009-03-09 07:41:10 charles Exp $";
--
- #ifndef CONFIG_YAFFS_9BYTE_TAGS
- # define YTAG1_SIZE 8
- #else
-@@ -51,12 +51,12 @@ const char *yaffs_mtdif1_c_version = "$I
-  * adjust 'oobfree' to match your existing Yaffs data.
-  *
-  * This nand_ecclayout scatters/gathers to/from the old-yaffs layout with the
-- * pageStatus byte (at NAND spare offset 4) scattered/gathered from/to
-+ * page_status byte (at NAND spare offset 4) scattered/gathered from/to
-  * the 9th byte.
-  *
-  * Old-style on-NAND format: T0,T1,T2,T3,P,B,T4,T5,E0,E1,E2,T6,T7,E3,E4,E5
-- * We have/need PackedTags1 plus pageStatus: T0,T1,T2,T3,T4,T5,T6,T7,P
-- * where Tn are the tag bytes, En are MTD's ECC bytes, P is the pageStatus
-+ * We have/need PackedTags1 plus page_status: T0,T1,T2,T3,T4,T5,T6,T7,P
-+ * where Tn are the tag bytes, En are MTD's ECC bytes, P is the page_status
-  * byte and B is the small-page bad-block indicator byte.
-  */
- static struct nand_ecclayout nand_oob_16 = {
-@@ -88,42 +88,40 @@ static struct nand_ecclayout nand_oob_16
-  * Any underlying MTD error results in YAFFS_FAIL.
-  * Returns YAFFS_OK or YAFFS_FAIL.
-  */
--int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev,
--	int chunkInNAND, const __u8 *data, const yaffs_ExtendedTags *etags)
-+int nandmtd1_WriteChunkWithTagsToNAND(yaffs_dev_t *dev,
-+	int nand_chunk, const __u8 *data, const yaffs_ext_tags *etags)
- {
--	struct mtd_info *mtd = dev->genericDevice;
--	int chunkBytes = dev->nDataBytesPerChunk;
--	loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-+	int chunkBytes = dev->data_bytes_per_chunk;
-+	loff_t addr = ((loff_t)nand_chunk) * chunkBytes;
- 	struct mtd_oob_ops ops;
- 	yaffs_PackedTags1 pt1;
- 	int retval;
- 
--	/* we assume that PackedTags1 and yaffs_Tags are compatible */
-+	/* we assume that PackedTags1 and yaffs_tags_t are compatible */
- 	compile_time_assertion(sizeof(yaffs_PackedTags1) == 12);
--	compile_time_assertion(sizeof(yaffs_Tags) == 8);
--
--	dev->nPageWrites++;
-+	compile_time_assertion(sizeof(yaffs_tags_t) == 8);
- 
- 	yaffs_PackTags1(&pt1, etags);
--	yaffs_CalcTagsECC((yaffs_Tags *)&pt1);
-+	yaffs_calc_tags_ecc((yaffs_tags_t *)&pt1);
- 
- 	/* When deleting a chunk, the upper layer provides only skeletal
--	 * etags, one with chunkDeleted set.  However, we need to update the
-+	 * etags, one with is_deleted set.  However, we need to update the
- 	 * tags, not erase them completely.  So we use the NAND write property
- 	 * that only zeroed-bits stick and set tag bytes to all-ones and
- 	 * zero just the (not) deleted bit.
- 	 */
- #ifndef CONFIG_YAFFS_9BYTE_TAGS
--	if (etags->chunkDeleted) {
-+	if (etags->is_deleted) {
- 		memset(&pt1, 0xff, 8);
- 		/* clear delete status bit to indicate deleted */
- 		pt1.deleted = 0;
- 	}
- #else
- 	((__u8 *)&pt1)[8] = 0xff;
--	if (etags->chunkDeleted) {
-+	if (etags->is_deleted) {
- 		memset(&pt1, 0xff, 8);
--		/* zero pageStatus byte to indicate deleted */
-+		/* zero page_status byte to indicate deleted */
- 		((__u8 *)&pt1)[8] = 0;
- 	}
- #endif
-@@ -137,20 +135,20 @@ int nandmtd1_WriteChunkWithTagsToNAND(ya
- 
- 	retval = mtd->write_oob(mtd, addr, &ops);
- 	if (retval) {
--		yaffs_trace(YAFFS_TRACE_MTD,
--			"write_oob failed, chunk %d, mtd error %d\n",
--			chunkInNAND, retval);
-+		T(YAFFS_TRACE_MTD,
-+			(TSTR("write_oob failed, chunk %d, mtd error %d"TENDSTR),
-+			nand_chunk, retval));
- 	}
- 	return retval ? YAFFS_FAIL : YAFFS_OK;
- }
- 
--/* Return with empty ExtendedTags but add eccResult.
-+/* Return with empty ExtendedTags but add ecc_result.
-  */
--static int rettags(yaffs_ExtendedTags *etags, int eccResult, int retval)
-+static int rettags(yaffs_ext_tags *etags, int ecc_result, int retval)
- {
- 	if (etags) {
- 		memset(etags, 0, sizeof(*etags));
--		etags->eccResult = eccResult;
-+		etags->ecc_result = ecc_result;
- 	}
- 	return retval;
- }
-@@ -158,30 +156,28 @@ static int rettags(yaffs_ExtendedTags *e
- /* Read a chunk (page) from NAND.
-  *
-  * Caller expects ExtendedTags data to be usable even on error; that is,
-- * all members except eccResult and blockBad are zeroed.
-+ * all members except ecc_result and block_bad are zeroed.
-  *
-  *  - Check ECC results for data (if applicable)
-  *  - Check for blank/erased block (return empty ExtendedTags if blank)
-  *  - Check the PackedTags1 mini-ECC (correct if necessary/possible)
-  *  - Convert PackedTags1 to ExtendedTags
-- *  - Update eccResult and blockBad members to refect state.
-+ *  - Update ecc_result and block_bad members to refect state.
-  *
-  * Returns YAFFS_OK or YAFFS_FAIL.
-  */
--int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
--	int chunkInNAND, __u8 *data, yaffs_ExtendedTags *etags)
-+int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_dev_t *dev,
-+	int nand_chunk, __u8 *data, yaffs_ext_tags *etags)
- {
--	struct mtd_info *mtd = dev->genericDevice;
--	int chunkBytes = dev->nDataBytesPerChunk;
--	loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-+	int chunkBytes = dev->data_bytes_per_chunk;
-+	loff_t addr = ((loff_t)nand_chunk) * chunkBytes;
- 	int eccres = YAFFS_ECC_RESULT_NO_ERROR;
- 	struct mtd_oob_ops ops;
- 	yaffs_PackedTags1 pt1;
- 	int retval;
- 	int deleted;
- 
--	dev->nPageReads++;
--
- 	memset(&ops, 0, sizeof(ops));
- 	ops.mode = MTD_OOB_AUTO;
- 	ops.len = (data) ? chunkBytes : 0;
-@@ -200,9 +196,9 @@ int nandmtd1_ReadChunkWithTagsFromNAND(y
- 	 */
- 	retval = mtd->read_oob(mtd, addr, &ops);
- 	if (retval) {
--		yaffs_trace(YAFFS_TRACE_MTD,
--			"read_oob failed, chunk %d, mtd error %d\n",
--			chunkInNAND, retval);
-+		T(YAFFS_TRACE_MTD,
-+			(TSTR("read_oob failed, chunk %d, mtd error %d"TENDSTR),
-+			nand_chunk, retval));
- 	}
- 
- 	switch (retval) {
-@@ -213,23 +209,23 @@ int nandmtd1_ReadChunkWithTagsFromNAND(y
- 	case -EUCLEAN:
- 		/* MTD's ECC fixed the data */
- 		eccres = YAFFS_ECC_RESULT_FIXED;
--		dev->eccFixed++;
-+		dev->n_ecc_fixed++;
- 		break;
- 
- 	case -EBADMSG:
- 		/* MTD's ECC could not fix the data */
--		dev->eccUnfixed++;
-+		dev->n_ecc_unfixed++;
- 		/* fall into... */
- 	default:
- 		rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0);
--		etags->blockBad = (mtd->block_isbad)(mtd, addr);
-+		etags->block_bad = (mtd->block_isbad)(mtd, addr);
- 		return YAFFS_FAIL;
- 	}
- 
- 	/* Check for a blank/erased chunk.
- 	 */
--	if (yaffs_CheckFF((__u8 *)&pt1, 8)) {
--		/* when blank, upper layers want eccResult to be <= NO_ERROR */
-+	if (yaffs_check_ff((__u8 *)&pt1, 8)) {
-+		/* when blank, upper layers want ecc_result to be <= NO_ERROR */
- 		return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK);
- 	}
- 
-@@ -241,37 +237,37 @@ int nandmtd1_ReadChunkWithTagsFromNAND(y
- 	deleted = !pt1.deleted;
- 	pt1.deleted = 1;
- #else
--	deleted = (yaffs_CountBits(((__u8 *)&pt1)[8]) < 7);
-+	deleted = (yaffs_count_bits(((__u8 *)&pt1)[8]) < 7);
- #endif
- 
- 	/* Check the packed tags mini-ECC and correct if necessary/possible.
- 	 */
--	retval = yaffs_CheckECCOnTags((yaffs_Tags *)&pt1);
-+	retval = yaffs_check_tags_ecc((yaffs_tags_t *)&pt1);
- 	switch (retval) {
- 	case 0:
- 		/* no tags error, use MTD result */
- 		break;
- 	case 1:
- 		/* recovered tags-ECC error */
--		dev->tagsEccFixed++;
-+		dev->n_tags_ecc_fixed++;
- 		if (eccres == YAFFS_ECC_RESULT_NO_ERROR)
- 			eccres = YAFFS_ECC_RESULT_FIXED;
- 		break;
- 	default:
- 		/* unrecovered tags-ECC error */
--		dev->tagsEccUnfixed++;
-+		dev->n_tags_ecc_unfixed++;
- 		return rettags(etags, YAFFS_ECC_RESULT_UNFIXED, YAFFS_FAIL);
- 	}
- 
- 	/* Unpack the tags to extended form and set ECC result.
--	 * [set shouldBeFF just to keep yaffs_UnpackTags1 happy]
-+	 * [set shouldBeFF just to keep yaffs_unpack_tags1 happy]
- 	 */
- 	pt1.shouldBeFF = 0xFFFFFFFF;
--	yaffs_UnpackTags1(etags, &pt1);
--	etags->eccResult = eccres;
-+	yaffs_unpack_tags1(etags, &pt1);
-+	etags->ecc_result = eccres;
- 
- 	/* Set deleted state */
--	etags->chunkDeleted = deleted;
-+	etags->is_deleted = deleted;
- 	return YAFFS_OK;
- }
- 
-@@ -282,15 +278,15 @@ int nandmtd1_ReadChunkWithTagsFromNAND(y
-  *
-  * Returns YAFFS_OK or YAFFS_FAIL.
-  */
--int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
-+int nandmtd1_MarkNANDBlockBad(struct yaffs_dev_s *dev, int block_no)
- {
--	struct mtd_info *mtd = dev->genericDevice;
--	int blocksize = dev->nChunksPerBlock * dev->nDataBytesPerChunk;
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-+	int blocksize = dev->param.chunks_per_block * dev->data_bytes_per_chunk;
- 	int retval;
- 
--	yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad\n", blockNo);
-+	T(YAFFS_TRACE_BAD_BLOCKS,(TSTR("marking block %d bad"TENDSTR), block_no));
- 
--	retval = mtd->block_markbad(mtd, (loff_t)blocksize * blockNo);
-+	retval = mtd->block_markbad(mtd, (loff_t)blocksize * block_no);
- 	return (retval) ? YAFFS_FAIL : YAFFS_OK;
- }
- 
-@@ -305,9 +301,9 @@ static int nandmtd1_TestPrerequists(stru
- 	int oobavail = mtd->ecclayout->oobavail;
- 
- 	if (oobavail < YTAG1_SIZE) {
--		yaffs_trace(YAFFS_TRACE_ERROR,
--			"mtd device has only %d bytes for tags, need %d\n",
--			oobavail, YTAG1_SIZE);
-+		T(YAFFS_TRACE_ERROR,
-+			(TSTR("mtd device has only %d bytes for tags, need %d"TENDSTR),
-+			oobavail, YTAG1_SIZE));
- 		return YAFFS_FAIL;
- 	}
- 	return YAFFS_OK;
-@@ -322,13 +318,13 @@ static int nandmtd1_TestPrerequists(stru
-  *
-  * Always returns YAFFS_OK.
-  */
--int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--	yaffs_BlockState *pState, __u32 *pSequenceNumber)
-+int nandmtd1_QueryNANDBlock(struct yaffs_dev_s *dev, int block_no,
-+	yaffs_block_state_t *pState, __u32 *pSequenceNumber)
- {
--	struct mtd_info *mtd = dev->genericDevice;
--	int chunkNo = blockNo * dev->nChunksPerBlock;
--	loff_t addr = (loff_t)chunkNo * dev->nDataBytesPerChunk;
--	yaffs_ExtendedTags etags;
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
-+	int chunkNo = block_no * dev->param.chunks_per_block;
-+	loff_t addr = (loff_t)chunkNo * dev->data_bytes_per_chunk;
-+	yaffs_ext_tags etags;
- 	int state = YAFFS_BLOCK_STATE_DEAD;
- 	int seqnum = 0;
- 	int retval;
-@@ -340,17 +336,17 @@ int nandmtd1_QueryNANDBlock(struct yaffs
- 		return YAFFS_FAIL;
- 
- 	retval = nandmtd1_ReadChunkWithTagsFromNAND(dev, chunkNo, NULL, &etags);
--	etags.blockBad = (mtd->block_isbad)(mtd, addr);
--	if (etags.blockBad) {
--		yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
--			"block %d is marked bad\n", blockNo);
-+	etags.block_bad = (mtd->block_isbad)(mtd, addr);
-+	if (etags.block_bad) {
-+		T(YAFFS_TRACE_BAD_BLOCKS,
-+			(TSTR("block %d is marked bad"TENDSTR), block_no));
- 		state = YAFFS_BLOCK_STATE_DEAD;
--	} else if (etags.eccResult != YAFFS_ECC_RESULT_NO_ERROR) {
-+	} else if (etags.ecc_result != YAFFS_ECC_RESULT_NO_ERROR) {
- 		/* bad tags, need to look more closely */
- 		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
--	} else if (etags.chunkUsed) {
-+	} else if (etags.chunk_used) {
- 		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
--		seqnum = etags.sequenceNumber;
-+		seqnum = etags.seq_number;
- 	} else {
- 		state = YAFFS_BLOCK_STATE_EMPTY;
- 	}
---- a/fs/yaffs2/yaffs_mtdif1-compat.c
-+++ /dev/null
-@@ -1,434 +0,0 @@
--From ian@brightstareng.com Fri May 18 15:06:49 2007
--From ian@brightstareng.com Fri May 18 15:08:21 2007
--Received: from 206.173.66.57.ptr.us.xo.net ([206.173.66.57] helo=zebra.brightstareng.com)
--	by apollo.linkchoose.co.uk with esmtp (Exim 4.60)
--	(envelope-from <ian@brightstareng.com>)
--	id 1Hp380-00011e-T6
--	for david.goodenough@linkchoose.co.uk; Fri, 18 May 2007 15:08:21 +0100
--Received: from localhost (localhost.localdomain [127.0.0.1])
--	by zebra.brightstareng.com (Postfix) with ESMTP
--	id 4819F28C004; Fri, 18 May 2007 10:07:49 -0400 (EDT)
--Received: from zebra.brightstareng.com ([127.0.0.1])
-- by localhost (zebra [127.0.0.1]) (amavisd-new, port 10024) with ESMTP
-- id 05328-06; Fri, 18 May 2007 10:07:16 -0400 (EDT)
--Received: from pippin (unknown [192.168.1.25])
--	by zebra.brightstareng.com (Postfix) with ESMTP
--	id 8BEF528C1BC; Fri, 18 May 2007 10:06:53 -0400 (EDT)
--From: Ian McDonnell <ian@brightstareng.com>
--To: David Goodenough <david.goodenough@linkchoose.co.uk>
--Subject: Re: something tested this time -- yaffs_mtdif1-compat.c
--Date: Fri, 18 May 2007 10:06:49 -0400
--User-Agent: KMail/1.9.1
--References: <200705142207.06909.ian@brightstareng.com> <200705171131.53536.ian@brightstareng.com> <200705181334.32166.david.goodenough@linkchoose.co.uk>
--In-Reply-To: <200705181334.32166.david.goodenough@linkchoose.co.uk>
--Cc: Andrea Conti <alyf@alyf.net>,
-- Charles Manning <manningc2@actrix.gen.nz>
--MIME-Version: 1.0
--Content-Type: Multipart/Mixed;
--  boundary="Boundary-00=_5LbTGmt62YoutxM"
--Message-Id: <200705181006.49860.ian@brightstareng.com>
--X-Virus-Scanned: by amavisd-new at brightstareng.com
--Status: R
--X-Status: NT
--X-KMail-EncryptionState:
--X-KMail-SignatureState:
--X-KMail-MDN-Sent:
--
----Boundary-00=_5LbTGmt62YoutxM
--Content-Type: text/plain;
--  charset="iso-8859-15"
--Content-Transfer-Encoding: 7bit
--Content-Disposition: inline
--
--David, Andrea,
--
--On Friday 18 May 2007 08:34, you wrote:
--> Yea team.  With this fix in place (I put it in the wrong place
--> at first) I can now mount and ls the Yaffs partition without
--> an error messages!
--
--Good news!
--
--Attached is a newer yaffs_mtdif1.c with a bandaid to help the
--2.6.18 and 2.6.19 versions of MTD not trip on the oob read.
--See the LINUX_VERSION_CODE conditional in
--nandmtd1_ReadChunkWithTagsFromNAND.
--
---imcd
--
----Boundary-00=_5LbTGmt62YoutxM
--Content-Type: text/x-csrc;
--  charset="iso-8859-15";
--  name="yaffs_mtdif1.c"
--Content-Transfer-Encoding: 7bit
--Content-Disposition: attachment;
--	filename="yaffs_mtdif1.c"
--
--/*
-- * YAFFS: Yet another FFS. A NAND-flash specific file system.
-- * yaffs_mtdif1.c  NAND mtd interface functions for small-page NAND.
-- *
-- * Copyright (C) 2002 Aleph One Ltd.
-- *   for Toby Churchill Ltd and Brightstar Engineering
-- *
-- * This program is free software; you can redistribute it and/or modify
-- * it under the terms of the GNU General Public License version 2 as
-- * published by the Free Software Foundation.
-- */
--
--/*
-- * This module provides the interface between yaffs_nand.c and the
-- * MTD API.  This version is used when the MTD interface supports the
-- * 'mtd_oob_ops' style calls to read_oob and write_oob, circa 2.6.17,
-- * and we have small-page NAND device.
-- *
-- * These functions are invoked via function pointers in yaffs_nand.c.
-- * This replaces functionality provided by functions in yaffs_mtdif.c
-- * and the yaffs_TagsCompatability functions in yaffs_tagscompat.c that are
-- * called in yaffs_mtdif.c when the function pointers are NULL.
-- * We assume the MTD layer is performing ECC (useNANDECC is true).
-- */
--
--#include "yportenv.h"
--#include "yaffs_guts.h"
--#include "yaffs_packedtags1.h"
--#include "yaffs_tagscompat.h"	// for yaffs_CalcTagsECC
--
--#include "linux/kernel.h"
--#include "linux/version.h"
--#include "linux/types.h"
--#include "linux/mtd/mtd.h"
--
--/* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
--#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
--
--const char *yaffs_mtdif1_c_version = "$Id$";
--
--#ifndef CONFIG_YAFFS_9BYTE_TAGS
--# define YTAG1_SIZE 8
--#else
--# define YTAG1_SIZE 9
--#endif
--
--#if 0
--/* Use the following nand_ecclayout with MTD when using
-- * CONFIG_YAFFS_9BYTE_TAGS and the older on-NAND tags layout.
-- * If you have existing Yaffs images and the byte order differs from this,
-- * adjust 'oobfree' to match your existing Yaffs data.
-- *
-- * This nand_ecclayout scatters/gathers to/from the old-yaffs layout with the
-- * pageStatus byte (at NAND spare offset 4) scattered/gathered from/to
-- * the 9th byte.
-- *
-- * Old-style on-NAND format: T0,T1,T2,T3,P,B,T4,T5,E0,E1,E2,T6,T7,E3,E4,E5
-- * We have/need PackedTags1 plus pageStatus: T0,T1,T2,T3,T4,T5,T6,T7,P
-- * where Tn are the tag bytes, En are MTD's ECC bytes, P is the pageStatus
-- * byte and B is the small-page bad-block indicator byte.
-- */
--static struct nand_ecclayout nand_oob_16 = {
--	.eccbytes = 6,
--	.eccpos = { 8, 9, 10, 13, 14, 15 },
--	.oobavail = 9,
--	.oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } }
--};
--#endif
--
--/* Write a chunk (page) of data to NAND.
-- *
-- * Caller always provides ExtendedTags data which are converted to a more
-- * compact (packed) form for storage in NAND.  A mini-ECC runs over the
-- * contents of the tags meta-data; used to valid the tags when read.
-- *
-- *  - Pack ExtendedTags to PackedTags1 form
-- *  - Compute mini-ECC for PackedTags1
-- *  - Write data and packed tags to NAND.
-- *
-- * Note: Due to the use of the PackedTags1 meta-data which does not include
-- * a full sequence number (as found in the larger PackedTags2 form) it is
-- * necessary for Yaffs to re-write a chunk/page (just once) to mark it as
-- * discarded and dirty.  This is not ideal: newer NAND parts are supposed
-- * to be written just once.  When Yaffs performs this operation, this
-- * function is called with a NULL data pointer -- calling MTD write_oob
-- * without data is valid usage (2.6.17).
-- *
-- * Any underlying MTD error results in YAFFS_FAIL.
-- * Returns YAFFS_OK or YAFFS_FAIL.
-- */
--int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev,
--	int chunkInNAND, const __u8 * data, const yaffs_ExtendedTags * etags)
--{
--	struct mtd_info * mtd = dev->genericDevice;
--	int chunkBytes = dev->nDataBytesPerChunk;
--	loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
--	struct mtd_oob_ops ops;
--	yaffs_PackedTags1 pt1;
--	int retval;
--
--	/* we assume that PackedTags1 and yaffs_Tags are compatible */
--	compile_time_assertion(sizeof(yaffs_PackedTags1) == 12);
--	compile_time_assertion(sizeof(yaffs_Tags) == 8);
--
--	yaffs_PackTags1(&pt1, etags);
--	yaffs_CalcTagsECC((yaffs_Tags *)&pt1);
--
--	/* When deleting a chunk, the upper layer provides only skeletal
--	 * etags, one with chunkDeleted set.  However, we need to update the
--	 * tags, not erase them completely.  So we use the NAND write property
--	 * that only zeroed-bits stick and set tag bytes to all-ones and
--	 * zero just the (not) deleted bit.
--	 */
--#ifndef CONFIG_YAFFS_9BYTE_TAGS
--	if (etags->chunkDeleted) {
--		memset(&pt1, 0xff, 8);
--		/* clear delete status bit to indicate deleted */
--		pt1.deleted = 0;
--	}
--#else
--	((__u8 *)&pt1)[8] = 0xff;
--	if (etags->chunkDeleted) {
--		memset(&pt1, 0xff, 8);
--		/* zero pageStatus byte to indicate deleted */
--		((__u8 *)&pt1)[8] = 0;
--	}
--#endif
--
--	memset(&ops, 0, sizeof(ops));
--	ops.mode = MTD_OOB_AUTO;
--	ops.len = (data) ? chunkBytes : 0;
--	ops.ooblen = YTAG1_SIZE;
--	ops.datbuf = (__u8 *)data;
--	ops.oobbuf = (__u8 *)&pt1;
--
--	retval = mtd->write_oob(mtd, addr, &ops);
--	if (retval) {
--		yaffs_trace(YAFFS_TRACE_MTD,
--			"write_oob failed, chunk %d, mtd error %d\n",
--			chunkInNAND, retval);
--	}
--	return retval ? YAFFS_FAIL : YAFFS_OK;
--}
--
--/* Return with empty ExtendedTags but add eccResult.
-- */
--static int rettags(yaffs_ExtendedTags * etags, int eccResult, int retval)
--{
--	if (etags) {
--		memset(etags, 0, sizeof(*etags));
--		etags->eccResult = eccResult;
--	}
--	return retval;
--}
--
--/* Read a chunk (page) from NAND.
-- *
-- * Caller expects ExtendedTags data to be usable even on error; that is,
-- * all members except eccResult and blockBad are zeroed.
-- *
-- *  - Check ECC results for data (if applicable)
-- *  - Check for blank/erased block (return empty ExtendedTags if blank)
-- *  - Check the PackedTags1 mini-ECC (correct if necessary/possible)
-- *  - Convert PackedTags1 to ExtendedTags
-- *  - Update eccResult and blockBad members to refect state.
-- *
-- * Returns YAFFS_OK or YAFFS_FAIL.
-- */
--int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev,
--	int chunkInNAND, __u8 * data, yaffs_ExtendedTags * etags)
--{
--	struct mtd_info * mtd = dev->genericDevice;
--	int chunkBytes = dev->nDataBytesPerChunk;
--	loff_t addr = ((loff_t)chunkInNAND) * chunkBytes;
--	int eccres = YAFFS_ECC_RESULT_NO_ERROR;
--	struct mtd_oob_ops ops;
--	yaffs_PackedTags1 pt1;
--	int retval;
--	int deleted;
--
--	memset(&ops, 0, sizeof(ops));
--	ops.mode = MTD_OOB_AUTO;
--	ops.len = (data) ? chunkBytes : 0;
--	ops.ooblen = YTAG1_SIZE;
--	ops.datbuf = data;
--	ops.oobbuf = (__u8 *)&pt1;
--
--#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
--	/* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug;
--	 * help it out with ops.len = ops.ooblen when ops.datbuf == NULL.
--	 */
--	ops.len = (ops.datbuf) ? ops.len : ops.ooblen;
--#endif
--	/* Read page and oob using MTD.
--	 * Check status and determine ECC result.
--	 */
--	retval = mtd->read_oob(mtd, addr, &ops);
--	if (retval) {
--		yaffs_trace(YAFFS_TRACE_MTD,
--			"read_oob failed, chunk %d, mtd error %d\n",
--			chunkInNAND, retval);
--	}
--
--	switch (retval) {
--	case 0:
--		/* no error */
--		break;
--
--	case -EUCLEAN:
--		/* MTD's ECC fixed the data */
--		eccres = YAFFS_ECC_RESULT_FIXED;
--		dev->eccFixed++;
--		break;
--
--	case -EBADMSG:
--		/* MTD's ECC could not fix the data */
--		dev->eccUnfixed++;
--		/* fall into... */
--	default:
--		rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0);
--		etags->blockBad = (mtd->block_isbad)(mtd, addr);
--		return YAFFS_FAIL;
--	}
--
--	/* Check for a blank/erased chunk.
--	 */
--	if (yaffs_CheckFF((__u8 *)&pt1, 8)) {
--		/* when blank, upper layers want eccResult to be <= NO_ERROR */
--		return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK);
--	}
--
--#ifndef CONFIG_YAFFS_9BYTE_TAGS
--	/* Read deleted status (bit) then return it to it's non-deleted
--	 * state before performing tags mini-ECC check. pt1.deleted is
--	 * inverted.
--	 */
--	deleted = !pt1.deleted;
--	pt1.deleted = 1;
--#else
--	(void) deleted; /* not used */
--#endif
--
--	/* Check the packed tags mini-ECC and correct if necessary/possible.
--	 */
--	retval = yaffs_CheckECCOnTags((yaffs_Tags *)&pt1);
--	switch (retval) {
--	case 0:
--		/* no tags error, use MTD result */
--		break;
--	case 1:
--		/* recovered tags-ECC error */
--		dev->tagsEccFixed++;
--		eccres = YAFFS_ECC_RESULT_FIXED;
--		break;
--	default:
--		/* unrecovered tags-ECC error */
--		dev->tagsEccUnfixed++;
--		return rettags(etags, YAFFS_ECC_RESULT_UNFIXED, YAFFS_FAIL);
--	}
--
--	/* Unpack the tags to extended form and set ECC result.
--	 * [set shouldBeFF just to keep yaffs_UnpackTags1 happy]
--	 */
--	pt1.shouldBeFF = 0xFFFFFFFF;
--	yaffs_UnpackTags1(etags, &pt1);
--	etags->eccResult = eccres;
--
--	/* Set deleted state.
--	 */
--#ifndef CONFIG_YAFFS_9BYTE_TAGS
--	etags->chunkDeleted = deleted;
--#else
--	etags->chunkDeleted = (yaffs_CountBits(((__u8 *)&pt1)[8]) < 7);
--#endif
--	return YAFFS_OK;
--}
--
--/* Mark a block bad.
-- *
-- * This is a persistant state.
-- * Use of this function should be rare.
-- *
-- * Returns YAFFS_OK or YAFFS_FAIL.
-- */
--int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
--{
--	struct mtd_info * mtd = dev->genericDevice;
--	int blocksize = dev->nChunksPerBlock * dev->nDataBytesPerChunk;
--	int retval;
--
--	yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad", blockNo);
--
--	retval = mtd->block_markbad(mtd, (loff_t)blocksize * blockNo);
--	return (retval) ? YAFFS_FAIL : YAFFS_OK;
--}
--
--/* Check any MTD prerequists.
-- *
-- * Returns YAFFS_OK or YAFFS_FAIL.
-- */
--static int nandmtd1_TestPrerequists(struct mtd_info * mtd)
--{
--	/* 2.6.18 has mtd->ecclayout->oobavail */
--	/* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
--	int oobavail = mtd->ecclayout->oobavail;
--
--	if (oobavail < YTAG1_SIZE) {
--		yaffs_trace(YAFFS_TRACE_ERROR,
--			"mtd device has only %d bytes for tags, need %d",
--			oobavail, YTAG1_SIZE);
--		return YAFFS_FAIL;
--	}
--	return YAFFS_OK;
--}
--
--/* Query for the current state of a specific block.
-- *
-- * Examine the tags of the first chunk of the block and return the state:
-- *  - YAFFS_BLOCK_STATE_DEAD, the block is marked bad
-- *  - YAFFS_BLOCK_STATE_NEEDS_SCANNING, the block is in use
-- *  - YAFFS_BLOCK_STATE_EMPTY, the block is clean
-- *
-- * Always returns YAFFS_OK.
-- */
--int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--	yaffs_BlockState * pState, int *pSequenceNumber)
--{
--	struct mtd_info * mtd = dev->genericDevice;
--	int chunkNo = blockNo * dev->nChunksPerBlock;
--	yaffs_ExtendedTags etags;
--	int state = YAFFS_BLOCK_STATE_DEAD;
--	int seqnum = 0;
--	int retval;
--
--	/* We don't yet have a good place to test for MTD config prerequists.
--	 * Do it here as we are called during the initial scan.
--	 */
--	if (nandmtd1_TestPrerequists(mtd) != YAFFS_OK) {
--		return YAFFS_FAIL;
--	}
--
--	retval = nandmtd1_ReadChunkWithTagsFromNAND(dev, chunkNo, NULL, &etags);
--	if (etags.blockBad) {
--		yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
--			"block %d is marked bad", blockNo);
--		state = YAFFS_BLOCK_STATE_DEAD;
--	}
--	else if (etags.chunkUsed) {
--		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
--		seqnum = etags.sequenceNumber;
--	}
--	else {
--		state = YAFFS_BLOCK_STATE_EMPTY;
--	}
--
--	*pState = state;
--	*pSequenceNumber = seqnum;
--
--	/* query always succeeds */
--	return YAFFS_OK;
--}
--
--#endif /*KERNEL_VERSION*/
--
----Boundary-00=_5LbTGmt62YoutxM--
--
--
--
---- a/fs/yaffs2/yaffs_mtdif1.h
-+++ b/fs/yaffs2/yaffs_mtdif1.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * This program is free software; you can redistribute it and/or modify
-@@ -14,15 +14,15 @@
- #ifndef __YAFFS_MTDIF1_H__
- #define __YAFFS_MTDIF1_H__
- 
--int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
--	const __u8 *data, const yaffs_ExtendedTags *tags);
-+int nandmtd1_WriteChunkWithTagsToNAND(yaffs_dev_t *dev, int nand_chunk,
-+	const __u8 *data, const yaffs_ext_tags *tags);
- 
--int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
--	__u8 *data, yaffs_ExtendedTags *tags);
-+int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_dev_t *dev, int nand_chunk,
-+	__u8 *data, yaffs_ext_tags *tags);
- 
--int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
-+int nandmtd1_MarkNANDBlockBad(struct yaffs_dev_s *dev, int block_no);
- 
--int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--	yaffs_BlockState *state, __u32 *sequenceNumber);
-+int nandmtd1_QueryNANDBlock(struct yaffs_dev_s *dev, int block_no,
-+	yaffs_block_state_t *state, __u32 *seq_number);
- 
- #endif
---- a/fs/yaffs2/yaffs_mtdif2.c
-+++ b/fs/yaffs2/yaffs_mtdif2.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -13,11 +13,8 @@
- 
- /* mtd interface for YAFFS2 */
- 
--const char *yaffs_mtdif2_c_version =
--	"$Id: yaffs_mtdif2.c,v 1.23 2009-03-06 17:20:53 wookey Exp $";
--
- #include "yportenv.h"
--
-+#include "yaffs_trace.h"
- 
- #include "yaffs_mtdif2.h"
- 
-@@ -27,15 +24,17 @@ const char *yaffs_mtdif2_c_version =
- 
- #include "yaffs_packedtags2.h"
- 
-+#include "yaffs_linux.h"
-+
- /* NB For use with inband tags....
-  * We assume that the data buffer is of size totalBytersPerChunk so that we can also
-  * use it to load the tags.
-  */
--int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
-+int nandmtd2_WriteChunkWithTagsToNAND(yaffs_dev_t *dev, int nand_chunk,
- 				      const __u8 *data,
--				      const yaffs_ExtendedTags *tags)
-+				      const yaffs_ext_tags *tags)
- {
--	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 	struct mtd_oob_ops ops;
- #else
-@@ -47,13 +46,16 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
- 
- 	yaffs_PackedTags2 pt;
- 
-+	int packed_tags_size = dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
-+	void * packed_tags_ptr = dev->param.no_tags_ecc ? (void *) &pt.t : (void *)&pt;
-+
- 	T(YAFFS_TRACE_MTD,
- 	  (TSTR
- 	   ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p"
--	    TENDSTR), chunkInNAND, data, tags));
-+	    TENDSTR), nand_chunk, data, tags));
- 
- 
--	addr  = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
-+	addr  = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
- 
- 	/* For yaffs2 writing there must be both data and tags.
- 	 * If we're using inband tags, then the tags are stuffed into
-@@ -61,30 +63,30 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
- 	 */
- 	if (!data || !tags)
- 		BUG();
--	else if (dev->inbandTags) {
-+	else if (dev->param.inband_tags) {
- 		yaffs_PackedTags2TagsPart *pt2tp;
--		pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->nDataBytesPerChunk);
-+		pt2tp = (yaffs_PackedTags2TagsPart *)(data + dev->data_bytes_per_chunk);
- 		yaffs_PackTags2TagsPart(pt2tp, tags);
- 	} else
--		yaffs_PackTags2(&pt, tags);
-+		yaffs_PackTags2(&pt, tags, !dev->param.no_tags_ecc);
- 
- #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- 	ops.mode = MTD_OOB_AUTO;
--	ops.ooblen = (dev->inbandTags) ? 0 : sizeof(pt);
--	ops.len = dev->totalBytesPerChunk;
-+	ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
-+	ops.len = dev->param.total_bytes_per_chunk;
- 	ops.ooboffs = 0;
- 	ops.datbuf = (__u8 *)data;
--	ops.oobbuf = (dev->inbandTags) ? NULL : (void *)&pt;
-+	ops.oobbuf = (dev->param.inband_tags) ? NULL : packed_tags_ptr;
- 	retval = mtd->write_oob(mtd, addr, &ops);
- 
- #else
--	if (!dev->inbandTags) {
-+	if (!dev->param.inband_tags) {
- 		retval =
--		    mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
--				   &dummy, data, (__u8 *) &pt, NULL);
-+		    mtd->write_ecc(mtd, addr, dev->data_bytes_per_chunk,
-+				   &dummy, data, (__u8 *) packed_tags_ptr, NULL);
- 	} else {
- 		retval =
--		    mtd->write(mtd, addr, dev->totalBytesPerChunk, &dummy,
-+		    mtd->write(mtd, addr, dev->param.total_bytes_per_chunk, &dummy,
- 			       data);
- 	}
- #endif
-@@ -95,10 +97,10 @@ int nandmtd2_WriteChunkWithTagsToNAND(ya
- 		return YAFFS_FAIL;
- }
- 
--int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
--				       __u8 *data, yaffs_ExtendedTags *tags)
-+int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_dev_t *dev, int nand_chunk,
-+				       __u8 *data, yaffs_ext_tags *tags)
- {
--	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- #if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
- 	struct mtd_oob_ops ops;
- #endif
-@@ -106,20 +108,23 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
- 	int retval = 0;
- 	int localData = 0;
- 
--	loff_t addr = ((loff_t) chunkInNAND) * dev->totalBytesPerChunk;
-+	loff_t addr = ((loff_t) nand_chunk) * dev->param.total_bytes_per_chunk;
- 
- 	yaffs_PackedTags2 pt;
- 
-+	int packed_tags_size = dev->param.no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
-+	void * packed_tags_ptr = dev->param.no_tags_ecc ? (void *) &pt.t: (void *)&pt;
-+
- 	T(YAFFS_TRACE_MTD,
- 	  (TSTR
- 	   ("nandmtd2_ReadChunkWithTagsFromNAND chunk %d data %p tags %p"
--	    TENDSTR), chunkInNAND, data, tags));
-+	    TENDSTR), nand_chunk, data, tags));
- 
--	if (dev->inbandTags) {
-+	if (dev->param.inband_tags) {
- 
- 		if (!data) {
- 			localData = 1;
--			data = yaffs_GetTempBuffer(dev, __LINE__);
-+			data = yaffs_get_temp_buffer(dev, __LINE__);
- 		}
- 
- 
-@@ -127,30 +132,30 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
- 
- 
- #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
--	if (dev->inbandTags || (data && !tags))
--		retval = mtd->read(mtd, addr, dev->totalBytesPerChunk,
-+	if (dev->param.inband_tags || (data && !tags))
-+		retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
- 				&dummy, data);
- 	else if (tags) {
- 		ops.mode = MTD_OOB_AUTO;
--		ops.ooblen = sizeof(pt);
--		ops.len = data ? dev->nDataBytesPerChunk : sizeof(pt);
-+		ops.ooblen = packed_tags_size;
-+		ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
- 		ops.ooboffs = 0;
- 		ops.datbuf = data;
--		ops.oobbuf = dev->spareBuffer;
-+		ops.oobbuf = yaffs_dev_to_lc(dev)->spareBuffer;
- 		retval = mtd->read_oob(mtd, addr, &ops);
- 	}
- #else
--	if (!dev->inbandTags && data && tags) {
-+	if (!dev->param.inband_tags && data && tags) {
- 
--		retval = mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
-+		retval = mtd->read_ecc(mtd, addr, dev->data_bytes_per_chunk,
- 					  &dummy, data, dev->spareBuffer,
- 					  NULL);
- 	} else {
- 		if (data)
- 			retval =
--			    mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
-+			    mtd->read(mtd, addr, dev->data_bytes_per_chunk, &dummy,
- 				      data);
--		if (!dev->inbandTags && tags)
-+		if (!dev->param.inband_tags && tags)
- 			retval =
- 			    mtd->read_oob(mtd, addr, mtd->oobsize, &dummy,
- 					  dev->spareBuffer);
-@@ -158,41 +163,47 @@ int nandmtd2_ReadChunkWithTagsFromNAND(y
- #endif
- 
- 
--	if (dev->inbandTags) {
-+	if (dev->param.inband_tags) {
- 		if (tags) {
- 			yaffs_PackedTags2TagsPart *pt2tp;
--			pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->nDataBytesPerChunk];
--			yaffs_UnpackTags2TagsPart(tags, pt2tp);
-+			pt2tp = (yaffs_PackedTags2TagsPart *)&data[dev->data_bytes_per_chunk];
-+			yaffs_unpack_tags2tags_part(tags, pt2tp);
- 		}
- 	} else {
- 		if (tags) {
--			memcpy(&pt, dev->spareBuffer, sizeof(pt));
--			yaffs_UnpackTags2(tags, &pt);
-+			memcpy(packed_tags_ptr, yaffs_dev_to_lc(dev)->spareBuffer, packed_tags_size);
-+			yaffs_unpack_tags2(tags, &pt, !dev->param.no_tags_ecc);
- 		}
- 	}
- 
- 	if (localData)
--		yaffs_ReleaseTempBuffer(dev, data, __LINE__);
-+		yaffs_release_temp_buffer(dev, data, __LINE__);
- 
--	if (tags && retval == -EBADMSG && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR)
--		tags->eccResult = YAFFS_ECC_RESULT_UNFIXED;
-+	if (tags && retval == -EBADMSG && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
-+		tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;
-+		dev->n_ecc_unfixed++;
-+	}
-+	if(tags && retval == -EUCLEAN && tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
-+		tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
-+		dev->n_ecc_fixed++;
-+	}
- 	if (retval == 0)
- 		return YAFFS_OK;
- 	else
- 		return YAFFS_FAIL;
- }
- 
--int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo)
-+int nandmtd2_MarkNANDBlockBad(struct yaffs_dev_s *dev, int block_no)
- {
--	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- 	int retval;
- 	T(YAFFS_TRACE_MTD,
--	  (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), blockNo));
-+	  (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), block_no));
- 
- 	retval =
- 	    mtd->block_markbad(mtd,
--			       blockNo * dev->nChunksPerBlock *
--			       dev->totalBytesPerChunk);
-+			       block_no * dev->param.chunks_per_block *
-+			       dev->param.total_bytes_per_chunk);
- 
- 	if (retval == 0)
- 		return YAFFS_OK;
-@@ -201,41 +212,41 @@ int nandmtd2_MarkNANDBlockBad(struct yaf
- 
- }
- 
--int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--			    yaffs_BlockState *state, __u32 *sequenceNumber)
-+int nandmtd2_QueryNANDBlock(struct yaffs_dev_s *dev, int block_no,
-+			    yaffs_block_state_t *state, __u32 *seq_number)
- {
--	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- 	int retval;
- 
- 	T(YAFFS_TRACE_MTD,
--	  (TSTR("nandmtd2_QueryNANDBlock %d" TENDSTR), blockNo));
-+	  (TSTR("nandmtd2_QueryNANDBlock %d" TENDSTR), block_no));
- 	retval =
- 	    mtd->block_isbad(mtd,
--			     blockNo * dev->nChunksPerBlock *
--			     dev->totalBytesPerChunk);
-+			     block_no * dev->param.chunks_per_block *
-+			     dev->param.total_bytes_per_chunk);
- 
- 	if (retval) {
- 		T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR)));
- 
- 		*state = YAFFS_BLOCK_STATE_DEAD;
--		*sequenceNumber = 0;
-+		*seq_number = 0;
- 	} else {
--		yaffs_ExtendedTags t;
-+		yaffs_ext_tags t;
- 		nandmtd2_ReadChunkWithTagsFromNAND(dev,
--						   blockNo *
--						   dev->nChunksPerBlock, NULL,
-+						   block_no *
-+						   dev->param.chunks_per_block, NULL,
- 						   &t);
- 
--		if (t.chunkUsed) {
--			*sequenceNumber = t.sequenceNumber;
-+		if (t.chunk_used) {
-+			*seq_number = t.seq_number;
- 			*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING;
- 		} else {
--			*sequenceNumber = 0;
-+			*seq_number = 0;
- 			*state = YAFFS_BLOCK_STATE_EMPTY;
- 		}
- 	}
- 	T(YAFFS_TRACE_MTD,
--	  (TSTR("block is bad seq %d state %d" TENDSTR), *sequenceNumber,
-+	  (TSTR("block is bad seq %d state %d" TENDSTR), *seq_number,
- 	   *state));
- 
- 	if (retval == 0)
---- a/fs/yaffs2/yaffs_mtdif2.h
-+++ b/fs/yaffs2/yaffs_mtdif2.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -17,13 +17,13 @@
- #define __YAFFS_MTDIF2_H__
- 
- #include "yaffs_guts.h"
--int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device *dev, int chunkInNAND,
-+int nandmtd2_WriteChunkWithTagsToNAND(yaffs_dev_t *dev, int nand_chunk,
- 				const __u8 *data,
--				const yaffs_ExtendedTags *tags);
--int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
--				__u8 *data, yaffs_ExtendedTags *tags);
--int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
--int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--			yaffs_BlockState *state, __u32 *sequenceNumber);
-+				const yaffs_ext_tags *tags);
-+int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_dev_t *dev, int nand_chunk,
-+				__u8 *data, yaffs_ext_tags *tags);
-+int nandmtd2_MarkNANDBlockBad(struct yaffs_dev_s *dev, int block_no);
-+int nandmtd2_QueryNANDBlock(struct yaffs_dev_s *dev, int block_no,
-+			yaffs_block_state_t *state, __u32 *seq_number);
- 
- #endif
---- a/fs/yaffs2/yaffs_mtdif.c
-+++ b/fs/yaffs2/yaffs_mtdif.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -11,9 +11,6 @@
-  * published by the Free Software Foundation.
-  */
- 
--const char *yaffs_mtdif_c_version =
--	"$Id: yaffs_mtdif.c,v 1.22 2009-03-06 17:20:51 wookey Exp $";
--
- #include "yportenv.h"
- 
- 
-@@ -24,208 +21,26 @@ const char *yaffs_mtdif_c_version =
- #include "linux/time.h"
- #include "linux/mtd/nand.h"
- 
--#if (MTD_VERSION_CODE < MTD_VERSION(2, 6, 18))
--static struct nand_oobinfo yaffs_oobinfo = {
--	.useecc = 1,
--	.eccbytes = 6,
--	.eccpos = {8, 9, 10, 13, 14, 15}
--};
--
--static struct nand_oobinfo yaffs_noeccinfo = {
--	.useecc = 0,
--};
--#endif
--
--#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
--static inline void translate_spare2oob(const yaffs_Spare *spare, __u8 *oob)
--{
--	oob[0] = spare->tagByte0;
--	oob[1] = spare->tagByte1;
--	oob[2] = spare->tagByte2;
--	oob[3] = spare->tagByte3;
--	oob[4] = spare->tagByte4;
--	oob[5] = spare->tagByte5 & 0x3f;
--	oob[5] |= spare->blockStatus == 'Y' ? 0 : 0x80;
--	oob[5] |= spare->pageStatus == 0 ? 0 : 0x40;
--	oob[6] = spare->tagByte6;
--	oob[7] = spare->tagByte7;
--}
--
--static inline void translate_oob2spare(yaffs_Spare *spare, __u8 *oob)
--{
--	struct yaffs_NANDSpare *nspare = (struct yaffs_NANDSpare *)spare;
--	spare->tagByte0 = oob[0];
--	spare->tagByte1 = oob[1];
--	spare->tagByte2 = oob[2];
--	spare->tagByte3 = oob[3];
--	spare->tagByte4 = oob[4];
--	spare->tagByte5 = oob[5] == 0xff ? 0xff : oob[5] & 0x3f;
--	spare->blockStatus = oob[5] & 0x80 ? 0xff : 'Y';
--	spare->pageStatus = oob[5] & 0x40 ? 0xff : 0;
--	spare->ecc1[0] = spare->ecc1[1] = spare->ecc1[2] = 0xff;
--	spare->tagByte6 = oob[6];
--	spare->tagByte7 = oob[7];
--	spare->ecc2[0] = spare->ecc2[1] = spare->ecc2[2] = 0xff;
--
--	nspare->eccres1 = nspare->eccres2 = 0; /* FIXME */
--}
--#endif
--
--int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
--			     const __u8 *data, const yaffs_Spare *spare)
--{
--	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
--#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
--	struct mtd_oob_ops ops;
--#endif
--	size_t dummy;
--	int retval = 0;
--
--	loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
--#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
--	__u8 spareAsBytes[8]; /* OOB */
--
--	if (data && !spare)
--		retval = mtd->write(mtd, addr, dev->nDataBytesPerChunk,
--				&dummy, data);
--	else if (spare) {
--		if (dev->useNANDECC) {
--			translate_spare2oob(spare, spareAsBytes);
--			ops.mode = MTD_OOB_AUTO;
--			ops.ooblen = 8; /* temp hack */
--		} else {
--			ops.mode = MTD_OOB_RAW;
--			ops.ooblen = YAFFS_BYTES_PER_SPARE;
--		}
--		ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
--		ops.datbuf = (u8 *)data;
--		ops.ooboffs = 0;
--		ops.oobbuf = spareAsBytes;
--		retval = mtd->write_oob(mtd, addr, &ops);
--	}
--#else
--	__u8 *spareAsBytes = (__u8 *) spare;
--
--	if (data && spare) {
--		if (dev->useNANDECC)
--			retval =
--			    mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
--					   &dummy, data, spareAsBytes,
--					   &yaffs_oobinfo);
--		else
--			retval =
--			    mtd->write_ecc(mtd, addr, dev->nDataBytesPerChunk,
--					   &dummy, data, spareAsBytes,
--					   &yaffs_noeccinfo);
--	} else {
--		if (data)
--			retval =
--			    mtd->write(mtd, addr, dev->nDataBytesPerChunk, &dummy,
--				       data);
--		if (spare)
--			retval =
--			    mtd->write_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
--					   &dummy, spareAsBytes);
--	}
--#endif
--
--	if (retval == 0)
--		return YAFFS_OK;
--	else
--		return YAFFS_FAIL;
--}
--
--int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
--			      yaffs_Spare *spare)
--{
--	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
--#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
--	struct mtd_oob_ops ops;
--#endif
--	size_t dummy;
--	int retval = 0;
-+#include "yaffs_linux.h"
- 
--	loff_t addr = ((loff_t) chunkInNAND) * dev->nDataBytesPerChunk;
--#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
--	__u8 spareAsBytes[8]; /* OOB */
--
--	if (data && !spare)
--		retval = mtd->read(mtd, addr, dev->nDataBytesPerChunk,
--				&dummy, data);
--	else if (spare) {
--		if (dev->useNANDECC) {
--			ops.mode = MTD_OOB_AUTO;
--			ops.ooblen = 8; /* temp hack */
--		} else {
--			ops.mode = MTD_OOB_RAW;
--			ops.ooblen = YAFFS_BYTES_PER_SPARE;
--		}
--		ops.len = data ? dev->nDataBytesPerChunk : ops.ooblen;
--		ops.datbuf = data;
--		ops.ooboffs = 0;
--		ops.oobbuf = spareAsBytes;
--		retval = mtd->read_oob(mtd, addr, &ops);
--		if (dev->useNANDECC)
--			translate_oob2spare(spare, spareAsBytes);
--	}
--#else
--	__u8 *spareAsBytes = (__u8 *) spare;
--
--	if (data && spare) {
--		if (dev->useNANDECC) {
--			/* Careful, this call adds 2 ints */
--			/* to the end of the spare data.  Calling function */
--			/* should allocate enough memory for spare, */
--			/* i.e. [YAFFS_BYTES_PER_SPARE+2*sizeof(int)]. */
--			retval =
--			    mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
--					  &dummy, data, spareAsBytes,
--					  &yaffs_oobinfo);
--		} else {
--			retval =
--			    mtd->read_ecc(mtd, addr, dev->nDataBytesPerChunk,
--					  &dummy, data, spareAsBytes,
--					  &yaffs_noeccinfo);
--		}
--	} else {
--		if (data)
--			retval =
--			    mtd->read(mtd, addr, dev->nDataBytesPerChunk, &dummy,
--				      data);
--		if (spare)
--			retval =
--			    mtd->read_oob(mtd, addr, YAFFS_BYTES_PER_SPARE,
--					  &dummy, spareAsBytes);
--	}
--#endif
--
--	if (retval == 0)
--		return YAFFS_OK;
--	else
--		return YAFFS_FAIL;
--}
--
--int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber)
-+int nandmtd_EraseBlockInNAND(yaffs_dev_t *dev, int blockNumber)
- {
--	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice);
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(dev);
- 	__u32 addr =
--	    ((loff_t) blockNumber) * dev->nDataBytesPerChunk
--		* dev->nChunksPerBlock;
-+	    ((loff_t) blockNumber) * dev->param.total_bytes_per_chunk
-+		* dev->param.chunks_per_block;
- 	struct erase_info ei;
-+	
- 	int retval = 0;
- 
- 	ei.mtd = mtd;
- 	ei.addr = addr;
--	ei.len = dev->nDataBytesPerChunk * dev->nChunksPerBlock;
-+	ei.len = dev->param.total_bytes_per_chunk * dev->param.chunks_per_block;
- 	ei.time = 1000;
- 	ei.retries = 2;
- 	ei.callback = NULL;
- 	ei.priv = (u_long) dev;
- 
--	/* Todo finish off the ei if required */
--
--	sema_init(&dev->sem, 0);
--
- 	retval = mtd->erase(mtd, &ei);
- 
- 	if (retval == 0)
-@@ -234,7 +49,7 @@ int nandmtd_EraseBlockInNAND(yaffs_Devic
- 		return YAFFS_FAIL;
- }
- 
--int nandmtd_InitialiseNAND(yaffs_Device *dev)
-+int nandmtd_InitialiseNAND(yaffs_dev_t *dev)
- {
- 	return YAFFS_OK;
- }
---- a/fs/yaffs2/yaffs_mtdif.h
-+++ b/fs/yaffs2/yaffs_mtdif.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -22,11 +22,6 @@
- extern struct nand_oobinfo yaffs_oobinfo;
- extern struct nand_oobinfo yaffs_noeccinfo;
- #endif
--
--int nandmtd_WriteChunkToNAND(yaffs_Device *dev, int chunkInNAND,
--			const __u8 *data, const yaffs_Spare *spare);
--int nandmtd_ReadChunkFromNAND(yaffs_Device *dev, int chunkInNAND, __u8 *data,
--			yaffs_Spare *spare);
--int nandmtd_EraseBlockInNAND(yaffs_Device *dev, int blockNumber);
--int nandmtd_InitialiseNAND(yaffs_Device *dev);
-+int nandmtd_EraseBlockInNAND(yaffs_dev_t *dev, int blockNumber);
-+int nandmtd_InitialiseNAND(yaffs_dev_t *dev);
- #endif
---- /dev/null
-+++ b/fs/yaffs2/yaffs_nameval.c
-@@ -0,0 +1,197 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+/*
-+ * This simple implementation of a name-value store assumes a small number of values and fits
-+ * into a small finite buffer.
-+ *
-+ * Each attribute is stored as a record:
-+ *  sizeof(int) bytes   record size.
-+ *  strnlen+1 bytes name null terminated.
-+ *  nbytes    value.
-+ *  ----------
-+ *  total size  stored in record size 
-+ *
-+ * This code has not been tested with unicode yet.
-+ */
-+
-+
-+#include "yaffs_nameval.h"
-+
-+#include "yportenv.h"
-+ 
-+static int nval_find(const char *xb, int xb_size, const YCHAR *name,
-+		int *exist_size)
-+{
-+	int pos=0;
-+	int size;
-+
-+	memcpy(&size,xb,sizeof(int));
-+	while(size > 0 && (size < xb_size) && (pos + size < xb_size)){
-+		if(yaffs_strncmp((YCHAR *)(xb+pos+sizeof(int)),name,size) == 0){
-+			if(exist_size)
-+				*exist_size = size;
-+			return pos;
-+		}
-+		pos += size;
-+		if(pos < xb_size -sizeof(int))
-+			memcpy(&size,xb + pos,sizeof(int));
-+		else
-+			size = 0;
-+	}
-+	if(exist_size)
-+		*exist_size = 0;
-+	return -1;
-+}
-+
-+static int nval_used(const char *xb, int xb_size)
-+{
-+	int pos=0;
-+	int size;
-+
-+	memcpy(&size,xb + pos,sizeof(int));
-+	while(size > 0 && (size < xb_size) && (pos + size < xb_size)){
-+		pos += size;
-+		if(pos < xb_size -sizeof(int))
-+			memcpy(&size,xb + pos,sizeof(int));
-+		else
-+			size = 0;
-+	}
-+	return pos;
-+}
-+
-+int nval_del(char *xb, int xb_size, const YCHAR *name)
-+{
-+	int pos  = nval_find(xb, xb_size, name, NULL);
-+	int size;
-+	
-+	if(pos >= 0 && pos < xb_size){
-+		/* Find size, shift rest over this record, then zero out the rest of buffer */
-+		memcpy(&size,xb+pos,sizeof(int));
-+		memcpy(xb + pos, xb + pos + size, xb_size - (pos + size));
-+		memset(xb + (xb_size - size),0,size);
-+		return 0;
-+	} else
-+		return -ENODATA;
-+}
-+
-+int nval_set(char *xb, int xb_size, const YCHAR *name, const char *buf, int bsize, int flags)
-+{
-+	int pos;
-+	int namelen = yaffs_strnlen(name,xb_size);
-+	int reclen;
-+	int size_exist = 0;
-+	int space;
-+	int start;
-+
-+	pos = nval_find(xb,xb_size,name, &size_exist);
-+
-+	if(flags & XATTR_CREATE && pos >= 0)
-+		return -EEXIST;
-+	if(flags & XATTR_REPLACE && pos < 0)
-+		return -ENODATA;
-+
-+	start = nval_used(xb,xb_size);
-+	space = xb_size - start + size_exist;
-+
-+	reclen = (sizeof(int) + namelen + 1 + bsize);
-+
-+	if(reclen > space)
-+		return -ENOSPC;
-+
-+	if(pos >= 0){
-+		nval_del(xb,xb_size,name);
-+		start = nval_used(xb, xb_size);
-+	}
-+
-+	pos = start;
-+
-+	memcpy(xb + pos,&reclen,sizeof(int));
-+	pos +=sizeof(int);
-+	yaffs_strncpy((YCHAR *)(xb + pos), name, reclen);
-+	pos+= (namelen+1);
-+	memcpy(xb + pos,buf,bsize);
-+	return 0;
-+}
-+
-+int nval_get(const char *xb, int xb_size, const YCHAR *name, char *buf, int bsize)
-+{
-+	int pos = nval_find(xb,xb_size,name,NULL);
-+	int size;
-+	
-+	if(pos >= 0 && pos< xb_size){
-+		
-+		memcpy(&size,xb +pos,sizeof(int));
-+		pos+=sizeof(int); /* advance past record length */
-+		size -= sizeof(int);
-+
-+		/* Advance over name string */
-+		while(xb[pos] && size > 0 && pos < xb_size){
-+			pos++;
-+			size--;
-+		}
-+		/*Advance over NUL */
-+		pos++;
-+		size--;
-+
-+		if(size <= bsize){
-+			memcpy(buf,xb + pos,size);
-+			return size;
-+		}
-+		
-+	}
-+	if(pos >= 0)
-+		return -ERANGE;
-+	else
-+		return -ENODATA;
-+}
-+
-+int nval_list(const char *xb, int xb_size, char *buf, int bsize)
-+{
-+	int pos = 0;
-+	int size;
-+	int name_len;
-+	int ncopied = 0;
-+	int filled = 0;
-+
-+	memcpy(&size,xb + pos,sizeof(int));
-+	while(size > sizeof(int) && size <= xb_size && (pos + size) < xb_size && !filled){
-+		pos+= sizeof(int);
-+		size-=sizeof(int);
-+		name_len = yaffs_strnlen((YCHAR *)(xb + pos), size);
-+		if(ncopied + name_len + 1 < bsize){
-+			memcpy(buf,xb+pos,name_len * sizeof(YCHAR));
-+			buf+= name_len;
-+			*buf = '\0';
-+			buf++;
-+			if(sizeof(YCHAR) > 1){
-+				*buf = '\0';
-+				buf++;
-+			}
-+			ncopied += (name_len+1);
-+		} else
-+			filled = 1;
-+		pos+=size;
-+		if(pos < xb_size -sizeof(int))
-+			memcpy(&size,xb + pos,sizeof(int));
-+		else
-+			size = 0;
-+	}
-+	return ncopied;
-+}
-+
-+
-+int nval_hasvalues(const char *xb, int xb_size)
-+{
-+	return nval_used(xb, xb_size) > 0;
-+}
---- /dev/null
-+++ b/fs/yaffs2/yaffs_nameval.h
-@@ -0,0 +1,25 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+#ifndef __NAMEVAL_H__
-+#define __NAMEVAL_H__
-+
-+#include "yportenv.h"
-+
-+int nval_del(char *xb, int xb_size, const YCHAR *name);
-+int nval_set(char *xb, int xb_size, const YCHAR *name, const char *buf, int bsize, int flags);
-+int nval_get(const char *xb, int xb_size, const YCHAR *name, char *buf, int bsize);
-+int nval_list(const char *xb, int xb_size, char *buf, int bsize);
-+int nval_hasvalues(const char *xb, int xb_size);
-+#endif
---- a/fs/yaffs2/yaffs_nand.c
-+++ b/fs/yaffs2/yaffs_nand.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -11,124 +11,129 @@
-  * published by the Free Software Foundation.
-  */
- 
--const char *yaffs_nand_c_version =
--	"$Id: yaffs_nand.c,v 1.10 2009-03-06 17:20:54 wookey Exp $";
--
- #include "yaffs_nand.h"
- #include "yaffs_tagscompat.h"
- #include "yaffs_tagsvalidity.h"
- 
- #include "yaffs_getblockinfo.h"
- 
--int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
-+int yaffs_rd_chunk_tags_nand(yaffs_dev_t *dev, int nand_chunk,
- 					   __u8 *buffer,
--					   yaffs_ExtendedTags *tags)
-+					   yaffs_ext_tags *tags)
- {
- 	int result;
--	yaffs_ExtendedTags localTags;
-+	yaffs_ext_tags localTags;
-+
-+	int realignedChunkInNAND = nand_chunk - dev->chunk_offset;
- 
--	int realignedChunkInNAND = chunkInNAND - dev->chunkOffset;
-+	dev->n_page_reads++;
- 
- 	/* If there are no tags provided, use local tags to get prioritised gc working */
- 	if (!tags)
- 		tags = &localTags;
- 
--	if (dev->readChunkWithTagsFromNAND)
--		result = dev->readChunkWithTagsFromNAND(dev, realignedChunkInNAND, buffer,
-+	if (dev->param.read_chunk_tags_fn)
-+		result = dev->param.read_chunk_tags_fn(dev, realignedChunkInNAND, buffer,
- 						      tags);
- 	else
--		result = yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(dev,
-+		result = yaffs_tags_compat_rd(dev,
- 									realignedChunkInNAND,
- 									buffer,
- 									tags);
- 	if (tags &&
--	   tags->eccResult > YAFFS_ECC_RESULT_NO_ERROR) {
-+	   tags->ecc_result > YAFFS_ECC_RESULT_NO_ERROR) {
- 
--		yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, chunkInNAND/dev->nChunksPerBlock);
--		yaffs_HandleChunkError(dev, bi);
-+		yaffs_block_info_t *bi;
-+		bi = yaffs_get_block_info(dev, nand_chunk/dev->param.chunks_per_block);
-+		yaffs_handle_chunk_error(dev, bi);
- 	}
- 
- 	return result;
- }
- 
--int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
--						   int chunkInNAND,
-+int yaffs_wr_chunk_tags_nand(yaffs_dev_t *dev,
-+						   int nand_chunk,
- 						   const __u8 *buffer,
--						   yaffs_ExtendedTags *tags)
-+						   yaffs_ext_tags *tags)
- {
--	chunkInNAND -= dev->chunkOffset;
-+
-+	dev->n_page_writes++;
-+
-+	nand_chunk -= dev->chunk_offset;
- 
- 
- 	if (tags) {
--		tags->sequenceNumber = dev->sequenceNumber;
--		tags->chunkUsed = 1;
--		if (!yaffs_ValidateTags(tags)) {
-+		tags->seq_number = dev->seq_number;
-+		tags->chunk_used = 1;
-+		if (!yaffs_validate_tags(tags)) {
- 			T(YAFFS_TRACE_ERROR,
- 			  (TSTR("Writing uninitialised tags" TENDSTR)));
- 			YBUG();
- 		}
- 		T(YAFFS_TRACE_WRITE,
--		  (TSTR("Writing chunk %d tags %d %d" TENDSTR), chunkInNAND,
--		   tags->objectId, tags->chunkId));
-+		  (TSTR("Writing chunk %d tags %d %d" TENDSTR), nand_chunk,
-+		   tags->obj_id, tags->chunk_id));
- 	} else {
- 		T(YAFFS_TRACE_ERROR, (TSTR("Writing with no tags" TENDSTR)));
- 		YBUG();
- 	}
- 
--	if (dev->writeChunkWithTagsToNAND)
--		return dev->writeChunkWithTagsToNAND(dev, chunkInNAND, buffer,
-+	if (dev->param.write_chunk_tags_fn)
-+		return dev->param.write_chunk_tags_fn(dev, nand_chunk, buffer,
- 						     tags);
- 	else
--		return yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(dev,
--								       chunkInNAND,
-+		return yaffs_tags_compat_wr(dev,
-+								       nand_chunk,
- 								       buffer,
- 								       tags);
- }
- 
--int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo)
-+int yaffs_mark_bad(yaffs_dev_t *dev, int block_no)
- {
--	blockNo -= dev->blockOffset;
-+	block_no -= dev->block_offset;
-+
- 
--;
--	if (dev->markNANDBlockBad)
--		return dev->markNANDBlockBad(dev, blockNo);
-+	if (dev->param.bad_block_fn)
-+		return dev->param.bad_block_fn(dev, block_no);
- 	else
--		return yaffs_TagsCompatabilityMarkNANDBlockBad(dev, blockNo);
-+		return yaffs_tags_compat_mark_bad(dev, block_no);
- }
- 
--int yaffs_QueryInitialBlockState(yaffs_Device *dev,
--						 int blockNo,
--						 yaffs_BlockState *state,
--						 __u32 *sequenceNumber)
-+int yaffs_query_init_block_state(yaffs_dev_t *dev,
-+						 int block_no,
-+						 yaffs_block_state_t *state,
-+						 __u32 *seq_number)
- {
--	blockNo -= dev->blockOffset;
-+	block_no -= dev->block_offset;
- 
--	if (dev->queryNANDBlock)
--		return dev->queryNANDBlock(dev, blockNo, state, sequenceNumber);
-+	if (dev->param.query_block_fn)
-+		return dev->param.query_block_fn(dev, block_no, state, seq_number);
- 	else
--		return yaffs_TagsCompatabilityQueryNANDBlock(dev, blockNo,
-+		return yaffs_tags_compat_query_block(dev, block_no,
- 							     state,
--							     sequenceNumber);
-+							     seq_number);
- }
- 
- 
--int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
--				  int blockInNAND)
-+int yaffs_erase_block(struct yaffs_dev_s *dev,
-+				  int flash_block)
- {
- 	int result;
- 
--	blockInNAND -= dev->blockOffset;
-+	flash_block -= dev->block_offset;
- 
-+	dev->n_erasures++;
- 
--	dev->nBlockErasures++;
--	result = dev->eraseBlockInNAND(dev, blockInNAND);
-+	result = dev->param.erase_fn(dev, flash_block);
- 
- 	return result;
- }
- 
--int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev)
-+int yaffs_init_nand(struct yaffs_dev_s *dev)
- {
--	return dev->initialiseNAND(dev);
-+	if(dev->param.initialise_flash_fn)
-+		return dev->param.initialise_flash_fn(dev);
-+	return YAFFS_OK;
- }
- 
- 
---- a/fs/yaffs2/yaffs_nandemul2k.h
-+++ b/fs/yaffs2/yaffs_nandemul2k.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -20,18 +20,18 @@
- 
- #include "yaffs_guts.h"
- 
--int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_DeviceStruct *dev,
--					int chunkInNAND, const __u8 *data,
--					const yaffs_ExtendedTags *tags);
--int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_DeviceStruct *dev,
--					 int chunkInNAND, __u8 *data,
--					 yaffs_ExtendedTags *tags);
--int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo);
--int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo,
--			      yaffs_BlockState *state, __u32 *sequenceNumber);
--int nandemul2k_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
--				int blockInNAND);
--int nandemul2k_InitialiseNAND(struct yaffs_DeviceStruct *dev);
-+int nandemul2k_WriteChunkWithTagsToNAND(struct yaffs_dev_s *dev,
-+					int nand_chunk, const __u8 *data,
-+					const yaffs_ext_tags *tags);
-+int nandemul2k_ReadChunkWithTagsFromNAND(struct yaffs_dev_s *dev,
-+					 int nand_chunk, __u8 *data,
-+					 yaffs_ext_tags *tags);
-+int nandemul2k_MarkNANDBlockBad(struct yaffs_dev_s *dev, int block_no);
-+int nandemul2k_QueryNANDBlock(struct yaffs_dev_s *dev, int block_no,
-+			      yaffs_block_state_t *state, __u32 *seq_number);
-+int nandemul2k_EraseBlockInNAND(struct yaffs_dev_s *dev,
-+				int flash_block);
-+int nandemul2k_InitialiseNAND(struct yaffs_dev_s *dev);
- int nandemul2k_GetBytesPerChunk(void);
- int nandemul2k_GetChunksPerBlock(void);
- int nandemul2k_GetNumberOfBlocks(void);
---- a/fs/yaffs2/yaffs_nand.h
-+++ b/fs/yaffs2/yaffs_nand.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -19,26 +19,26 @@
- 
- 
- 
--int yaffs_ReadChunkWithTagsFromNAND(yaffs_Device *dev, int chunkInNAND,
-+int yaffs_rd_chunk_tags_nand(yaffs_dev_t *dev, int nand_chunk,
- 					__u8 *buffer,
--					yaffs_ExtendedTags *tags);
-+					yaffs_ext_tags *tags);
- 
--int yaffs_WriteChunkWithTagsToNAND(yaffs_Device *dev,
--						int chunkInNAND,
-+int yaffs_wr_chunk_tags_nand(yaffs_dev_t *dev,
-+						int nand_chunk,
- 						const __u8 *buffer,
--						yaffs_ExtendedTags *tags);
-+						yaffs_ext_tags *tags);
- 
--int yaffs_MarkBlockBad(yaffs_Device *dev, int blockNo);
-+int yaffs_mark_bad(yaffs_dev_t *dev, int block_no);
- 
--int yaffs_QueryInitialBlockState(yaffs_Device *dev,
--						int blockNo,
--						yaffs_BlockState *state,
--						unsigned *sequenceNumber);
-+int yaffs_query_init_block_state(yaffs_dev_t *dev,
-+						int block_no,
-+						yaffs_block_state_t *state,
-+						unsigned *seq_number);
- 
--int yaffs_EraseBlockInNAND(struct yaffs_DeviceStruct *dev,
--				  int blockInNAND);
-+int yaffs_erase_block(struct yaffs_dev_s *dev,
-+				  int flash_block);
- 
--int yaffs_InitialiseNAND(struct yaffs_DeviceStruct *dev);
-+int yaffs_init_nand(struct yaffs_dev_s *dev);
- 
- #endif
- 
---- a/fs/yaffs2/yaffs_packedtags1.c
-+++ b/fs/yaffs2/yaffs_packedtags1.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -14,37 +14,37 @@
- #include "yaffs_packedtags1.h"
- #include "yportenv.h"
- 
--void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ExtendedTags *t)
-+void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ext_tags *t)
- {
--	pt->chunkId = t->chunkId;
--	pt->serialNumber = t->serialNumber;
--	pt->byteCount = t->byteCount;
--	pt->objectId = t->objectId;
-+	pt->chunk_id = t->chunk_id;
-+	pt->serial_number = t->serial_number;
-+	pt->n_bytes = t->n_bytes;
-+	pt->obj_id = t->obj_id;
- 	pt->ecc = 0;
--	pt->deleted = (t->chunkDeleted) ? 0 : 1;
-+	pt->deleted = (t->is_deleted) ? 0 : 1;
- 	pt->unusedStuff = 0;
- 	pt->shouldBeFF = 0xFFFFFFFF;
- 
- }
- 
--void yaffs_UnpackTags1(yaffs_ExtendedTags *t, const yaffs_PackedTags1 *pt)
-+void yaffs_unpack_tags1(yaffs_ext_tags *t, const yaffs_PackedTags1 *pt)
- {
- 	static const __u8 allFF[] =
- 	    { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff };
- 
- 	if (memcmp(allFF, pt, sizeof(yaffs_PackedTags1))) {
--		t->blockBad = 0;
-+		t->block_bad = 0;
- 		if (pt->shouldBeFF != 0xFFFFFFFF)
--			t->blockBad = 1;
--		t->chunkUsed = 1;
--		t->objectId = pt->objectId;
--		t->chunkId = pt->chunkId;
--		t->byteCount = pt->byteCount;
--		t->eccResult = YAFFS_ECC_RESULT_NO_ERROR;
--		t->chunkDeleted = (pt->deleted) ? 0 : 1;
--		t->serialNumber = pt->serialNumber;
-+			t->block_bad = 1;
-+		t->chunk_used = 1;
-+		t->obj_id = pt->obj_id;
-+		t->chunk_id = pt->chunk_id;
-+		t->n_bytes = pt->n_bytes;
-+		t->ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
-+		t->is_deleted = (pt->deleted) ? 0 : 1;
-+		t->serial_number = pt->serial_number;
- 	} else {
--		memset(t, 0, sizeof(yaffs_ExtendedTags));
-+		memset(t, 0, sizeof(yaffs_ext_tags));
- 	}
- }
---- a/fs/yaffs2/yaffs_packedtags1.h
-+++ b/fs/yaffs2/yaffs_packedtags1.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -21,10 +21,10 @@
- #include "yaffs_guts.h"
- 
- typedef struct {
--	unsigned chunkId:20;
--	unsigned serialNumber:2;
--	unsigned byteCount:10;
--	unsigned objectId:18;
-+	unsigned chunk_id:20;
-+	unsigned serial_number:2;
-+	unsigned n_bytes:10;
-+	unsigned obj_id:18;
- 	unsigned ecc:12;
- 	unsigned deleted:1;
- 	unsigned unusedStuff:1;
-@@ -32,6 +32,6 @@ typedef struct {
- 
- } yaffs_PackedTags1;
- 
--void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ExtendedTags *t);
--void yaffs_UnpackTags1(yaffs_ExtendedTags *t, const yaffs_PackedTags1 *pt);
-+void yaffs_PackTags1(yaffs_PackedTags1 *pt, const yaffs_ext_tags *t);
-+void yaffs_unpack_tags1(yaffs_ext_tags *t, const yaffs_PackedTags1 *pt);
- #endif
---- a/fs/yaffs2/yaffs_packedtags2.c
-+++ b/fs/yaffs2/yaffs_packedtags2.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -13,6 +13,7 @@
- 
- #include "yaffs_packedtags2.h"
- #include "yportenv.h"
-+#include "yaffs_trace.h"
- #include "yaffs_tagsvalidity.h"
- 
- /* This code packs a set of extended tags into a binary structure for
-@@ -24,7 +25,7 @@
-  * This is defined by having the EXTRA_HEADER_INFO_FLAG set.
-  */
- 
--/* Extra flags applied to chunkId */
-+/* Extra flags applied to chunk_id */
- 
- #define EXTRA_HEADER_INFO_FLAG	0x80000000
- #define EXTRA_SHRINK_FLAG	0x40000000
-@@ -42,53 +43,53 @@ static void yaffs_DumpPackedTags2TagsPar
- {
- 	T(YAFFS_TRACE_MTD,
- 	  (TSTR("packed tags obj %d chunk %d byte %d seq %d" TENDSTR),
--	   ptt->objectId, ptt->chunkId, ptt->byteCount,
--	   ptt->sequenceNumber));
-+	   ptt->obj_id, ptt->chunk_id, ptt->n_bytes,
-+	   ptt->seq_number));
- }
- static void yaffs_DumpPackedTags2(const yaffs_PackedTags2 *pt)
- {
- 	yaffs_DumpPackedTags2TagsPart(&pt->t);
- }
- 
--static void yaffs_DumpTags2(const yaffs_ExtendedTags *t)
-+static void yaffs_DumpTags2(const yaffs_ext_tags *t)
- {
- 	T(YAFFS_TRACE_MTD,
- 	  (TSTR
- 	   ("ext.tags eccres %d blkbad %d chused %d obj %d chunk%d byte %d del %d ser %d seq %d"
--	    TENDSTR), t->eccResult, t->blockBad, t->chunkUsed, t->objectId,
--	   t->chunkId, t->byteCount, t->chunkDeleted, t->serialNumber,
--	   t->sequenceNumber));
-+	    TENDSTR), t->ecc_result, t->block_bad, t->chunk_used, t->obj_id,
-+	   t->chunk_id, t->n_bytes, t->is_deleted, t->serial_number,
-+	   t->seq_number));
- 
- }
- 
- void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *ptt,
--		const yaffs_ExtendedTags *t)
-+		const yaffs_ext_tags *t)
- {
--	ptt->chunkId = t->chunkId;
--	ptt->sequenceNumber = t->sequenceNumber;
--	ptt->byteCount = t->byteCount;
--	ptt->objectId = t->objectId;
-+	ptt->chunk_id = t->chunk_id;
-+	ptt->seq_number = t->seq_number;
-+	ptt->n_bytes = t->n_bytes;
-+	ptt->obj_id = t->obj_id;
- 
--	if (t->chunkId == 0 && t->extraHeaderInfoAvailable) {
-+	if (t->chunk_id == 0 && t->extra_available) {
- 		/* Store the extra header info instead */
--		/* We save the parent object in the chunkId */
--		ptt->chunkId = EXTRA_HEADER_INFO_FLAG
--			| t->extraParentObjectId;
--		if (t->extraIsShrinkHeader)
--			ptt->chunkId |= EXTRA_SHRINK_FLAG;
--		if (t->extraShadows)
--			ptt->chunkId |= EXTRA_SHADOWS_FLAG;
--
--		ptt->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
--		ptt->objectId |=
--		    (t->extraObjectType << EXTRA_OBJECT_TYPE_SHIFT);
--
--		if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK)
--			ptt->byteCount = t->extraEquivalentObjectId;
--		else if (t->extraObjectType == YAFFS_OBJECT_TYPE_FILE)
--			ptt->byteCount = t->extraFileLength;
-+		/* We save the parent object in the chunk_id */
-+		ptt->chunk_id = EXTRA_HEADER_INFO_FLAG
-+			| t->extra_parent_id;
-+		if (t->extra_is_shrink)
-+			ptt->chunk_id |= EXTRA_SHRINK_FLAG;
-+		if (t->extra_shadows)
-+			ptt->chunk_id |= EXTRA_SHADOWS_FLAG;
-+
-+		ptt->obj_id &= ~EXTRA_OBJECT_TYPE_MASK;
-+		ptt->obj_id |=
-+		    (t->extra_obj_type << EXTRA_OBJECT_TYPE_SHIFT);
-+
-+		if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK)
-+			ptt->n_bytes = t->extra_equiv_id;
-+		else if (t->extra_obj_type == YAFFS_OBJECT_TYPE_FILE)
-+			ptt->n_bytes = t->extra_length;
- 		else
--			ptt->byteCount = 0;
-+			ptt->n_bytes = 0;
- 	}
- 
- 	yaffs_DumpPackedTags2TagsPart(ptt);
-@@ -96,59 +97,56 @@ void yaffs_PackTags2TagsPart(yaffs_Packe
- }
- 
- 
--void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t)
-+void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ext_tags *t, int tagsECC)
- {
- 	yaffs_PackTags2TagsPart(&pt->t, t);
- 
--#ifndef YAFFS_IGNORE_TAGS_ECC
--	{
--		yaffs_ECCCalculateOther((unsigned char *)&pt->t,
-+	if(tagsECC)
-+		yaffs_ecc_calc_other((unsigned char *)&pt->t,
- 					sizeof(yaffs_PackedTags2TagsPart),
- 					&pt->ecc);
--	}
--#endif
- }
- 
- 
--void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags *t,
-+void yaffs_unpack_tags2tags_part(yaffs_ext_tags *t,
- 		yaffs_PackedTags2TagsPart *ptt)
- {
- 
--	memset(t, 0, sizeof(yaffs_ExtendedTags));
-+	memset(t, 0, sizeof(yaffs_ext_tags));
- 
--	yaffs_InitialiseTags(t);
-+	yaffs_init_tags(t);
- 
--	if (ptt->sequenceNumber != 0xFFFFFFFF) {
--		t->blockBad = 0;
--		t->chunkUsed = 1;
--		t->objectId = ptt->objectId;
--		t->chunkId = ptt->chunkId;
--		t->byteCount = ptt->byteCount;
--		t->chunkDeleted = 0;
--		t->serialNumber = 0;
--		t->sequenceNumber = ptt->sequenceNumber;
-+	if (ptt->seq_number != 0xFFFFFFFF) {
-+		t->block_bad = 0;
-+		t->chunk_used = 1;
-+		t->obj_id = ptt->obj_id;
-+		t->chunk_id = ptt->chunk_id;
-+		t->n_bytes = ptt->n_bytes;
-+		t->is_deleted = 0;
-+		t->serial_number = 0;
-+		t->seq_number = ptt->seq_number;
- 
- 		/* Do extra header info stuff */
- 
--		if (ptt->chunkId & EXTRA_HEADER_INFO_FLAG) {
--			t->chunkId = 0;
--			t->byteCount = 0;
--
--			t->extraHeaderInfoAvailable = 1;
--			t->extraParentObjectId =
--			    ptt->chunkId & (~(ALL_EXTRA_FLAGS));
--			t->extraIsShrinkHeader =
--			    (ptt->chunkId & EXTRA_SHRINK_FLAG) ? 1 : 0;
--			t->extraShadows =
--			    (ptt->chunkId & EXTRA_SHADOWS_FLAG) ? 1 : 0;
--			t->extraObjectType =
--			    ptt->objectId >> EXTRA_OBJECT_TYPE_SHIFT;
--			t->objectId &= ~EXTRA_OBJECT_TYPE_MASK;
-+		if (ptt->chunk_id & EXTRA_HEADER_INFO_FLAG) {
-+			t->chunk_id = 0;
-+			t->n_bytes = 0;
-+
-+			t->extra_available = 1;
-+			t->extra_parent_id =
-+			    ptt->chunk_id & (~(ALL_EXTRA_FLAGS));
-+			t->extra_is_shrink =
-+			    (ptt->chunk_id & EXTRA_SHRINK_FLAG) ? 1 : 0;
-+			t->extra_shadows =
-+			    (ptt->chunk_id & EXTRA_SHADOWS_FLAG) ? 1 : 0;
-+			t->extra_obj_type =
-+			    ptt->obj_id >> EXTRA_OBJECT_TYPE_SHIFT;
-+			t->obj_id &= ~EXTRA_OBJECT_TYPE_MASK;
- 
--			if (t->extraObjectType == YAFFS_OBJECT_TYPE_HARDLINK)
--				t->extraEquivalentObjectId = ptt->byteCount;
-+			if (t->extra_obj_type == YAFFS_OBJECT_TYPE_HARDLINK)
-+				t->extra_equiv_id = ptt->n_bytes;
- 			else
--				t->extraFileLength = ptt->byteCount;
-+				t->extra_length = ptt->n_bytes;
- 		}
- 	}
- 
-@@ -158,49 +156,43 @@ void yaffs_UnpackTags2TagsPart(yaffs_Ext
- }
- 
- 
--void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt)
-+void yaffs_unpack_tags2(yaffs_ext_tags *t, yaffs_PackedTags2 *pt, int tagsECC)
- {
- 
--	yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_NO_ERROR;
-+	yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
- 
--	if (pt->t.sequenceNumber != 0xFFFFFFFF) {
--		/* Page is in use */
--#ifndef YAFFS_IGNORE_TAGS_ECC
--		{
--			yaffs_ECCOther ecc;
--			int result;
--			yaffs_ECCCalculateOther((unsigned char *)&pt->t,
--						sizeof
--						(yaffs_PackedTags2TagsPart),
--						&ecc);
--			result =
--			    yaffs_ECCCorrectOther((unsigned char *)&pt->t,
--						  sizeof
--						  (yaffs_PackedTags2TagsPart),
--						  &pt->ecc, &ecc);
--			switch (result) {
-+	if (pt->t.seq_number != 0xFFFFFFFF &&
-+	    tagsECC){
-+		/* Chunk is in use and we need to do ECC */
-+		
-+		yaffs_ECCOther ecc;
-+		int result;
-+		yaffs_ecc_calc_other((unsigned char *)&pt->t,
-+					sizeof(yaffs_PackedTags2TagsPart),
-+					&ecc);
-+		result = yaffs_ecc_correct_other((unsigned char *)&pt->t,
-+						sizeof(yaffs_PackedTags2TagsPart),
-+						&pt->ecc, &ecc);
-+		switch (result) {
- 			case 0:
--				eccResult = YAFFS_ECC_RESULT_NO_ERROR;
-+				ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
- 				break;
- 			case 1:
--				eccResult = YAFFS_ECC_RESULT_FIXED;
-+				ecc_result = YAFFS_ECC_RESULT_FIXED;
- 				break;
- 			case -1:
--				eccResult = YAFFS_ECC_RESULT_UNFIXED;
-+				ecc_result = YAFFS_ECC_RESULT_UNFIXED;
- 				break;
- 			default:
--				eccResult = YAFFS_ECC_RESULT_UNKNOWN;
--			}
-+				ecc_result = YAFFS_ECC_RESULT_UNKNOWN;
- 		}
--#endif
- 	}
- 
--	yaffs_UnpackTags2TagsPart(t, &pt->t);
-+	yaffs_unpack_tags2tags_part(t, &pt->t);
- 
--	t->eccResult = eccResult;
-+	t->ecc_result = ecc_result;
- 
- 	yaffs_DumpPackedTags2(pt);
- 	yaffs_DumpTags2(t);
--
- }
- 
---- a/fs/yaffs2/yaffs_packedtags2.h
-+++ b/fs/yaffs2/yaffs_packedtags2.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -22,10 +22,10 @@
- #include "yaffs_ecc.h"
- 
- typedef struct {
--	unsigned sequenceNumber;
--	unsigned objectId;
--	unsigned chunkId;
--	unsigned byteCount;
-+	unsigned seq_number;
-+	unsigned obj_id;
-+	unsigned chunk_id;
-+	unsigned n_bytes;
- } yaffs_PackedTags2TagsPart;
- 
- typedef struct {
-@@ -34,10 +34,10 @@ typedef struct {
- } yaffs_PackedTags2;
- 
- /* Full packed tags with ECC, used for oob tags */
--void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ExtendedTags *t);
--void yaffs_UnpackTags2(yaffs_ExtendedTags *t, yaffs_PackedTags2 *pt);
-+void yaffs_PackTags2(yaffs_PackedTags2 *pt, const yaffs_ext_tags *t, int tagsECC);
-+void yaffs_unpack_tags2(yaffs_ext_tags *t, yaffs_PackedTags2 *pt, int tagsECC);
- 
- /* Only the tags part (no ECC for use with inband tags */
--void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *pt, const yaffs_ExtendedTags *t);
--void yaffs_UnpackTags2TagsPart(yaffs_ExtendedTags *t, yaffs_PackedTags2TagsPart *pt);
-+void yaffs_PackTags2TagsPart(yaffs_PackedTags2TagsPart *pt, const yaffs_ext_tags *t);
-+void yaffs_unpack_tags2tags_part(yaffs_ext_tags *t, yaffs_PackedTags2TagsPart *pt);
- #endif
---- a/fs/yaffs2/yaffs_qsort.h
-+++ b/fs/yaffs2/yaffs_qsort.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -17,7 +17,18 @@
- #ifndef __YAFFS_QSORT_H__
- #define __YAFFS_QSORT_H__
- 
-+#ifdef __KERNEL__
-+#include <linux/sort.h>
-+
-+extern void yaffs_qsort(void *const base, size_t total_elems, size_t size,
-+			int (*cmp)(const void *, const void *)){
-+	sort(base, total_elems, size, cmp, NULL);
-+}
-+
-+#else
-+
- extern void yaffs_qsort(void *const base, size_t total_elems, size_t size,
- 			int (*cmp)(const void *, const void *));
- 
- #endif
-+#endif
---- a/fs/yaffs2/yaffs_tagscompat.c
-+++ b/fs/yaffs2/yaffs_tagscompat.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -15,19 +15,20 @@
- #include "yaffs_tagscompat.h"
- #include "yaffs_ecc.h"
- #include "yaffs_getblockinfo.h"
-+#include "yaffs_trace.h"
- 
--static void yaffs_HandleReadDataError(yaffs_Device *dev, int chunkInNAND);
-+static void yaffs_handle_rd_data_error(yaffs_dev_t *dev, int nand_chunk);
- #ifdef NOTYET
--static void yaffs_CheckWrittenBlock(yaffs_Device *dev, int chunkInNAND);
--static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
-+static void yaffs_check_written_block(yaffs_dev_t *dev, int nand_chunk);
-+static void yaffs_handle_chunk_wr_ok(yaffs_dev_t *dev, int nand_chunk,
- 				     const __u8 *data,
--				     const yaffs_Spare *spare);
--static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
--				    const yaffs_Spare *spare);
--static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND);
-+				     const yaffs_spare *spare);
-+static void yaffs_handle_chunk_update(yaffs_dev_t *dev, int nand_chunk,
-+				    const yaffs_spare *spare);
-+static void yaffs_handle_chunk_wr_error(yaffs_dev_t *dev, int nand_chunk);
- #endif
- 
--static const char yaffs_countBitsTable[256] = {
-+static const char yaffs_count_bits_table[256] = {
- 	0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
- 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
- 	1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
-@@ -46,26 +47,26 @@ static const char yaffs_countBitsTable[2
- 	4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
- };
- 
--int yaffs_CountBits(__u8 x)
-+int yaffs_count_bits(__u8 x)
- {
- 	int retVal;
--	retVal = yaffs_countBitsTable[x];
-+	retVal = yaffs_count_bits_table[x];
- 	return retVal;
- }
- 
- /********** Tags ECC calculations  *********/
- 
--void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare)
-+void yaffs_calc_ecc(const __u8 *data, yaffs_spare *spare)
- {
--	yaffs_ECCCalculate(data, spare->ecc1);
--	yaffs_ECCCalculate(&data[256], spare->ecc2);
-+	yaffs_ecc_cacl(data, spare->ecc1);
-+	yaffs_ecc_cacl(&data[256], spare->ecc2);
- }
- 
--void yaffs_CalcTagsECC(yaffs_Tags *tags)
-+void yaffs_calc_tags_ecc(yaffs_tags_t *tags)
- {
- 	/* Calculate an ecc */
- 
--	unsigned char *b = ((yaffs_TagsUnion *) tags)->asBytes;
-+	unsigned char *b = ((yaffs_tags_union_t *) tags)->as_bytes;
- 	unsigned i, j;
- 	unsigned ecc = 0;
- 	unsigned bit = 0;
-@@ -84,24 +85,24 @@ void yaffs_CalcTagsECC(yaffs_Tags *tags)
- 
- }
- 
--int yaffs_CheckECCOnTags(yaffs_Tags *tags)
-+int yaffs_check_tags_ecc(yaffs_tags_t *tags)
- {
- 	unsigned ecc = tags->ecc;
- 
--	yaffs_CalcTagsECC(tags);
-+	yaffs_calc_tags_ecc(tags);
- 
- 	ecc ^= tags->ecc;
- 
- 	if (ecc && ecc <= 64) {
- 		/* TODO: Handle the failure better. Retire? */
--		unsigned char *b = ((yaffs_TagsUnion *) tags)->asBytes;
-+		unsigned char *b = ((yaffs_tags_union_t *) tags)->as_bytes;
- 
- 		ecc--;
- 
- 		b[ecc / 8] ^= (1 << (ecc & 7));
- 
- 		/* Now recvalc the ecc */
--		yaffs_CalcTagsECC(tags);
-+		yaffs_calc_tags_ecc(tags);
- 
- 		return 1;	/* recovered error */
- 	} else if (ecc) {
-@@ -115,76 +116,73 @@ int yaffs_CheckECCOnTags(yaffs_Tags *tag
- 
- /********** Tags **********/
- 
--static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr,
--				yaffs_Tags *tagsPtr)
-+static void yaffs_load_tags_to_spare(yaffs_spare *sparePtr,
-+				yaffs_tags_t *tagsPtr)
- {
--	yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr;
-+	yaffs_tags_union_t *tu = (yaffs_tags_union_t *) tagsPtr;
- 
--	yaffs_CalcTagsECC(tagsPtr);
-+	yaffs_calc_tags_ecc(tagsPtr);
- 
--	sparePtr->tagByte0 = tu->asBytes[0];
--	sparePtr->tagByte1 = tu->asBytes[1];
--	sparePtr->tagByte2 = tu->asBytes[2];
--	sparePtr->tagByte3 = tu->asBytes[3];
--	sparePtr->tagByte4 = tu->asBytes[4];
--	sparePtr->tagByte5 = tu->asBytes[5];
--	sparePtr->tagByte6 = tu->asBytes[6];
--	sparePtr->tagByte7 = tu->asBytes[7];
-+	sparePtr->tb0 = tu->as_bytes[0];
-+	sparePtr->tb1 = tu->as_bytes[1];
-+	sparePtr->tb2 = tu->as_bytes[2];
-+	sparePtr->tb3 = tu->as_bytes[3];
-+	sparePtr->tb4 = tu->as_bytes[4];
-+	sparePtr->tb5 = tu->as_bytes[5];
-+	sparePtr->tb6 = tu->as_bytes[6];
-+	sparePtr->tb7 = tu->as_bytes[7];
- }
- 
--static void yaffs_GetTagsFromSpare(yaffs_Device *dev, yaffs_Spare *sparePtr,
--				yaffs_Tags *tagsPtr)
-+static void yaffs_get_tags_from_spare(yaffs_dev_t *dev, yaffs_spare *sparePtr,
-+				yaffs_tags_t *tagsPtr)
- {
--	yaffs_TagsUnion *tu = (yaffs_TagsUnion *) tagsPtr;
-+	yaffs_tags_union_t *tu = (yaffs_tags_union_t *) tagsPtr;
- 	int result;
- 
--	tu->asBytes[0] = sparePtr->tagByte0;
--	tu->asBytes[1] = sparePtr->tagByte1;
--	tu->asBytes[2] = sparePtr->tagByte2;
--	tu->asBytes[3] = sparePtr->tagByte3;
--	tu->asBytes[4] = sparePtr->tagByte4;
--	tu->asBytes[5] = sparePtr->tagByte5;
--	tu->asBytes[6] = sparePtr->tagByte6;
--	tu->asBytes[7] = sparePtr->tagByte7;
-+	tu->as_bytes[0] = sparePtr->tb0;
-+	tu->as_bytes[1] = sparePtr->tb1;
-+	tu->as_bytes[2] = sparePtr->tb2;
-+	tu->as_bytes[3] = sparePtr->tb3;
-+	tu->as_bytes[4] = sparePtr->tb4;
-+	tu->as_bytes[5] = sparePtr->tb5;
-+	tu->as_bytes[6] = sparePtr->tb6;
-+	tu->as_bytes[7] = sparePtr->tb7;
- 
--	result = yaffs_CheckECCOnTags(tagsPtr);
-+	result = yaffs_check_tags_ecc(tagsPtr);
- 	if (result > 0)
--		dev->tagsEccFixed++;
-+		dev->n_tags_ecc_fixed++;
- 	else if (result < 0)
--		dev->tagsEccUnfixed++;
-+		dev->n_tags_ecc_unfixed++;
- }
- 
--static void yaffs_SpareInitialise(yaffs_Spare *spare)
-+static void yaffs_spare_init(yaffs_spare *spare)
- {
--	memset(spare, 0xFF, sizeof(yaffs_Spare));
-+	memset(spare, 0xFF, sizeof(yaffs_spare));
- }
- 
--static int yaffs_WriteChunkToNAND(struct yaffs_DeviceStruct *dev,
--				int chunkInNAND, const __u8 *data,
--				yaffs_Spare *spare)
-+static int yaffs_wr_nand(struct yaffs_dev_s *dev,
-+				int nand_chunk, const __u8 *data,
-+				yaffs_spare *spare)
- {
--	if (chunkInNAND < dev->startBlock * dev->nChunksPerBlock) {
-+	if (nand_chunk < dev->param.start_block * dev->param.chunks_per_block) {
- 		T(YAFFS_TRACE_ERROR,
- 		  (TSTR("**>> yaffs chunk %d is not valid" TENDSTR),
--		   chunkInNAND));
-+		   nand_chunk));
- 		return YAFFS_FAIL;
- 	}
- 
--	dev->nPageWrites++;
--	return dev->writeChunkToNAND(dev, chunkInNAND, data, spare);
-+	return dev->param.write_chunk_fn(dev, nand_chunk, data, spare);
- }
- 
--static int yaffs_ReadChunkFromNAND(struct yaffs_DeviceStruct *dev,
--				   int chunkInNAND,
-+static int yaffs_rd_chunk_nand(struct yaffs_dev_s *dev,
-+				   int nand_chunk,
- 				   __u8 *data,
--				   yaffs_Spare *spare,
--				   yaffs_ECCResult *eccResult,
-+				   yaffs_spare *spare,
-+				   yaffs_ecc_result *ecc_result,
- 				   int doErrorCorrection)
- {
- 	int retVal;
--	yaffs_Spare localSpare;
--
--	dev->nPageReads++;
-+	yaffs_spare localSpare;
- 
- 	if (!spare && data) {
- 		/* If we don't have a real spare, then we use a local one. */
-@@ -192,107 +190,107 @@ static int yaffs_ReadChunkFromNAND(struc
- 		spare = &localSpare;
- 	}
- 
--	if (!dev->useNANDECC) {
--		retVal = dev->readChunkFromNAND(dev, chunkInNAND, data, spare);
-+	if (!dev->param.use_nand_ecc) {
-+		retVal = dev->param.read_chunk_fn(dev, nand_chunk, data, spare);
- 		if (data && doErrorCorrection) {
- 			/* Do ECC correction */
- 			/* Todo handle any errors */
--			int eccResult1, eccResult2;
-+			int ecc_result1, ecc_result2;
- 			__u8 calcEcc[3];
- 
--			yaffs_ECCCalculate(data, calcEcc);
--			eccResult1 =
--			    yaffs_ECCCorrect(data, spare->ecc1, calcEcc);
--			yaffs_ECCCalculate(&data[256], calcEcc);
--			eccResult2 =
--			    yaffs_ECCCorrect(&data[256], spare->ecc2, calcEcc);
-+			yaffs_ecc_cacl(data, calcEcc);
-+			ecc_result1 =
-+			    yaffs_ecc_correct(data, spare->ecc1, calcEcc);
-+			yaffs_ecc_cacl(&data[256], calcEcc);
-+			ecc_result2 =
-+			    yaffs_ecc_correct(&data[256], spare->ecc2, calcEcc);
- 
--			if (eccResult1 > 0) {
-+			if (ecc_result1 > 0) {
- 				T(YAFFS_TRACE_ERROR,
- 				  (TSTR
- 				   ("**>>yaffs ecc error fix performed on chunk %d:0"
--				    TENDSTR), chunkInNAND));
--				dev->eccFixed++;
--			} else if (eccResult1 < 0) {
-+				    TENDSTR), nand_chunk));
-+				dev->n_ecc_fixed++;
-+			} else if (ecc_result1 < 0) {
- 				T(YAFFS_TRACE_ERROR,
- 				  (TSTR
- 				   ("**>>yaffs ecc error unfixed on chunk %d:0"
--				    TENDSTR), chunkInNAND));
--				dev->eccUnfixed++;
-+				    TENDSTR), nand_chunk));
-+				dev->n_ecc_unfixed++;
- 			}
- 
--			if (eccResult2 > 0) {
-+			if (ecc_result2 > 0) {
- 				T(YAFFS_TRACE_ERROR,
- 				  (TSTR
- 				   ("**>>yaffs ecc error fix performed on chunk %d:1"
--				    TENDSTR), chunkInNAND));
--				dev->eccFixed++;
--			} else if (eccResult2 < 0) {
-+				    TENDSTR), nand_chunk));
-+				dev->n_ecc_fixed++;
-+			} else if (ecc_result2 < 0) {
- 				T(YAFFS_TRACE_ERROR,
- 				  (TSTR
- 				   ("**>>yaffs ecc error unfixed on chunk %d:1"
--				    TENDSTR), chunkInNAND));
--				dev->eccUnfixed++;
-+				    TENDSTR), nand_chunk));
-+				dev->n_ecc_unfixed++;
- 			}
- 
--			if (eccResult1 || eccResult2) {
-+			if (ecc_result1 || ecc_result2) {
- 				/* We had a data problem on this page */
--				yaffs_HandleReadDataError(dev, chunkInNAND);
-+				yaffs_handle_rd_data_error(dev, nand_chunk);
- 			}
- 
--			if (eccResult1 < 0 || eccResult2 < 0)
--				*eccResult = YAFFS_ECC_RESULT_UNFIXED;
--			else if (eccResult1 > 0 || eccResult2 > 0)
--				*eccResult = YAFFS_ECC_RESULT_FIXED;
-+			if (ecc_result1 < 0 || ecc_result2 < 0)
-+				*ecc_result = YAFFS_ECC_RESULT_UNFIXED;
-+			else if (ecc_result1 > 0 || ecc_result2 > 0)
-+				*ecc_result = YAFFS_ECC_RESULT_FIXED;
- 			else
--				*eccResult = YAFFS_ECC_RESULT_NO_ERROR;
-+				*ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
- 		}
- 	} else {
- 		/* Must allocate enough memory for spare+2*sizeof(int) */
- 		/* for ecc results from device. */
--		struct yaffs_NANDSpare nspare;
-+		struct yaffs_nand_spare nspare;
- 
- 		memset(&nspare, 0, sizeof(nspare));
- 
--		retVal = dev->readChunkFromNAND(dev, chunkInNAND, data,
--					(yaffs_Spare *) &nspare);
--		memcpy(spare, &nspare, sizeof(yaffs_Spare));
-+		retVal = dev->param.read_chunk_fn(dev, nand_chunk, data,
-+					(yaffs_spare *) &nspare);
-+		memcpy(spare, &nspare, sizeof(yaffs_spare));
- 		if (data && doErrorCorrection) {
- 			if (nspare.eccres1 > 0) {
- 				T(YAFFS_TRACE_ERROR,
- 				  (TSTR
- 				   ("**>>mtd ecc error fix performed on chunk %d:0"
--				    TENDSTR), chunkInNAND));
-+				    TENDSTR), nand_chunk));
- 			} else if (nspare.eccres1 < 0) {
- 				T(YAFFS_TRACE_ERROR,
- 				  (TSTR
- 				   ("**>>mtd ecc error unfixed on chunk %d:0"
--				    TENDSTR), chunkInNAND));
-+				    TENDSTR), nand_chunk));
- 			}
- 
- 			if (nspare.eccres2 > 0) {
- 				T(YAFFS_TRACE_ERROR,
- 				  (TSTR
- 				   ("**>>mtd ecc error fix performed on chunk %d:1"
--				    TENDSTR), chunkInNAND));
-+				    TENDSTR), nand_chunk));
- 			} else if (nspare.eccres2 < 0) {
- 				T(YAFFS_TRACE_ERROR,
- 				  (TSTR
- 				   ("**>>mtd ecc error unfixed on chunk %d:1"
--				    TENDSTR), chunkInNAND));
-+				    TENDSTR), nand_chunk));
- 			}
- 
- 			if (nspare.eccres1 || nspare.eccres2) {
- 				/* We had a data problem on this page */
--				yaffs_HandleReadDataError(dev, chunkInNAND);
-+				yaffs_handle_rd_data_error(dev, nand_chunk);
- 			}
- 
- 			if (nspare.eccres1 < 0 || nspare.eccres2 < 0)
--				*eccResult = YAFFS_ECC_RESULT_UNFIXED;
-+				*ecc_result = YAFFS_ECC_RESULT_UNFIXED;
- 			else if (nspare.eccres1 > 0 || nspare.eccres2 > 0)
--				*eccResult = YAFFS_ECC_RESULT_FIXED;
-+				*ecc_result = YAFFS_ECC_RESULT_FIXED;
- 			else
--				*eccResult = YAFFS_ECC_RESULT_NO_ERROR;
-+				*ecc_result = YAFFS_ECC_RESULT_NO_ERROR;
- 
- 		}
- 	}
-@@ -300,17 +298,17 @@ static int yaffs_ReadChunkFromNAND(struc
- }
- 
- #ifdef NOTYET
--static int yaffs_CheckChunkErased(struct yaffs_DeviceStruct *dev,
--				  int chunkInNAND)
-+static int yaffs_check_chunk_erased(struct yaffs_dev_s *dev,
-+				  int nand_chunk)
- {
- 	static int init;
- 	static __u8 cmpbuf[YAFFS_BYTES_PER_CHUNK];
- 	static __u8 data[YAFFS_BYTES_PER_CHUNK];
- 	/* Might as well always allocate the larger size for */
--	/* dev->useNANDECC == true; */
--	static __u8 spare[sizeof(struct yaffs_NANDSpare)];
-+	/* dev->param.use_nand_ecc == true; */
-+	static __u8 spare[sizeof(struct yaffs_nand_spare)];
- 
--	dev->readChunkFromNAND(dev, chunkInNAND, data, (yaffs_Spare *) spare);
-+	dev->param.read_chunk_fn(dev, nand_chunk, data, (yaffs_spare *) spare);
- 
- 	if (!init) {
- 		memset(cmpbuf, 0xff, YAFFS_BYTES_PER_CHUNK);
-@@ -331,14 +329,14 @@ static int yaffs_CheckChunkErased(struct
-  * Functions for robustisizing
-  */
- 
--static void yaffs_HandleReadDataError(yaffs_Device *dev, int chunkInNAND)
-+static void yaffs_handle_rd_data_error(yaffs_dev_t *dev, int nand_chunk)
- {
--	int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
-+	int flash_block = nand_chunk / dev->param.chunks_per_block;
- 
- 	/* Mark the block for retirement */
--	yaffs_GetBlockInfo(dev, blockInNAND + dev->blockOffset)->needsRetiring = 1;
-+	yaffs_get_block_info(dev, flash_block + dev->block_offset)->needs_retiring = 1;
- 	T(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
--	  (TSTR("**>>Block %d marked for retirement" TENDSTR), blockInNAND));
-+	  (TSTR("**>>Block %d marked for retirement" TENDSTR), flash_block));
- 
- 	/* TODO:
- 	 * Just do a garbage collection on the affected block
-@@ -348,44 +346,44 @@ static void yaffs_HandleReadDataError(ya
- }
- 
- #ifdef NOTYET
--static void yaffs_CheckWrittenBlock(yaffs_Device *dev, int chunkInNAND)
-+static void yaffs_check_written_block(yaffs_dev_t *dev, int nand_chunk)
- {
- }
- 
--static void yaffs_HandleWriteChunkOk(yaffs_Device *dev, int chunkInNAND,
-+static void yaffs_handle_chunk_wr_ok(yaffs_dev_t *dev, int nand_chunk,
- 				     const __u8 *data,
--				     const yaffs_Spare *spare)
-+				     const yaffs_spare *spare)
- {
- }
- 
--static void yaffs_HandleUpdateChunk(yaffs_Device *dev, int chunkInNAND,
--				    const yaffs_Spare *spare)
-+static void yaffs_handle_chunk_update(yaffs_dev_t *dev, int nand_chunk,
-+				    const yaffs_spare *spare)
- {
- }
- 
--static void yaffs_HandleWriteChunkError(yaffs_Device *dev, int chunkInNAND)
-+static void yaffs_handle_chunk_wr_error(yaffs_dev_t *dev, int nand_chunk)
- {
--	int blockInNAND = chunkInNAND / dev->nChunksPerBlock;
-+	int flash_block = nand_chunk / dev->param.chunks_per_block;
- 
- 	/* Mark the block for retirement */
--	yaffs_GetBlockInfo(dev, blockInNAND)->needsRetiring = 1;
-+	yaffs_get_block_info(dev, flash_block)->needs_retiring = 1;
- 	/* Delete the chunk */
--	yaffs_DeleteChunk(dev, chunkInNAND, 1, __LINE__);
-+	yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
- }
- 
--static int yaffs_VerifyCompare(const __u8 *d0, const __u8 *d1,
--			       const yaffs_Spare *s0, const yaffs_Spare *s1)
-+static int yaffs_verify_cmp(const __u8 *d0, const __u8 *d1,
-+			       const yaffs_spare *s0, const yaffs_spare *s1)
- {
- 
- 	if (memcmp(d0, d1, YAFFS_BYTES_PER_CHUNK) != 0 ||
--	    s0->tagByte0 != s1->tagByte0 ||
--	    s0->tagByte1 != s1->tagByte1 ||
--	    s0->tagByte2 != s1->tagByte2 ||
--	    s0->tagByte3 != s1->tagByte3 ||
--	    s0->tagByte4 != s1->tagByte4 ||
--	    s0->tagByte5 != s1->tagByte5 ||
--	    s0->tagByte6 != s1->tagByte6 ||
--	    s0->tagByte7 != s1->tagByte7 ||
-+	    s0->tb0 != s1->tb0 ||
-+	    s0->tb1 != s1->tb1 ||
-+	    s0->tb2 != s1->tb2 ||
-+	    s0->tb3 != s1->tb3 ||
-+	    s0->tb4 != s1->tb4 ||
-+	    s0->tb5 != s1->tb5 ||
-+	    s0->tb6 != s1->tb6 ||
-+	    s0->tb7 != s1->tb7 ||
- 	    s0->ecc1[0] != s1->ecc1[0] ||
- 	    s0->ecc1[1] != s1->ecc1[1] ||
- 	    s0->ecc1[2] != s1->ecc1[2] ||
-@@ -398,53 +396,53 @@ static int yaffs_VerifyCompare(const __u
- }
- #endif				/* NOTYET */
- 
--int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
--						int chunkInNAND,
-+int yaffs_tags_compat_wr(yaffs_dev_t *dev,
-+						int nand_chunk,
- 						const __u8 *data,
--						const yaffs_ExtendedTags *eTags)
-+						const yaffs_ext_tags *eTags)
- {
--	yaffs_Spare spare;
--	yaffs_Tags tags;
-+	yaffs_spare spare;
-+	yaffs_tags_t tags;
- 
--	yaffs_SpareInitialise(&spare);
-+	yaffs_spare_init(&spare);
- 
--	if (eTags->chunkDeleted)
--		spare.pageStatus = 0;
-+	if (eTags->is_deleted)
-+		spare.page_status = 0;
- 	else {
--		tags.objectId = eTags->objectId;
--		tags.chunkId = eTags->chunkId;
-+		tags.obj_id = eTags->obj_id;
-+		tags.chunk_id = eTags->chunk_id;
- 
--		tags.byteCountLSB = eTags->byteCount & 0x3ff;
-+		tags.n_bytes_lsb = eTags->n_bytes & 0x3ff;
- 
--		if (dev->nDataBytesPerChunk >= 1024)
--			tags.byteCountMSB = (eTags->byteCount >> 10) & 3;
-+		if (dev->data_bytes_per_chunk >= 1024)
-+			tags.n_bytes_msb = (eTags->n_bytes >> 10) & 3;
- 		else
--			tags.byteCountMSB = 3;
-+			tags.n_bytes_msb = 3;
- 
- 
--		tags.serialNumber = eTags->serialNumber;
-+		tags.serial_number = eTags->serial_number;
- 
--		if (!dev->useNANDECC && data)
--			yaffs_CalcECC(data, &spare);
-+		if (!dev->param.use_nand_ecc && data)
-+			yaffs_calc_ecc(data, &spare);
- 
--		yaffs_LoadTagsIntoSpare(&spare, &tags);
-+		yaffs_load_tags_to_spare(&spare, &tags);
- 
- 	}
- 
--	return yaffs_WriteChunkToNAND(dev, chunkInNAND, data, &spare);
-+	return yaffs_wr_nand(dev, nand_chunk, data, &spare);
- }
- 
--int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,
--						     int chunkInNAND,
-+int yaffs_tags_compat_rd(yaffs_dev_t *dev,
-+						     int nand_chunk,
- 						     __u8 *data,
--						     yaffs_ExtendedTags *eTags)
-+						     yaffs_ext_tags *eTags)
- {
- 
--	yaffs_Spare spare;
--	yaffs_Tags tags;
--	yaffs_ECCResult eccResult = YAFFS_ECC_RESULT_UNKNOWN;
-+	yaffs_spare spare;
-+	yaffs_tags_t tags;
-+	yaffs_ecc_result ecc_result = YAFFS_ECC_RESULT_UNKNOWN;
- 
--	static yaffs_Spare spareFF;
-+	static yaffs_spare spareFF;
- 	static int init;
- 
- 	if (!init) {
-@@ -452,33 +450,33 @@ int yaffs_TagsCompatabilityReadChunkWith
- 		init = 1;
- 	}
- 
--	if (yaffs_ReadChunkFromNAND
--	    (dev, chunkInNAND, data, &spare, &eccResult, 1)) {
-+	if (yaffs_rd_chunk_nand
-+	    (dev, nand_chunk, data, &spare, &ecc_result, 1)) {
- 		/* eTags may be NULL */
- 		if (eTags) {
- 
- 			int deleted =
--			    (yaffs_CountBits(spare.pageStatus) < 7) ? 1 : 0;
-+			    (yaffs_count_bits(spare.page_status) < 7) ? 1 : 0;
- 
--			eTags->chunkDeleted = deleted;
--			eTags->eccResult = eccResult;
--			eTags->blockBad = 0;	/* We're reading it */
-+			eTags->is_deleted = deleted;
-+			eTags->ecc_result = ecc_result;
-+			eTags->block_bad = 0;	/* We're reading it */
- 			/* therefore it is not a bad block */
--			eTags->chunkUsed =
-+			eTags->chunk_used =
- 			    (memcmp(&spareFF, &spare, sizeof(spareFF)) !=
- 			     0) ? 1 : 0;
- 
--			if (eTags->chunkUsed) {
--				yaffs_GetTagsFromSpare(dev, &spare, &tags);
-+			if (eTags->chunk_used) {
-+				yaffs_get_tags_from_spare(dev, &spare, &tags);
- 
--				eTags->objectId = tags.objectId;
--				eTags->chunkId = tags.chunkId;
--				eTags->byteCount = tags.byteCountLSB;
-+				eTags->obj_id = tags.obj_id;
-+				eTags->chunk_id = tags.chunk_id;
-+				eTags->n_bytes = tags.n_bytes_lsb;
- 
--				if (dev->nDataBytesPerChunk >= 1024)
--					eTags->byteCount |= (((unsigned) tags.byteCountMSB) << 10);
-+				if (dev->data_bytes_per_chunk >= 1024)
-+					eTags->n_bytes |= (((unsigned) tags.n_bytes_msb) << 10);
- 
--				eTags->serialNumber = tags.serialNumber;
-+				eTags->serial_number = tags.serial_number;
- 			}
- 		}
- 
-@@ -488,49 +486,49 @@ int yaffs_TagsCompatabilityReadChunkWith
- 	}
- }
- 
--int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
--					    int blockInNAND)
-+int yaffs_tags_compat_mark_bad(struct yaffs_dev_s *dev,
-+					    int flash_block)
- {
- 
--	yaffs_Spare spare;
-+	yaffs_spare spare;
- 
--	memset(&spare, 0xff, sizeof(yaffs_Spare));
-+	memset(&spare, 0xff, sizeof(yaffs_spare));
- 
--	spare.blockStatus = 'Y';
-+	spare.block_status = 'Y';
- 
--	yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock, NULL,
-+	yaffs_wr_nand(dev, flash_block * dev->param.chunks_per_block, NULL,
- 			       &spare);
--	yaffs_WriteChunkToNAND(dev, blockInNAND * dev->nChunksPerBlock + 1,
-+	yaffs_wr_nand(dev, flash_block * dev->param.chunks_per_block + 1,
- 			       NULL, &spare);
- 
- 	return YAFFS_OK;
- 
- }
- 
--int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
--					  int blockNo,
--					  yaffs_BlockState *state,
--					  __u32 *sequenceNumber)
-+int yaffs_tags_compat_query_block(struct yaffs_dev_s *dev,
-+					  int block_no,
-+					  yaffs_block_state_t *state,
-+					  __u32 *seq_number)
- {
- 
--	yaffs_Spare spare0, spare1;
--	static yaffs_Spare spareFF;
-+	yaffs_spare spare0, spare1;
-+	static yaffs_spare spareFF;
- 	static int init;
--	yaffs_ECCResult dummy;
-+	yaffs_ecc_result dummy;
- 
- 	if (!init) {
- 		memset(&spareFF, 0xFF, sizeof(spareFF));
- 		init = 1;
- 	}
- 
--	*sequenceNumber = 0;
-+	*seq_number = 0;
- 
--	yaffs_ReadChunkFromNAND(dev, blockNo * dev->nChunksPerBlock, NULL,
-+	yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block, NULL,
- 				&spare0, &dummy, 1);
--	yaffs_ReadChunkFromNAND(dev, blockNo * dev->nChunksPerBlock + 1, NULL,
-+	yaffs_rd_chunk_nand(dev, block_no * dev->param.chunks_per_block + 1, NULL,
- 				&spare1, &dummy, 1);
- 
--	if (yaffs_CountBits(spare0.blockStatus & spare1.blockStatus) < 7)
-+	if (yaffs_count_bits(spare0.block_status & spare1.block_status) < 7)
- 		*state = YAFFS_BLOCK_STATE_DEAD;
- 	else if (memcmp(&spareFF, &spare0, sizeof(spareFF)) == 0)
- 		*state = YAFFS_BLOCK_STATE_EMPTY;
---- a/fs/yaffs2/yaffs_tagscompat.h
-+++ b/fs/yaffs2/yaffs_tagscompat.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -17,23 +17,23 @@
- #define __YAFFS_TAGSCOMPAT_H__
- 
- #include "yaffs_guts.h"
--int yaffs_TagsCompatabilityWriteChunkWithTagsToNAND(yaffs_Device *dev,
--						int chunkInNAND,
-+int yaffs_tags_compat_wr(yaffs_dev_t *dev,
-+						int nand_chunk,
- 						const __u8 *data,
--						const yaffs_ExtendedTags *tags);
--int yaffs_TagsCompatabilityReadChunkWithTagsFromNAND(yaffs_Device *dev,
--						int chunkInNAND,
-+						const yaffs_ext_tags *tags);
-+int yaffs_tags_compat_rd(yaffs_dev_t *dev,
-+						int nand_chunk,
- 						__u8 *data,
--						yaffs_ExtendedTags *tags);
--int yaffs_TagsCompatabilityMarkNANDBlockBad(struct yaffs_DeviceStruct *dev,
--					    int blockNo);
--int yaffs_TagsCompatabilityQueryNANDBlock(struct yaffs_DeviceStruct *dev,
--					  int blockNo,
--					  yaffs_BlockState *state,
--					  __u32 *sequenceNumber);
-+						yaffs_ext_tags *tags);
-+int yaffs_tags_compat_mark_bad(struct yaffs_dev_s *dev,
-+					    int block_no);
-+int yaffs_tags_compat_query_block(struct yaffs_dev_s *dev,
-+					  int block_no,
-+					  yaffs_block_state_t *state,
-+					  __u32 *seq_number);
- 
--void yaffs_CalcTagsECC(yaffs_Tags *tags);
--int yaffs_CheckECCOnTags(yaffs_Tags *tags);
--int yaffs_CountBits(__u8 byte);
-+void yaffs_calc_tags_ecc(yaffs_tags_t *tags);
-+int yaffs_check_tags_ecc(yaffs_tags_t *tags);
-+int yaffs_count_bits(__u8 byte);
- 
- #endif
---- a/fs/yaffs2/yaffs_tagsvalidity.c
-+++ b/fs/yaffs2/yaffs_tagsvalidity.c
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -13,16 +13,16 @@
- 
- #include "yaffs_tagsvalidity.h"
- 
--void yaffs_InitialiseTags(yaffs_ExtendedTags *tags)
-+void yaffs_init_tags(yaffs_ext_tags *tags)
- {
--	memset(tags, 0, sizeof(yaffs_ExtendedTags));
--	tags->validMarker0 = 0xAAAAAAAA;
--	tags->validMarker1 = 0x55555555;
-+	memset(tags, 0, sizeof(yaffs_ext_tags));
-+	tags->validity1 = 0xAAAAAAAA;
-+	tags->validty1 = 0x55555555;
- }
- 
--int yaffs_ValidateTags(yaffs_ExtendedTags *tags)
-+int yaffs_validate_tags(yaffs_ext_tags *tags)
- {
--	return (tags->validMarker0 == 0xAAAAAAAA &&
--		tags->validMarker1 == 0x55555555);
-+	return (tags->validity1 == 0xAAAAAAAA &&
-+		tags->validty1 == 0x55555555);
- 
- }
---- a/fs/yaffs2/yaffs_tagsvalidity.h
-+++ b/fs/yaffs2/yaffs_tagsvalidity.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -19,6 +19,6 @@
- 
- #include "yaffs_guts.h"
- 
--void yaffs_InitialiseTags(yaffs_ExtendedTags *tags);
--int yaffs_ValidateTags(yaffs_ExtendedTags *tags);
-+void yaffs_init_tags(yaffs_ext_tags *tags);
-+int yaffs_validate_tags(yaffs_ext_tags *tags);
- #endif
---- /dev/null
-+++ b/fs/yaffs2/yaffs_trace.h
-@@ -0,0 +1,60 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+
-+#ifndef __YTRACE_H__
-+#define __YTRACE_H__
-+
-+extern unsigned int yaffs_trace_mask;
-+extern unsigned int yaffs_wr_attempts;
-+
-+/*
-+ * Tracing flags.
-+ * The flags masked in YAFFS_TRACE_ALWAYS are always traced.
-+ */
-+
-+#define YAFFS_TRACE_OS			0x00000002
-+#define YAFFS_TRACE_ALLOCATE		0x00000004
-+#define YAFFS_TRACE_SCAN		0x00000008
-+#define YAFFS_TRACE_BAD_BLOCKS		0x00000010
-+#define YAFFS_TRACE_ERASE		0x00000020
-+#define YAFFS_TRACE_GC			0x00000040
-+#define YAFFS_TRACE_WRITE		0x00000080
-+#define YAFFS_TRACE_TRACING		0x00000100
-+#define YAFFS_TRACE_DELETION		0x00000200
-+#define YAFFS_TRACE_BUFFERS		0x00000400
-+#define YAFFS_TRACE_NANDACCESS		0x00000800
-+#define YAFFS_TRACE_GC_DETAIL		0x00001000
-+#define YAFFS_TRACE_SCAN_DEBUG		0x00002000
-+#define YAFFS_TRACE_MTD			0x00004000
-+#define YAFFS_TRACE_CHECKPOINT		0x00008000
-+
-+#define YAFFS_TRACE_VERIFY		0x00010000
-+#define YAFFS_TRACE_VERIFY_NAND		0x00020000
-+#define YAFFS_TRACE_VERIFY_FULL		0x00040000
-+#define YAFFS_TRACE_VERIFY_ALL		0x000F0000
-+
-+#define YAFFS_TRACE_SYNC		0x00100000
-+#define YAFFS_TRACE_BACKGROUND		0x00200000
-+#define YAFFS_TRACE_LOCK		0x00400000
-+
-+#define YAFFS_TRACE_ERROR		0x40000000
-+#define YAFFS_TRACE_BUG			0x80000000
-+#define YAFFS_TRACE_ALWAYS		0xF0000000
-+
-+
-+#define T(mask, p) do { if ((mask) & (yaffs_trace_mask | YAFFS_TRACE_ALWAYS)) TOUT(p); } while (0)
-+
-+#endif
---- /dev/null
-+++ b/fs/yaffs2/yaffs_verify.c
-@@ -0,0 +1,626 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+
-+#include "yaffs_verify.h"
-+#include "yaffs_trace.h"
-+#include "yaffs_bitmap.h"
-+#include "yaffs_getblockinfo.h"
-+#include "yaffs_nand.h"
-+
-+int yaffs_skip_verification(yaffs_dev_t *dev)
-+{
-+	dev=dev;
-+	return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY | YAFFS_TRACE_VERIFY_FULL));
-+}
-+
-+static int yaffs_skip_full_verification(yaffs_dev_t *dev)
-+{
-+	dev=dev;
-+	return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_FULL));
-+}
-+
-+static int yaffs_skip_nand_verification(yaffs_dev_t *dev)
-+{
-+	dev=dev;
-+	return !(yaffs_trace_mask & (YAFFS_TRACE_VERIFY_NAND));
-+}
-+
-+
-+static const char *block_stateName[] = {
-+"Unknown",
-+"Needs scanning",
-+"Scanning",
-+"Empty",
-+"Allocating",
-+"Full",
-+"Dirty",
-+"Checkpoint",
-+"Collecting",
-+"Dead"
-+};
-+
-+
-+void yaffs_verify_blk(yaffs_dev_t *dev, yaffs_block_info_t *bi, int n)
-+{
-+	int actuallyUsed;
-+	int inUse;
-+
-+	if (yaffs_skip_verification(dev))
-+		return;
-+
-+	/* Report illegal runtime states */
-+	if (bi->block_state >= YAFFS_NUMBER_OF_BLOCK_STATES)
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has undefined state %d"TENDSTR), n, bi->block_state));
-+
-+	switch (bi->block_state) {
-+	case YAFFS_BLOCK_STATE_UNKNOWN:
-+	case YAFFS_BLOCK_STATE_SCANNING:
-+	case YAFFS_BLOCK_STATE_NEEDS_SCANNING:
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has bad run-state %s"TENDSTR),
-+		n, block_stateName[bi->block_state]));
-+	}
-+
-+	/* Check pages in use and soft deletions are legal */
-+
-+	actuallyUsed = bi->pages_in_use - bi->soft_del_pages;
-+
-+	if (bi->pages_in_use < 0 || bi->pages_in_use > dev->param.chunks_per_block ||
-+	   bi->soft_del_pages < 0 || bi->soft_del_pages > dev->param.chunks_per_block ||
-+	   actuallyUsed < 0 || actuallyUsed > dev->param.chunks_per_block)
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has illegal values pages_in_used %d soft_del_pages %d"TENDSTR),
-+		n, bi->pages_in_use, bi->soft_del_pages));
-+
-+
-+	/* Check chunk bitmap legal */
-+	inUse = yaffs_count_chunk_bits(dev, n);
-+	if (inUse != bi->pages_in_use)
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Block %d has inconsistent values pages_in_use %d counted chunk bits %d"TENDSTR),
-+			n, bi->pages_in_use, inUse));
-+
-+}
-+
-+
-+
-+void yaffs_verify_collected_blk(yaffs_dev_t *dev, yaffs_block_info_t *bi, int n)
-+{
-+	yaffs_verify_blk(dev, bi, n);
-+
-+	/* After collection the block should be in the erased state */
-+
-+	if (bi->block_state != YAFFS_BLOCK_STATE_COLLECTING &&
-+			bi->block_state != YAFFS_BLOCK_STATE_EMPTY) {
-+		T(YAFFS_TRACE_ERROR, (TSTR("Block %d is in state %d after gc, should be erased"TENDSTR),
-+			n, bi->block_state));
-+	}
-+}
-+
-+void yaffs_verify_blocks(yaffs_dev_t *dev)
-+{
-+	int i;
-+	int nBlocksPerState[YAFFS_NUMBER_OF_BLOCK_STATES];
-+	int nIllegalBlockStates = 0;
-+
-+	if (yaffs_skip_verification(dev))
-+		return;
-+
-+	memset(nBlocksPerState, 0, sizeof(nBlocksPerState));
-+
-+	for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
-+		yaffs_block_info_t *bi = yaffs_get_block_info(dev, i);
-+		yaffs_verify_blk(dev, bi, i);
-+
-+		if (bi->block_state < YAFFS_NUMBER_OF_BLOCK_STATES)
-+			nBlocksPerState[bi->block_state]++;
-+		else
-+			nIllegalBlockStates++;
-+	}
-+
-+	T(YAFFS_TRACE_VERIFY, (TSTR(""TENDSTR)));
-+	T(YAFFS_TRACE_VERIFY, (TSTR("Block summary"TENDSTR)));
-+
-+	T(YAFFS_TRACE_VERIFY, (TSTR("%d blocks have illegal states"TENDSTR), nIllegalBlockStates));
-+	if (nBlocksPerState[YAFFS_BLOCK_STATE_ALLOCATING] > 1)
-+		T(YAFFS_TRACE_VERIFY, (TSTR("Too many allocating blocks"TENDSTR)));
-+
-+	for (i = 0; i < YAFFS_NUMBER_OF_BLOCK_STATES; i++)
-+		T(YAFFS_TRACE_VERIFY,
-+		  (TSTR("%s %d blocks"TENDSTR),
-+		  block_stateName[i], nBlocksPerState[i]));
-+
-+	if (dev->blocks_in_checkpt != nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT])
-+		T(YAFFS_TRACE_VERIFY,
-+		 (TSTR("Checkpoint block count wrong dev %d count %d"TENDSTR),
-+		 dev->blocks_in_checkpt, nBlocksPerState[YAFFS_BLOCK_STATE_CHECKPOINT]));
-+
-+	if (dev->n_erased_blocks != nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY])
-+		T(YAFFS_TRACE_VERIFY,
-+		 (TSTR("Erased block count wrong dev %d count %d"TENDSTR),
-+		 dev->n_erased_blocks, nBlocksPerState[YAFFS_BLOCK_STATE_EMPTY]));
-+
-+	if (nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING] > 1)
-+		T(YAFFS_TRACE_VERIFY,
-+		 (TSTR("Too many collecting blocks %d (max is 1)"TENDSTR),
-+		 nBlocksPerState[YAFFS_BLOCK_STATE_COLLECTING]));
-+
-+	T(YAFFS_TRACE_VERIFY, (TSTR(""TENDSTR)));
-+
-+}
-+
-+/*
-+ * Verify the object header. oh must be valid, but obj and tags may be NULL in which
-+ * case those tests will not be performed.
-+ */
-+void yaffs_verify_oh(yaffs_obj_t *obj, yaffs_obj_header *oh, yaffs_ext_tags *tags, int parentCheck)
-+{
-+	if (obj && yaffs_skip_verification(obj->my_dev))
-+		return;
-+
-+	if (!(tags && obj && oh)) {
-+		T(YAFFS_TRACE_VERIFY,
-+				(TSTR("Verifying object header tags %p obj %p oh %p"TENDSTR),
-+				tags, obj, oh));
-+		return;
-+	}
-+
-+	if (oh->type <= YAFFS_OBJECT_TYPE_UNKNOWN ||
-+			oh->type > YAFFS_OBJECT_TYPE_MAX)
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header type is illegal value 0x%x"TENDSTR),
-+			tags->obj_id, oh->type));
-+
-+	if (tags->obj_id != obj->obj_id)
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header mismatch obj_id %d"TENDSTR),
-+			tags->obj_id, obj->obj_id));
-+
-+
-+	/*
-+	 * Check that the object's parent ids match if parentCheck requested.
-+	 *
-+	 * Tests do not apply to the root object.
-+	 */
-+
-+	if (parentCheck && tags->obj_id > 1 && !obj->parent)
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header mismatch parent_id %d obj->parent is NULL"TENDSTR),
-+			tags->obj_id, oh->parent_obj_id));
-+
-+	if (parentCheck && obj->parent &&
-+			oh->parent_obj_id != obj->parent->obj_id &&
-+			(oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED ||
-+			obj->parent->obj_id != YAFFS_OBJECTID_DELETED))
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header mismatch parent_id %d parent_obj_id %d"TENDSTR),
-+			tags->obj_id, oh->parent_obj_id, obj->parent->obj_id));
-+
-+	if (tags->obj_id > 1 && oh->name[0] == 0) /* Null name */
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header name is NULL"TENDSTR),
-+			obj->obj_id));
-+
-+	if (tags->obj_id > 1 && ((__u8)(oh->name[0])) == 0xff) /* Trashed name */
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d header name is 0xFF"TENDSTR),
-+			obj->obj_id));
-+}
-+
-+
-+#if 0
-+/* Not being used, but don't want to throw away yet */
-+int yaffs_verify_tnode_worker(yaffs_obj_t *obj, yaffs_tnode_t *tn,
-+					__u32 level, int chunk_offset)
-+{
-+	int i;
-+	yaffs_dev_t *dev = obj->my_dev;
-+	int ok = 1;
-+
-+	if (tn) {
-+		if (level > 0) {
-+
-+			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
-+				if (tn->internal[i]) {
-+					ok = yaffs_verify_tnode_worker(obj,
-+							tn->internal[i],
-+							level - 1,
-+							(chunk_offset<<YAFFS_TNODES_INTERNAL_BITS) + i);
-+				}
-+			}
-+		} else if (level == 0) {
-+			yaffs_ext_tags tags;
-+			__u32 obj_id = obj->obj_id;
-+
-+			chunk_offset <<=  YAFFS_TNODES_LEVEL0_BITS;
-+
-+			for (i = 0; i < YAFFS_NTNODES_LEVEL0; i++) {
-+				__u32 theChunk = yaffs_get_group_base(dev, tn, i);
-+
-+				if (theChunk > 0) {
-+					/* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),tags.obj_id,tags.chunk_id,theChunk)); */
-+					yaffs_rd_chunk_tags_nand(dev, theChunk, NULL, &tags);
-+					if (tags.obj_id != obj_id || tags.chunk_id != chunk_offset) {
-+						T(~0, (TSTR("Object %d chunk_id %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
-+							obj_id, chunk_offset, theChunk,
-+							tags.obj_id, tags.chunk_id));
-+					}
-+				}
-+				chunk_offset++;
-+			}
-+		}
-+	}
-+
-+	return ok;
-+
-+}
-+
-+#endif
-+
-+void yaffs_verify_file(yaffs_obj_t *obj)
-+{
-+	int requiredTallness;
-+	int actualTallness;
-+	__u32 lastChunk;
-+	__u32 x;
-+	__u32 i;
-+	yaffs_dev_t *dev;
-+	yaffs_ext_tags tags;
-+	yaffs_tnode_t *tn;
-+	__u32 obj_id;
-+
-+	if (!obj)
-+		return;
-+
-+	if (yaffs_skip_verification(obj->my_dev))
-+		return;
-+
-+	dev = obj->my_dev;
-+	obj_id = obj->obj_id;
-+
-+	/* Check file size is consistent with tnode depth */
-+	lastChunk =  obj->variant.file_variant.file_size / dev->data_bytes_per_chunk + 1;
-+	x = lastChunk >> YAFFS_TNODES_LEVEL0_BITS;
-+	requiredTallness = 0;
-+	while (x > 0) {
-+		x >>= YAFFS_TNODES_INTERNAL_BITS;
-+		requiredTallness++;
-+	}
-+
-+	actualTallness = obj->variant.file_variant.top_level;
-+
-+	/* Check that the chunks in the tnode tree are all correct.
-+	 * We do this by scanning through the tnode tree and
-+	 * checking the tags for every chunk match.
-+	 */
-+
-+	if (yaffs_skip_nand_verification(dev))
-+		return;
-+
-+	for (i = 1; i <= lastChunk; i++) {
-+		tn = yaffs_find_tnode_0(dev, &obj->variant.file_variant, i);
-+
-+		if (tn) {
-+			__u32 theChunk = yaffs_get_group_base(dev, tn, i);
-+			if (theChunk > 0) {
-+				/* T(~0,(TSTR("verifying (%d:%d) %d"TENDSTR),obj_id,i,theChunk)); */
-+				yaffs_rd_chunk_tags_nand(dev, theChunk, NULL, &tags);
-+				if (tags.obj_id != obj_id || tags.chunk_id != i) {
-+					T(~0, (TSTR("Object %d chunk_id %d NAND mismatch chunk %d tags (%d:%d)"TENDSTR),
-+						obj_id, i, theChunk,
-+						tags.obj_id, tags.chunk_id));
-+				}
-+			}
-+		}
-+	}
-+}
-+
-+
-+void yaffs_verify_link(yaffs_obj_t *obj)
-+{
-+	if (obj && yaffs_skip_verification(obj->my_dev))
-+		return;
-+
-+	/* Verify sane equivalent object */
-+}
-+
-+void yaffs_verify_symlink(yaffs_obj_t *obj)
-+{
-+	if (obj && yaffs_skip_verification(obj->my_dev))
-+		return;
-+
-+	/* Verify symlink string */
-+}
-+
-+void yaffs_verify_special(yaffs_obj_t *obj)
-+{
-+	if (obj && yaffs_skip_verification(obj->my_dev))
-+		return;
-+}
-+
-+void yaffs_verify_obj(yaffs_obj_t *obj)
-+{
-+	yaffs_dev_t *dev;
-+
-+	__u32 chunkMin;
-+	__u32 chunkMax;
-+
-+	__u32 chunk_idOk;
-+	__u32 chunkInRange;
-+	__u32 chunkShouldNotBeDeleted;
-+	__u32 chunkValid;
-+
-+	if (!obj)
-+		return;
-+
-+	if (obj->being_created)
-+		return;
-+
-+	dev = obj->my_dev;
-+
-+	if (yaffs_skip_verification(dev))
-+		return;
-+
-+	/* Check sane object header chunk */
-+
-+	chunkMin = dev->internal_start_block * dev->param.chunks_per_block;
-+	chunkMax = (dev->internal_end_block+1) * dev->param.chunks_per_block - 1;
-+
-+	chunkInRange = (((unsigned)(obj->hdr_chunk)) >= chunkMin && ((unsigned)(obj->hdr_chunk)) <= chunkMax);
-+	chunk_idOk = chunkInRange || (obj->hdr_chunk == 0);
-+	chunkValid = chunkInRange &&
-+			yaffs_check_chunk_bit(dev,
-+					obj->hdr_chunk / dev->param.chunks_per_block,
-+					obj->hdr_chunk % dev->param.chunks_per_block);
-+	chunkShouldNotBeDeleted = chunkInRange && !chunkValid;
-+
-+	if (!obj->fake &&
-+			(!chunk_idOk || chunkShouldNotBeDeleted)) {
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d has chunk_id %d %s %s"TENDSTR),
-+			obj->obj_id, obj->hdr_chunk,
-+			chunk_idOk ? "" : ",out of range",
-+			chunkShouldNotBeDeleted ? ",marked as deleted" : ""));
-+	}
-+
-+	if (chunkValid && !yaffs_skip_nand_verification(dev)) {
-+		yaffs_ext_tags tags;
-+		yaffs_obj_header *oh;
-+		__u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
-+
-+		oh = (yaffs_obj_header *)buffer;
-+
-+		yaffs_rd_chunk_tags_nand(dev, obj->hdr_chunk, buffer,
-+				&tags);
-+
-+		yaffs_verify_oh(obj, oh, &tags, 1);
-+
-+		yaffs_release_temp_buffer(dev, buffer, __LINE__);
-+	}
-+
-+	/* Verify it has a parent */
-+	if (obj && !obj->fake &&
-+			(!obj->parent || obj->parent->my_dev != dev)) {
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d has parent pointer %p which does not look like an object"TENDSTR),
-+			obj->obj_id, obj->parent));
-+	}
-+
-+	/* Verify parent is a directory */
-+	if (obj->parent && obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+		T(YAFFS_TRACE_VERIFY,
-+			(TSTR("Obj %d's parent is not a directory (type %d)"TENDSTR),
-+			obj->obj_id, obj->parent->variant_type));
-+	}
-+
-+	switch (obj->variant_type) {
-+	case YAFFS_OBJECT_TYPE_FILE:
-+		yaffs_verify_file(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_SYMLINK:
-+		yaffs_verify_symlink(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_DIRECTORY:
-+		yaffs_verify_dir(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_HARDLINK:
-+		yaffs_verify_link(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_SPECIAL:
-+		yaffs_verify_special(obj);
-+		break;
-+	case YAFFS_OBJECT_TYPE_UNKNOWN:
-+	default:
-+		T(YAFFS_TRACE_VERIFY,
-+		(TSTR("Obj %d has illegaltype %d"TENDSTR),
-+		obj->obj_id, obj->variant_type));
-+		break;
-+	}
-+}
-+
-+void yaffs_verify_objects(yaffs_dev_t *dev)
-+{
-+	yaffs_obj_t *obj;
-+	int i;
-+	struct ylist_head *lh;
-+
-+	if (yaffs_skip_verification(dev))
-+		return;
-+
-+	/* Iterate through the objects in each hash entry */
-+
-+	for (i = 0; i <  YAFFS_NOBJECT_BUCKETS; i++) {
-+		ylist_for_each(lh, &dev->obj_bucket[i].list) {
-+			if (lh) {
-+				obj = ylist_entry(lh, yaffs_obj_t, hash_link);
-+				yaffs_verify_obj(obj);
-+			}
-+		}
-+	}
-+}
-+
-+
-+void yaffs_verify_obj_in_dir(yaffs_obj_t *obj)
-+{
-+	struct ylist_head *lh;
-+	yaffs_obj_t *listObj;
-+
-+	int count = 0;
-+
-+	if (!obj) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("No object to verify" TENDSTR)));
-+		YBUG();
-+		return;
-+	}
-+
-+	if (yaffs_skip_verification(obj->my_dev))
-+		return;
-+
-+	if (!obj->parent) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("Object does not have parent" TENDSTR)));
-+		YBUG();
-+		return;
-+	}
-+
-+	if (obj->parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("Parent is not directory" TENDSTR)));
-+		YBUG();
-+	}
-+
-+	/* Iterate through the objects in each hash entry */
-+
-+	ylist_for_each(lh, &obj->parent->variant.dir_variant.children) {
-+		if (lh) {
-+			listObj = ylist_entry(lh, yaffs_obj_t, siblings);
-+			yaffs_verify_obj(listObj);
-+			if (obj == listObj)
-+				count++;
-+		}
-+	 }
-+
-+	if (count != 1) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("Object in directory %d times" TENDSTR), count));
-+		YBUG();
-+	}
-+}
-+
-+void yaffs_verify_dir(yaffs_obj_t *directory)
-+{
-+	struct ylist_head *lh;
-+	yaffs_obj_t *listObj;
-+
-+	if (!directory) {
-+		YBUG();
-+		return;
-+	}
-+
-+	if (yaffs_skip_full_verification(directory->my_dev))
-+		return;
-+
-+	if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+		T(YAFFS_TRACE_ALWAYS, (TSTR("Directory has wrong type: %d" TENDSTR), directory->variant_type));
-+		YBUG();
-+	}
-+
-+	/* Iterate through the objects in each hash entry */
-+
-+	ylist_for_each(lh, &directory->variant.dir_variant.children) {
-+		if (lh) {
-+			listObj = ylist_entry(lh, yaffs_obj_t, siblings);
-+			if (listObj->parent != directory) {
-+				T(YAFFS_TRACE_ALWAYS, (TSTR("Object in directory list has wrong parent %p" TENDSTR), listObj->parent));
-+				YBUG();
-+			}
-+			yaffs_verify_obj_in_dir(listObj);
-+		}
-+	}
-+}
-+
-+static int yaffs_free_verification_failures;
-+
-+void yaffs_verify_free_chunks(yaffs_dev_t *dev)
-+{
-+	int counted;
-+	int difference;
-+
-+	if (yaffs_skip_verification(dev))
-+		return;
-+
-+	counted = yaffs_count_free_chunks(dev);
-+
-+	difference = dev->n_free_chunks - counted;
-+
-+	if (difference) {
-+		T(YAFFS_TRACE_ALWAYS,
-+		  (TSTR("Freechunks verification failure %d %d %d" TENDSTR),
-+		   dev->n_free_chunks, counted, difference));
-+		yaffs_free_verification_failures++;
-+	}
-+}
-+
-+int yaffs_verify_file_sane(yaffs_obj_t *in)
-+{
-+#if 0
-+	int chunk;
-+	int n_chunks;
-+	int fSize;
-+	int failed = 0;
-+	int obj_id;
-+	yaffs_tnode_t *tn;
-+	yaffs_tags_t localTags;
-+	yaffs_tags_t *tags = &localTags;
-+	int theChunk;
-+	int is_deleted;
-+
-+	if (in->variant_type != YAFFS_OBJECT_TYPE_FILE)
-+		return YAFFS_FAIL;
-+
-+	obj_id = in->obj_id;
-+	fSize = in->variant.file_variant.file_size;
-+	n_chunks =
-+	    (fSize + in->my_dev->data_bytes_per_chunk - 1) / in->my_dev->data_bytes_per_chunk;
-+
-+	for (chunk = 1; chunk <= n_chunks; chunk++) {
-+		tn = yaffs_find_tnode_0(in->my_dev, &in->variant.file_variant,
-+					   chunk);
-+
-+		if (tn) {
-+
-+			theChunk = yaffs_get_group_base(dev, tn, chunk);
-+
-+			if (yaffs_check_chunk_bits
-+			    (dev, theChunk / dev->param.chunks_per_block,
-+			     theChunk % dev->param.chunks_per_block)) {
-+
-+				yaffs_rd_chunk_tags_nand(in->my_dev, theChunk,
-+							    tags,
-+							    &is_deleted);
-+				if (yaffs_tags_match
-+				    (tags, in->obj_id, chunk, is_deleted)) {
-+					/* found it; */
-+
-+				}
-+			} else {
-+
-+				failed = 1;
-+			}
-+
-+		} else {
-+			/* T(("No level 0 found for %d\n", chunk)); */
-+		}
-+	}
-+
-+	return failed ? YAFFS_FAIL : YAFFS_OK;
-+#else
-+	in=in;
-+	return YAFFS_OK;
-+#endif
-+}
---- /dev/null
-+++ b/fs/yaffs2/yaffs_verify.h
-@@ -0,0 +1,39 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#ifndef __YAFFS_VERIFY_H__
-+#define __YAFFS_VERIFY_H__
-+
-+#include "yaffs_guts.h"
-+
-+void yaffs_verify_blk(yaffs_dev_t *dev, yaffs_block_info_t *bi, int n);
-+void yaffs_verify_collected_blk(yaffs_dev_t *dev, yaffs_block_info_t *bi, int n);
-+void yaffs_verify_blocks(yaffs_dev_t *dev);
-+
-+void yaffs_verify_oh(yaffs_obj_t *obj, yaffs_obj_header *oh, yaffs_ext_tags *tags, int parentCheck);
-+void yaffs_verify_file(yaffs_obj_t *obj);
-+void yaffs_verify_link(yaffs_obj_t *obj);
-+void yaffs_verify_symlink(yaffs_obj_t *obj);
-+void yaffs_verify_special(yaffs_obj_t *obj);
-+void yaffs_verify_obj(yaffs_obj_t *obj);
-+void yaffs_verify_objects(yaffs_dev_t *dev);
-+void yaffs_verify_obj_in_dir(yaffs_obj_t *obj);
-+void yaffs_verify_dir(yaffs_obj_t *directory);
-+void yaffs_verify_free_chunks(yaffs_dev_t *dev);
-+
-+int yaffs_verify_file_sane(yaffs_obj_t *obj);
-+
-+int yaffs_skip_verification(yaffs_dev_t *dev);
-+
-+#endif
-+
---- /dev/null
-+++ b/fs/yaffs2/yaffs_vfs_glue.c
-@@ -0,0 +1,3576 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ * Acknowledgements:
-+ * Luc van OostenRyck for numerous patches.
-+ * Nick Bane for numerous patches.
-+ * Nick Bane for 2.5/2.6 integration.
-+ * Andras Toth for mknod rdev issue.
-+ * Michael Fischer for finding the problem with inode inconsistency.
-+ * Some code bodily lifted from JFFS
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+/*
-+ *
-+ * This is the file system front-end to YAFFS that hooks it up to
-+ * the VFS.
-+ *
-+ * Special notes:
-+ * >> 2.4: sb->u.generic_sbp points to the yaffs_dev_t associated with
-+ *         this superblock
-+ * >> 2.6: sb->s_fs_info  points to the yaffs_dev_t associated with this
-+ *         superblock
-+ * >> inode->u.generic_ip points to the associated yaffs_obj_t.
-+ */
-+
-+/*
-+ * There are two variants of the VFS glue code. This variant should compile
-+ * for any version of Linux.
-+ */
-+#include <linux/version.h>
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10))
-+#define YAFFS_COMPILE_BACKGROUND
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6, 23))
-+#define YAFFS_COMPILE_FREEZER
-+#endif
-+#endif
-+
-+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28))
-+#define YAFFS_COMPILE_EXPORTFS
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
-+#define YAFFS_USE_SETATTR_COPY
-+#define YAFFS_USE_TRUNCATE_SETSIZE
-+#endif
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35))
-+#define YAFFS_HAS_EVICT_INODE
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
-+#define YAFFS_NEW_FOLLOW_LINK 1
-+#else
-+#define YAFFS_NEW_FOLLOW_LINK 0
-+#endif
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
-+#include <linux/config.h>
-+#endif
-+
-+#include <linux/kernel.h>
-+#include <linux/module.h>
-+#include <linux/slab.h>
-+#include <linux/init.h>
-+#include <linux/fs.h>
-+#include <linux/proc_fs.h>
-+#include <linux/smp_lock.h>
-+#include <linux/pagemap.h>
-+#include <linux/mtd/mtd.h>
-+#include <linux/interrupt.h>
-+#include <linux/string.h>
-+#include <linux/ctype.h>
-+
-+#if (YAFFS_NEW_FOLLOW_LINK == 1)
-+#include <linux/namei.h>
-+#endif
-+
-+#ifdef YAFFS_COMPILE_EXPORTFS
-+#include <linux/exportfs.h>
-+#endif
-+
-+#ifdef YAFFS_COMPILE_BACKGROUND
-+#include <linux/kthread.h>
-+#include <linux/delay.h>
-+#endif
-+#ifdef YAFFS_COMPILE_FREEZER
-+#include <linux/freezer.h>
-+#endif
-+
-+#include <asm/div64.h>
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+
-+#include <linux/statfs.h>
-+
-+#define UnlockPage(p) unlock_page(p)
-+#define Page_Uptodate(page)	test_bit(PG_uptodate, &(page)->flags)
-+
-+/* FIXME: use sb->s_id instead ? */
-+#define yaffs_devname(sb, buf)	bdevname(sb->s_bdev, buf)
-+
-+#else
-+
-+#include <linux/locks.h>
-+#define	BDEVNAME_SIZE		0
-+#define	yaffs_devname(sb, buf)	kdevname(sb->s_dev)
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
-+/* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */
-+#define __user
-+#endif
-+
-+#endif
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
-+#define YPROC_ROOT  (&proc_root)
-+#else
-+#define YPROC_ROOT  NULL
-+#endif
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26))
-+#define Y_INIT_TIMER(a)	init_timer(a)
-+#else
-+#define Y_INIT_TIMER(a)	init_timer_on_stack(a)
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+#define WRITE_SIZE_STR "writesize"
-+#define WRITE_SIZE(mtd) ((mtd)->writesize)
-+#else
-+#define WRITE_SIZE_STR "oobblock"
-+#define WRITE_SIZE(mtd) ((mtd)->oobblock)
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
-+#define YAFFS_USE_WRITE_BEGIN_END 1
-+#else
-+#define YAFFS_USE_WRITE_BEGIN_END 0
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
-+static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
-+{
-+	uint64_t result = partition_size;
-+	do_div(result, block_size);
-+	return (uint32_t)result;
-+}
-+#else
-+#define YCALCBLOCKS(s, b) ((s)/(b))
-+#endif
-+
-+#include <linux/uaccess.h>
-+#include <linux/mtd/mtd.h>
-+
-+#include "yportenv.h"
-+#include "yaffs_trace.h"
-+#include "yaffs_guts.h"
-+
-+#include "yaffs_linux.h"
-+
-+#include "yaffs_mtdif.h"
-+#include "yaffs_mtdif1.h"
-+#include "yaffs_mtdif2.h"
-+
-+unsigned int yaffs_trace_mask = YAFFS_TRACE_BAD_BLOCKS | YAFFS_TRACE_ALWAYS;
-+unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
-+unsigned int yaffs_auto_checkpoint = 1;
-+unsigned int yaffs_gc_control = 1;
-+unsigned int yaffs_bg_enable = 1;
-+
-+/* Module Parameters */
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+module_param(yaffs_trace_mask, uint, 0644);
-+module_param(yaffs_wr_attempts, uint, 0644);
-+module_param(yaffs_auto_checkpoint, uint, 0644);
-+module_param(yaffs_gc_control, uint, 0644);
-+module_param(yaffs_bg_enable, uint, 0644);
-+#else
-+MODULE_PARM(yaffs_trace_mask, "i");
-+MODULE_PARM(yaffs_wr_attempts, "i");
-+MODULE_PARM(yaffs_auto_checkpoint, "i");
-+MODULE_PARM(yaffs_gc_control, "i");
-+#endif
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
-+/* use iget and read_inode */
-+#define Y_IGET(sb, inum) iget((sb), (inum))
-+static void yaffs_read_inode(struct inode *inode);
-+
-+#else
-+/* Call local equivalent */
-+#define YAFFS_USE_OWN_IGET
-+#define Y_IGET(sb, inum) yaffs_iget((sb), (inum))
-+
-+static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino);
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
-+#define yaffs_InodeToObjectLV(iptr) ((iptr)->i_private)
-+#else
-+#define yaffs_InodeToObjectLV(iptr) ((iptr)->u.generic_ip)
-+#endif
-+
-+#define yaffs_InodeToObject(iptr) ((yaffs_obj_t *)(yaffs_InodeToObjectLV(iptr)))
-+#define yaffs_dentry_to_obj(dptr) yaffs_InodeToObject((dptr)->d_inode)
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+#define yaffs_SuperToDevice(sb)	((yaffs_dev_t *)sb->s_fs_info)
-+#else
-+#define yaffs_SuperToDevice(sb)	((yaffs_dev_t *)sb->u.generic_sbp)
-+#endif
-+
-+
-+#define update_dir_time(dir) do {\
-+			(dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
-+		} while(0)
-+		
-+static void yaffs_put_super(struct super_block *sb);
-+
-+static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
-+				loff_t *pos);
-+static ssize_t yaffs_hold_space(struct file *f);
-+static void yaffs_release_space(struct file *f);
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static int yaffs_file_flush(struct file *file, fl_owner_t id);
-+#else
-+static int yaffs_file_flush(struct file *file);
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34))
-+static int yaffs_sync_object(struct file *file, int datasync);
-+#else
-+static int yaffs_sync_object(struct file *file, struct dentry *dentry,
-+				int datasync);
-+#endif
-+
-+static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir);
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
-+			struct nameidata *n);
-+static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
-+					struct nameidata *n);
-+#else
-+static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode);
-+static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry);
-+#endif
-+static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
-+			struct dentry *dentry);
-+static int yaffs_unlink(struct inode *dir, struct dentry *dentry);
-+static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
-+			const char *symname);
-+static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
-+			dev_t dev);
-+#else
-+static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
-+			int dev);
-+#endif
-+static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
-+			struct inode *new_dir, struct dentry *new_dentry);
-+static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static int yaffs_sync_fs(struct super_block *sb, int wait);
-+static void yaffs_write_super(struct super_block *sb);
-+#else
-+static int yaffs_sync_fs(struct super_block *sb);
-+static int yaffs_write_super(struct super_block *sb);
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf);
-+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
-+#else
-+static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
-+#endif
-+
-+#ifdef YAFFS_HAS_PUT_INODE
-+static void yaffs_put_inode(struct inode *inode);
-+#endif
-+
-+#ifdef YAFFS_HAS_EVICT_INODE
-+static void yaffs_evict_inode(struct inode *);
-+#else
-+static void yaffs_delete_inode(struct inode *);
-+static void yaffs_clear_inode(struct inode *);
-+#endif
-+
-+static int yaffs_readpage(struct file *file, struct page *page);
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_writepage(struct page *page, struct writeback_control *wbc);
-+#else
-+static int yaffs_writepage(struct page *page);
-+#endif
-+
-+#ifdef CONFIG_YAFFS_XATTR
-+int yaffs_setxattr(struct dentry *dentry, const char *name,
-+			const void *value, size_t size, int flags);
-+ssize_t yaffs_getxattr(struct dentry *dentry, const char *name, void *buff,
-+			size_t size);
-+int yaffs_removexattr(struct dentry *dentry, const char *name);
-+ssize_t yaffs_listxattr(struct dentry *dentry, char *buff, size_t size);
-+#endif
-+
-+
-+#if (YAFFS_USE_WRITE_BEGIN_END != 0)
-+static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
-+				loff_t pos, unsigned len, unsigned flags,
-+				struct page **pagep, void **fsdata);
-+static int yaffs_write_end(struct file *filp, struct address_space *mapping,
-+				loff_t pos, unsigned len, unsigned copied,
-+				struct page *pg, void *fsdadata);
-+#else
-+static int yaffs_prepare_write(struct file *f, struct page *pg,
-+				unsigned offset, unsigned to);
-+static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
-+				unsigned to);
-+
-+#endif
-+
-+static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
-+				int buflen);
-+#if (YAFFS_NEW_FOLLOW_LINK == 1)
-+void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias);
-+static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
-+#else
-+static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
-+#endif
-+
-+static void yaffs_touch_super(yaffs_dev_t *dev);
-+
-+static loff_t yaffs_dir_llseek(struct file *file, loff_t offset, int origin);
-+
-+static int yaffs_vfs_setattr(struct inode *, struct iattr *);
-+
-+
-+static struct address_space_operations yaffs_file_address_operations = {
-+	.readpage = yaffs_readpage,
-+	.writepage = yaffs_writepage,
-+#if (YAFFS_USE_WRITE_BEGIN_END > 0)
-+	.write_begin = yaffs_write_begin,
-+	.write_end = yaffs_write_end,
-+#else
-+	.prepare_write = yaffs_prepare_write,
-+	.commit_write = yaffs_commit_write,
-+#endif
-+};
-+
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
-+static const struct file_operations yaffs_file_operations = {
-+	.read = do_sync_read,
-+	.write = do_sync_write,
-+	.aio_read = generic_file_aio_read,
-+	.aio_write = generic_file_aio_write,
-+	.mmap = generic_file_mmap,
-+	.flush = yaffs_file_flush,
-+	.fsync = yaffs_sync_object,
-+	.splice_read = generic_file_splice_read,
-+	.splice_write = generic_file_splice_write,
-+	.llseek = generic_file_llseek,
-+};
-+
-+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
-+
-+static const struct file_operations yaffs_file_operations = {
-+	.read = do_sync_read,
-+	.write = do_sync_write,
-+	.aio_read = generic_file_aio_read,
-+	.aio_write = generic_file_aio_write,
-+	.mmap = generic_file_mmap,
-+	.flush = yaffs_file_flush,
-+	.fsync = yaffs_sync_object,
-+	.sendfile = generic_file_sendfile,
-+};
-+
-+#else
-+
-+static const struct file_operations yaffs_file_operations = {
-+	.read = generic_file_read,
-+	.write = generic_file_write,
-+	.mmap = generic_file_mmap,
-+	.flush = yaffs_file_flush,
-+	.fsync = yaffs_sync_object,
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+	.sendfile = generic_file_sendfile,
-+#endif
-+};
-+#endif
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25))
-+static void zero_user_segment(struct page *page, unsigned start, unsigned end)
-+{
-+	void * kaddr = kmap_atomic(page, KM_USER0);
-+	memset(kaddr + start, 0, end - start);
-+	kunmap_atomic(kaddr, KM_USER0);
-+	flush_dcache_page(page);
-+}
-+#endif
-+
-+
-+static const struct inode_operations yaffs_file_inode_operations = {
-+	.setattr = yaffs_setattr,
-+#ifdef CONFIG_YAFFS_XATTR
-+	.setxattr = yaffs_setxattr,
-+	.getxattr = yaffs_getxattr,
-+	.listxattr = yaffs_listxattr,
-+	.removexattr = yaffs_removexattr,
-+#endif
-+};
-+
-+static const struct inode_operations yaffs_symlink_inode_operations = {
-+	.readlink = yaffs_readlink,
-+	.follow_link = yaffs_follow_link,
-+#if (YAFFS_NEW_FOLLOW_LINK == 1)
-+	.put_link = yaffs_put_link,
-+#endif
-+	.setattr = yaffs_setattr,
-+#ifdef CONFIG_YAFFS_XATTR
-+	.setxattr = yaffs_setxattr,
-+	.getxattr = yaffs_getxattr,
-+	.listxattr = yaffs_listxattr,
-+	.removexattr = yaffs_removexattr,
-+#endif
-+};
-+
-+static const struct inode_operations yaffs_dir_inode_operations = {
-+	.create = yaffs_create,
-+	.lookup = yaffs_lookup,
-+	.link = yaffs_link,
-+	.unlink = yaffs_unlink,
-+	.symlink = yaffs_symlink,
-+	.mkdir = yaffs_mkdir,
-+	.rmdir = yaffs_unlink,
-+	.mknod = yaffs_mknod,
-+	.rename = yaffs_rename,
-+	.setattr = yaffs_setattr,
-+#ifdef CONFIG_YAFFS_XATTR
-+	.setxattr = yaffs_setxattr,
-+	.getxattr = yaffs_getxattr,
-+	.listxattr = yaffs_listxattr,
-+	.removexattr = yaffs_removexattr,
-+#endif
-+};
-+
-+static const struct file_operations yaffs_dir_operations = {
-+	.read = generic_read_dir,
-+	.readdir = yaffs_readdir,
-+	.fsync = yaffs_sync_object,
-+	.llseek = yaffs_dir_llseek,
-+};
-+
-+static const struct super_operations yaffs_super_ops = {
-+	.statfs = yaffs_statfs,
-+
-+#ifndef YAFFS_USE_OWN_IGET
-+	.read_inode = yaffs_read_inode,
-+#endif
-+#ifdef YAFFS_HAS_PUT_INODE
-+	.put_inode = yaffs_put_inode,
-+#endif
-+	.put_super = yaffs_put_super,
-+#ifdef YAFFS_HAS_EVICT_INODE
-+	.evict_inode = yaffs_evict_inode,
-+#else
-+	.delete_inode = yaffs_delete_inode,
-+	.clear_inode = yaffs_clear_inode,
-+#endif
-+	.sync_fs = yaffs_sync_fs,
-+	.write_super = yaffs_write_super,
-+};
-+
-+
-+static  int yaffs_vfs_setattr(struct inode *inode, struct iattr *attr)
-+{
-+#ifdef  YAFFS_USE_SETATTR_COPY
-+	setattr_copy(inode,attr);
-+	return 0;
-+#else
-+	return inode_setattr(inode, attr);
-+#endif
-+
-+}
-+
-+static  int yaffs_vfs_setsize(struct inode *inode, loff_t newsize)
-+{
-+#ifdef  YAFFS_USE_TRUNCATE_SETSIZE
-+	truncate_setsize(inode,newsize);
-+	return 0;
-+#else
-+	truncate_inode_pages(&inode->i_data,newsize);
-+	return 0;
-+#endif
-+
-+}
-+
-+static unsigned yaffs_gc_control_callback(yaffs_dev_t *dev)
-+{
-+	return yaffs_gc_control;
-+}
-+                	                                                                                          	
-+static void yaffs_gross_lock(yaffs_dev_t *dev)
-+{
-+	T(YAFFS_TRACE_LOCK, (TSTR("yaffs locking %p\n"), current));
-+	down(&(yaffs_dev_to_lc(dev)->grossLock));
-+	T(YAFFS_TRACE_LOCK, (TSTR("yaffs locked %p\n"), current));
-+}
-+
-+static void yaffs_gross_unlock(yaffs_dev_t *dev)
-+{
-+	T(YAFFS_TRACE_LOCK, (TSTR("yaffs unlocking %p\n"), current));
-+	up(&(yaffs_dev_to_lc(dev)->grossLock));
-+}
-+
-+#ifdef YAFFS_COMPILE_EXPORTFS
-+
-+static struct inode *
-+yaffs2_nfs_get_inode(struct super_block *sb, uint64_t ino, uint32_t generation)
-+{
-+	return Y_IGET(sb, ino);
-+}
-+
-+static struct dentry *
-+yaffs2_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, yaffs2_nfs_get_inode) ;
-+}
-+
-+static struct dentry *
-+ yaffs2_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, yaffs2_nfs_get_inode);
-+}
-+
-+struct dentry *yaffs2_get_parent(struct dentry *dentry)
-+{
-+
-+	struct super_block *sb = dentry->d_inode->i_sb;
-+	struct dentry *parent = ERR_PTR(-ENOENT);
-+	struct inode *inode;
-+	unsigned long parent_ino;
-+	yaffs_obj_t *d_obj;
-+	yaffs_obj_t *parent_obj;
-+
-+	d_obj = yaffs_InodeToObject(dentry->d_inode);
-+
-+	if (d_obj) {
-+		parent_obj = d_obj->parent;
-+		if (parent_obj) {
-+			parent_ino = yaffs_get_obj_inode(parent_obj);
-+			inode = Y_IGET(sb, parent_ino);
-+
-+			if (IS_ERR(inode)) {
-+				parent = ERR_CAST(inode);
-+			} else {
-+				parent = d_obtain_alias(inode);
-+				if (!IS_ERR(parent)) {
-+					parent = ERR_PTR(-ENOMEM);
-+					iput(inode);
-+				}
-+			}
-+		}
-+	}
-+
-+	return parent;
-+}
-+
-+/* Just declare a zero structure as a NULL value implies
-+ * using the default functions of exportfs.
-+ */
-+
-+static struct export_operations yaffs_export_ops =
-+{
-+	.fh_to_dentry = yaffs2_fh_to_dentry,
-+	.fh_to_parent = yaffs2_fh_to_parent,
-+	.get_parent = yaffs2_get_parent,
-+} ;
-+
-+#endif
-+
-+/*-----------------------------------------------------------------*/
-+/* Directory search context allows us to unlock access to yaffs during
-+ * filldir without causing problems with the directory being modified.
-+ * This is similar to the tried and tested mechanism used in yaffs direct.
-+ *
-+ * A search context iterates along a doubly linked list of siblings in the
-+ * directory. If the iterating object is deleted then this would corrupt
-+ * the list iteration, likely causing a crash. The search context avoids
-+ * this by using the remove_obj_fn to move the search context to the
-+ * next object before the object is deleted.
-+ *
-+ * Many readdirs (and thus seach conexts) may be alive simulateously so
-+ * each yaffs_dev_t has a list of these.
-+ *
-+ * A seach context lives for the duration of a readdir.
-+ *
-+ * All these functions must be called while yaffs is locked.
-+ */
-+
-+struct yaffs_SearchContext {
-+	yaffs_dev_t *dev;
-+	yaffs_obj_t *dirObj;
-+	yaffs_obj_t *nextReturn;
-+	struct ylist_head others;
-+};
-+
-+/*
-+ * yaffs_NewSearch() creates a new search context, initialises it and
-+ * adds it to the device's search context list.
-+ *
-+ * Called at start of readdir.
-+ */
-+static struct yaffs_SearchContext * yaffs_NewSearch(yaffs_obj_t *dir)
-+{
-+	yaffs_dev_t *dev = dir->my_dev;
-+	struct yaffs_SearchContext *sc = YMALLOC(sizeof(struct yaffs_SearchContext));
-+	if(sc){
-+		sc->dirObj = dir;
-+		sc->dev = dev;
-+		if( ylist_empty(&sc->dirObj->variant.dir_variant.children))
-+			sc->nextReturn = NULL;
-+		else
-+			sc->nextReturn = ylist_entry(
-+                                dir->variant.dir_variant.children.next,
-+				yaffs_obj_t,siblings);
-+		YINIT_LIST_HEAD(&sc->others);
-+		ylist_add(&sc->others,&(yaffs_dev_to_lc(dev)->searchContexts));
-+	}
-+	return sc;
-+}
-+
-+/*
-+ * yaffs_search_end() disposes of a search context and cleans up.
-+ */
-+static void yaffs_search_end(struct yaffs_SearchContext * sc)
-+{
-+	if(sc){
-+		ylist_del(&sc->others);
-+		YFREE(sc);
-+	}
-+}
-+
-+/*
-+ * yaffs_search_advance() moves a search context to the next object.
-+ * Called when the search iterates or when an object removal causes
-+ * the search context to be moved to the next object.
-+ */
-+static void yaffs_search_advance(struct yaffs_SearchContext *sc)
-+{
-+        if(!sc)
-+                return;
-+
-+        if( sc->nextReturn == NULL ||
-+                ylist_empty(&sc->dirObj->variant.dir_variant.children))
-+                sc->nextReturn = NULL;
-+        else {
-+                struct ylist_head *next = sc->nextReturn->siblings.next;
-+
-+                if( next == &sc->dirObj->variant.dir_variant.children)
-+                        sc->nextReturn = NULL; /* end of list */
-+                else
-+                        sc->nextReturn = ylist_entry(next,yaffs_obj_t,siblings);
-+        }
-+}
-+
-+/*
-+ * yaffs_remove_obj_callback() is called when an object is unlinked.
-+ * We check open search contexts and advance any which are currently
-+ * on the object being iterated.
-+ */
-+static void yaffs_remove_obj_callback(yaffs_obj_t *obj)
-+{
-+
-+        struct ylist_head *i;
-+        struct yaffs_SearchContext *sc;
-+        struct ylist_head *search_contexts = &(yaffs_dev_to_lc(obj->my_dev)->searchContexts);
-+
-+
-+        /* Iterate through the directory search contexts.
-+         * If any are currently on the object being removed, then advance
-+         * the search context to the next object to prevent a hanging pointer.
-+         */
-+         ylist_for_each(i, search_contexts) {
-+                if (i) {
-+                        sc = ylist_entry(i, struct yaffs_SearchContext,others);
-+                        if(sc->nextReturn == obj)
-+                                yaffs_search_advance(sc);
-+                }
-+	}
-+
-+}
-+
-+
-+/*-----------------------------------------------------------------*/
-+
-+static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
-+			int buflen)
-+{
-+	unsigned char *alias;
-+	int ret;
-+
-+	yaffs_dev_t *dev = yaffs_dentry_to_obj(dentry)->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
-+
-+	yaffs_gross_unlock(dev);
-+
-+	if (!alias)
-+		return -ENOMEM;
-+
-+	ret = vfs_readlink(dentry, buffer, buflen, alias);
-+	kfree(alias);
-+	return ret;
-+}
-+
-+#if (YAFFS_NEW_FOLLOW_LINK == 1)
-+static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
-+#else
-+static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
-+#endif
-+{
-+	unsigned char *alias;
-+	int ret;
-+	yaffs_dev_t *dev = yaffs_dentry_to_obj(dentry)->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	alias = yaffs_get_symlink_alias(yaffs_dentry_to_obj(dentry));
-+	yaffs_gross_unlock(dev);
-+
-+	if (!alias) {
-+		ret = -ENOMEM;
-+		goto out;
-+	}
-+
-+#if (YAFFS_NEW_FOLLOW_LINK == 1)
-+	nd_set_link(nd, alias);
-+	ret = (int)alias;
-+out:
-+	return ERR_PTR(ret);
-+#else
-+	ret = vfs_follow_link(nd, alias);
-+	kfree(alias);
-+out:
-+	return ret;
-+#endif
-+}
-+
-+#if (YAFFS_NEW_FOLLOW_LINK == 1)
-+void yaffs_put_link(struct dentry *dentry, struct nameidata *nd, void *alias) {
-+	kfree(alias);
-+}
-+#endif
-+
-+struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
-+				yaffs_obj_t *obj);
-+
-+/*
-+ * Lookup is used to find objects in the fs
-+ */
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+
-+static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
-+				struct nameidata *n)
-+#else
-+static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
-+#endif
-+{
-+	yaffs_obj_t *obj;
-+	struct inode *inode = NULL;	/* NCB 2.5/2.6 needs NULL here */
-+
-+	yaffs_dev_t *dev = yaffs_InodeToObject(dir)->my_dev;
-+
-+	if(current != yaffs_dev_to_lc(dev)->readdirProcess)
-+		yaffs_gross_lock(dev);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_lookup for %d:%s\n"),
-+		yaffs_InodeToObject(dir)->obj_id, dentry->d_name.name));
-+
-+	obj = yaffs_find_by_name(yaffs_InodeToObject(dir),
-+					dentry->d_name.name);
-+
-+	obj = yaffs_get_equivalent_obj(obj);	/* in case it was a hardlink */
-+
-+	/* Can't hold gross lock when calling yaffs_get_inode() */
-+	if(current != yaffs_dev_to_lc(dev)->readdirProcess)
-+		yaffs_gross_unlock(dev);
-+
-+	if (obj) {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_lookup found %d\n"), obj->obj_id));
-+
-+		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
-+
-+		if (inode) {
-+			T(YAFFS_TRACE_OS,
-+				(TSTR("yaffs_loookup dentry \n")));
-+/* #if 0 asserted by NCB for 2.5/6 compatability - falls through to
-+ * d_add even if NULL inode */
-+#if 0
-+			/*dget(dentry); // try to solve directory bug */
-+			d_add(dentry, inode);
-+
-+			/* return dentry; */
-+			return NULL;
-+#endif
-+		}
-+
-+	} else {
-+		T(YAFFS_TRACE_OS,(TSTR("yaffs_lookup not found\n")));
-+
-+	}
-+
-+/* added NCB for 2.5/6 compatability - forces add even if inode is
-+ * NULL which creates dentry hash */
-+	d_add(dentry, inode);
-+
-+	return NULL;
-+}
-+
-+
-+#ifdef YAFFS_HAS_PUT_INODE
-+
-+/* For now put inode is just for debugging
-+ * Put inode is called when the inode **structure** is put.
-+ */
-+static void yaffs_put_inode(struct inode *inode)
-+{
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_put_inode: ino %d, count %d\n"), (int)inode->i_ino,
-+		atomic_read(&inode->i_count)));
-+
-+}
-+#endif
-+
-+
-+static void yaffs_unstitch_obj(struct inode *inode, yaffs_obj_t *obj)
-+{
-+	/* Clear the association between the inode and
-+	 * the yaffs_obj_t.
-+	 */
-+	obj->my_inode = NULL;
-+	yaffs_InodeToObjectLV(inode) = NULL;
-+
-+	/* If the object freeing was deferred, then the real
-+	 * free happens now.
-+	 * This should fix the inode inconsistency problem.
-+	 */
-+	yaffs_handle_defered_free(obj);
-+}
-+
-+#ifdef YAFFS_HAS_EVICT_INODE
-+/* yaffs_evict_inode combines into one operation what was previously done in
-+ * yaffs_clear_inode() and yaffs_delete_inode()
-+ *
-+ */
-+static void yaffs_evict_inode( struct inode *inode)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev;
-+	int deleteme = 0;
-+
-+	obj = yaffs_InodeToObject(inode);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_evict_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
-+		atomic_read(&inode->i_count),
-+		obj ? "object exists" : "null object"));
-+
-+	if (!inode->i_nlink && !is_bad_inode(inode))
-+		deleteme = 1;
-+	truncate_inode_pages(&inode->i_data,0);
-+	end_writeback(inode);
-+
-+	if(deleteme && obj){
-+		dev = obj->my_dev;
-+		yaffs_gross_lock(dev);
-+		yaffs_del_obj(obj);
-+		yaffs_gross_unlock(dev);
-+	}
-+	if (obj) {
-+		dev = obj->my_dev;
-+		yaffs_gross_lock(dev);
-+		yaffs_unstitch_obj(inode,obj);
-+		yaffs_gross_unlock(dev);
-+	}
-+
-+
-+}
-+#else
-+
-+/* clear is called to tell the fs to release any per-inode data it holds.
-+ * The object might still exist on disk and is just being thrown out of the cache
-+ * or else the object has actually been deleted and we're being called via
-+ * the chain
-+ *   yaffs_delete_inode() -> clear_inode()->yaffs_clear_inode()
-+ */
-+
-+static void yaffs_clear_inode(struct inode *inode)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev;
-+
-+	obj = yaffs_InodeToObject(inode);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_clear_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
-+		atomic_read(&inode->i_count),
-+		obj ? "object exists" : "null object"));
-+
-+	if (obj) {
-+		dev = obj->my_dev;
-+		yaffs_gross_lock(dev);
-+		yaffs_unstitch_obj(inode,obj);
-+		yaffs_gross_unlock(dev);
-+	}
-+
-+}
-+
-+/* delete is called when the link count is zero and the inode
-+ * is put (ie. nobody wants to know about it anymore, time to
-+ * delete the file).
-+ * NB Must call clear_inode()
-+ */
-+static void yaffs_delete_inode(struct inode *inode)
-+{
-+	yaffs_obj_t *obj = yaffs_InodeToObject(inode);
-+	yaffs_dev_t *dev;
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_delete_inode: ino %d, count %d %s\n"), (int)inode->i_ino,
-+		atomic_read(&inode->i_count),
-+		obj ? "object exists" : "null object"));
-+
-+	if (obj) {
-+		dev = obj->my_dev;
-+		yaffs_gross_lock(dev);
-+		yaffs_del_obj(obj);
-+		yaffs_gross_unlock(dev);
-+	}
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
-+	truncate_inode_pages(&inode->i_data, 0);
-+#endif
-+	clear_inode(inode);
-+}
-+#endif
-+
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static int yaffs_file_flush(struct file *file, fl_owner_t id)
-+#else
-+static int yaffs_file_flush(struct file *file)
-+#endif
-+{
-+	yaffs_obj_t *obj = yaffs_dentry_to_obj(file->f_dentry);
-+
-+	yaffs_dev_t *dev = obj->my_dev;
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_file_flush object %d (%s)\n"), obj->obj_id,
-+		obj->dirty ? "dirty" : "clean"));
-+
-+	yaffs_gross_lock(dev);
-+
-+	yaffs_flush_file(obj, 1, 0);
-+
-+	yaffs_gross_unlock(dev);
-+
-+	return 0;
-+}
-+
-+static int yaffs_readpage_nolock(struct file *f, struct page *pg)
-+{
-+	/* Lifted from jffs2 */
-+
-+	yaffs_obj_t *obj;
-+	unsigned char *pg_buf;
-+	int ret;
-+
-+	yaffs_dev_t *dev;
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_readpage_nolock at %08x, size %08x\n"),
-+		(unsigned)(pg->index << PAGE_CACHE_SHIFT),
-+		(unsigned)PAGE_CACHE_SIZE));
-+
-+	obj = yaffs_dentry_to_obj(f->f_dentry);
-+
-+	dev = obj->my_dev;
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+	BUG_ON(!PageLocked(pg));
-+#else
-+	if (!PageLocked(pg))
-+		PAGE_BUG(pg);
-+#endif
-+
-+	pg_buf = kmap(pg);
-+	/* FIXME: Can kmap fail? */
-+
-+	yaffs_gross_lock(dev);
-+
-+	ret = yaffs_file_rd(obj, pg_buf,
-+				pg->index << PAGE_CACHE_SHIFT,
-+				PAGE_CACHE_SIZE);
-+
-+	yaffs_gross_unlock(dev);
-+
-+	if (ret >= 0)
-+		ret = 0;
-+
-+	if (ret) {
-+		ClearPageUptodate(pg);
-+		SetPageError(pg);
-+	} else {
-+		SetPageUptodate(pg);
-+		ClearPageError(pg);
-+	}
-+
-+	flush_dcache_page(pg);
-+	kunmap(pg);
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_readpage_nolock done\n")));
-+	return ret;
-+}
-+
-+static int yaffs_readpage_unlock(struct file *f, struct page *pg)
-+{
-+	int ret = yaffs_readpage_nolock(f, pg);
-+	UnlockPage(pg);
-+	return ret;
-+}
-+
-+static int yaffs_readpage(struct file *f, struct page *pg)
-+{
-+	int ret;
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_readpage\n")));
-+	ret=yaffs_readpage_unlock(f, pg);
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_readpage done\n")));
-+	return ret;
-+}
-+
-+/* writepage inspired by/stolen from smbfs */
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_writepage(struct page *page, struct writeback_control *wbc)
-+#else
-+static int yaffs_writepage(struct page *page)
-+#endif
-+{
-+	yaffs_dev_t *dev;
-+	struct address_space *mapping = page->mapping;
-+	struct inode *inode;
-+	unsigned long end_index;
-+	char *buffer;
-+	yaffs_obj_t *obj;
-+	int nWritten = 0;
-+	unsigned n_bytes;
-+	loff_t i_size;
-+
-+	if (!mapping)
-+		BUG();
-+	inode = mapping->host;
-+	if (!inode)
-+		BUG();
-+	i_size = i_size_read(inode);
-+
-+	end_index = i_size >> PAGE_CACHE_SHIFT;
-+
-+	if(page->index < end_index)
-+		n_bytes = PAGE_CACHE_SIZE;
-+	else {
-+		n_bytes = i_size & (PAGE_CACHE_SIZE -1);
-+
-+		if (page->index > end_index || !n_bytes) {
-+			T(YAFFS_TRACE_OS,
-+				(TSTR("yaffs_writepage at %08x, inode size = %08x!!!\n"),
-+				(unsigned)(page->index << PAGE_CACHE_SHIFT),
-+				(unsigned)inode->i_size));
-+			T(YAFFS_TRACE_OS,
-+				(TSTR("                -> don't care!!\n")));
-+
-+			zero_user_segment(page,0,PAGE_CACHE_SIZE);
-+			set_page_writeback(page);
-+			unlock_page(page);
-+			end_page_writeback(page);
-+			return 0;
-+		}
-+	}
-+
-+	if(n_bytes != PAGE_CACHE_SIZE)
-+		zero_user_segment(page,n_bytes,PAGE_CACHE_SIZE);
-+
-+	get_page(page);
-+
-+	buffer = kmap(page);
-+
-+	obj = yaffs_InodeToObject(inode);
-+	dev = obj->my_dev;
-+	yaffs_gross_lock(dev);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_writepage at %08x, size %08x\n"),
-+		(unsigned)(page->index << PAGE_CACHE_SHIFT), n_bytes));
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("writepag0: obj = %05x, ino = %05x\n"),
-+		(int)obj->variant.file_variant.file_size, (int)inode->i_size));
-+
-+	nWritten = yaffs_wr_file(obj, buffer,
-+			page->index << PAGE_CACHE_SHIFT, n_bytes, 0);
-+
-+	yaffs_touch_super(dev);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("writepag1: obj = %05x, ino = %05x\n"),
-+		(int)obj->variant.file_variant.file_size, (int)inode->i_size));
-+
-+	yaffs_gross_unlock(dev);
-+
-+	kunmap(page);
-+	set_page_writeback(page);
-+	unlock_page(page);
-+	end_page_writeback(page);
-+	put_page(page);
-+
-+	return (nWritten == n_bytes) ? 0 : -ENOSPC;
-+}
-+
-+
-+#if (YAFFS_USE_WRITE_BEGIN_END > 0)
-+static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
-+				loff_t pos, unsigned len, unsigned flags,
-+				struct page **pagep, void **fsdata)
-+{
-+	struct page *pg = NULL;
-+	pgoff_t index = pos >> PAGE_CACHE_SHIFT;
-+
-+	int ret = 0;
-+	int space_held = 0;
-+
-+	/* Get a page */
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+	pg = grab_cache_page_write_begin(mapping, index, flags);
-+#else
-+	pg = __grab_cache_page(mapping, index);
-+#endif
-+
-+	*pagep = pg;
-+	if (!pg) {
-+		ret =  -ENOMEM;
-+		goto out;
-+	}
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("start yaffs_write_begin index %d(%x) uptodate %d\n"),
-+		(int)index,(int)index,Page_Uptodate(pg) ? 1 : 0));
-+
-+	/* Get fs space */
-+	space_held = yaffs_hold_space(filp);
-+
-+	if (!space_held) {
-+		ret = -ENOSPC;
-+		goto out;
-+	}
-+
-+	/* Update page if required */
-+
-+	if (!Page_Uptodate(pg))
-+		ret = yaffs_readpage_nolock(filp, pg);
-+
-+	if (ret)
-+		goto out;
-+
-+	/* Happy path return */
-+	T(YAFFS_TRACE_OS, (TSTR("end yaffs_write_begin - ok\n")));
-+
-+	return 0;
-+
-+out:
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("end yaffs_write_begin fail returning %d\n"), ret));
-+	if (space_held)
-+		yaffs_release_space(filp);
-+	if (pg) {
-+		unlock_page(pg);
-+		page_cache_release(pg);
-+	}
-+	return ret;
-+}
-+
-+#else
-+
-+static int yaffs_prepare_write(struct file *f, struct page *pg,
-+				unsigned offset, unsigned to)
-+{
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_prepair_write\n")));
-+
-+	if (!Page_Uptodate(pg))
-+		return yaffs_readpage_nolock(f, pg);
-+	return 0;
-+}
-+#endif
-+
-+#if (YAFFS_USE_WRITE_BEGIN_END > 0)
-+static int yaffs_write_end(struct file *filp, struct address_space *mapping,
-+				loff_t pos, unsigned len, unsigned copied,
-+				struct page *pg, void *fsdadata)
-+{
-+	int ret = 0;
-+	void *addr, *kva;
-+	uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);
-+
-+	kva = kmap(pg);
-+	addr = kva + offset_into_page;
-+
-+	T(YAFFS_TRACE_OS,
-+		("yaffs_write_end addr %p pos %x n_bytes %d\n",
-+		addr,(unsigned)pos, copied));
-+
-+	ret = yaffs_file_write(filp, addr, copied, &pos);
-+
-+	if (ret != copied) {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_write_end not same size ret %d  copied %d\n"),
-+			ret, copied));
-+		SetPageError(pg);
-+	} else {
-+		/* Nothing */
-+	}
-+
-+	kunmap(pg);
-+
-+	yaffs_release_space(filp);
-+	unlock_page(pg);
-+	page_cache_release(pg);
-+	return ret;
-+}
-+#else
-+
-+static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
-+				unsigned to)
-+{
-+	void *addr, *kva;
-+
-+	loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;
-+	int n_bytes = to - offset;
-+	int nWritten;
-+
-+	unsigned spos = pos;
-+	unsigned saddr;
-+
-+	kva = kmap(pg);
-+	addr = kva + offset;
-+
-+	saddr = (unsigned) addr;
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_commit_write addr %x pos %x n_bytes %d\n"),
-+		saddr, spos, n_bytes));
-+
-+	nWritten = yaffs_file_write(f, addr, n_bytes, &pos);
-+
-+	if (nWritten != n_bytes) {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_commit_write not same size nWritten %d  n_bytes %d\n"),
-+			nWritten, n_bytes));
-+		SetPageError(pg);
-+	} else {
-+		/* Nothing */
-+	}
-+
-+	kunmap(pg);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_commit_write returning %d\n"),
-+		nWritten == n_bytes ? 0 : nWritten));
-+
-+	return nWritten == n_bytes ? 0 : nWritten;
-+}
-+#endif
-+
-+
-+static void yaffs_fill_inode_from_obj(struct inode *inode, yaffs_obj_t *obj)
-+{
-+	if (inode && obj) {
-+
-+
-+		/* Check mode against the variant type and attempt to repair if broken. */
-+		__u32 mode = obj->yst_mode;
-+		switch (obj->variant_type) {
-+		case YAFFS_OBJECT_TYPE_FILE:
-+			if (!S_ISREG(mode)) {
-+				obj->yst_mode &= ~S_IFMT;
-+				obj->yst_mode |= S_IFREG;
-+			}
-+
-+			break;
-+		case YAFFS_OBJECT_TYPE_SYMLINK:
-+			if (!S_ISLNK(mode)) {
-+				obj->yst_mode &= ~S_IFMT;
-+				obj->yst_mode |= S_IFLNK;
-+			}
-+
-+			break;
-+		case YAFFS_OBJECT_TYPE_DIRECTORY:
-+			if (!S_ISDIR(mode)) {
-+				obj->yst_mode &= ~S_IFMT;
-+				obj->yst_mode |= S_IFDIR;
-+			}
-+
-+			break;
-+		case YAFFS_OBJECT_TYPE_UNKNOWN:
-+		case YAFFS_OBJECT_TYPE_HARDLINK:
-+		case YAFFS_OBJECT_TYPE_SPECIAL:
-+		default:
-+			/* TODO? */
-+			break;
-+		}
-+
-+		inode->i_flags |= S_NOATIME;
-+
-+		inode->i_ino = obj->obj_id;
-+		inode->i_mode = obj->yst_mode;
-+		inode->i_uid = obj->yst_uid;
-+		inode->i_gid = obj->yst_gid;
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
-+		inode->i_blksize = inode->i_sb->s_blocksize;
-+#endif
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+
-+		inode->i_rdev = old_decode_dev(obj->yst_rdev);
-+		inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
-+		inode->i_atime.tv_nsec = 0;
-+		inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;
-+		inode->i_mtime.tv_nsec = 0;
-+		inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;
-+		inode->i_ctime.tv_nsec = 0;
-+#else
-+		inode->i_rdev = obj->yst_rdev;
-+		inode->i_atime = obj->yst_atime;
-+		inode->i_mtime = obj->yst_mtime;
-+		inode->i_ctime = obj->yst_ctime;
-+#endif
-+		inode->i_size = yaffs_get_obj_length(obj);
-+		inode->i_blocks = (inode->i_size + 511) >> 9;
-+
-+		inode->i_nlink = yaffs_get_obj_link_count(obj);
-+
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_fill_inode mode %x uid %d gid %d size %d count %d\n"),
-+			inode->i_mode, inode->i_uid, inode->i_gid,
-+			(int)inode->i_size, atomic_read(&inode->i_count)));
-+
-+		switch (obj->yst_mode & S_IFMT) {
-+		default:	/* fifo, device or socket */
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+			init_special_inode(inode, obj->yst_mode,
-+					old_decode_dev(obj->yst_rdev));
-+#else
-+			init_special_inode(inode, obj->yst_mode,
-+					(dev_t) (obj->yst_rdev));
-+#endif
-+			break;
-+		case S_IFREG:	/* file */
-+			inode->i_op = &yaffs_file_inode_operations;
-+			inode->i_fop = &yaffs_file_operations;
-+			inode->i_mapping->a_ops =
-+				&yaffs_file_address_operations;
-+			break;
-+		case S_IFDIR:	/* directory */
-+			inode->i_op = &yaffs_dir_inode_operations;
-+			inode->i_fop = &yaffs_dir_operations;
-+			break;
-+		case S_IFLNK:	/* symlink */
-+			inode->i_op = &yaffs_symlink_inode_operations;
-+			break;
-+		}
-+
-+		yaffs_InodeToObjectLV(inode) = obj;
-+
-+		obj->my_inode = inode;
-+
-+	} else {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_FileInode invalid parameters\n")));
-+	}
-+
-+}
-+
-+struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
-+				yaffs_obj_t *obj)
-+{
-+	struct inode *inode;
-+
-+	if (!sb) {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_get_inode for NULL super_block!!\n")));
-+		return NULL;
-+
-+	}
-+
-+	if (!obj) {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_get_inode for NULL object!!\n")));
-+		return NULL;
-+
-+	}
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_get_inode for object %d\n"), obj->obj_id));
-+
-+	inode = Y_IGET(sb, obj->obj_id);
-+	if (IS_ERR(inode))
-+		return NULL;
-+
-+	/* NB Side effect: iget calls back to yaffs_read_inode(). */
-+	/* iget also increments the inode's i_count */
-+	/* NB You can't be holding grossLock or deadlock will happen! */
-+
-+	return inode;
-+}
-+
-+static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
-+				loff_t *pos)
-+{
-+	yaffs_obj_t *obj;
-+	int nWritten, ipos;
-+	struct inode *inode;
-+	yaffs_dev_t *dev;
-+
-+	obj = yaffs_dentry_to_obj(f->f_dentry);
-+
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	inode = f->f_dentry->d_inode;
-+
-+	if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
-+		ipos = inode->i_size;
-+	else
-+		ipos = *pos;
-+
-+	if (!obj)
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_file_write: hey obj is null!\n")));
-+	else
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_file_write about to write writing %u(%x) bytes"
-+			"to object %d at %d(%x)\n"),
-+			(unsigned) n, (unsigned) n, obj->obj_id, ipos,ipos));
-+
-+	nWritten = yaffs_wr_file(obj, buf, ipos, n, 0);
-+
-+	yaffs_touch_super(dev);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_file_write: %d(%x) bytes written\n"),
-+		(unsigned )n,(unsigned)n));
-+
-+	if (nWritten > 0) {
-+		ipos += nWritten;
-+		*pos = ipos;
-+		if (ipos > inode->i_size) {
-+			inode->i_size = ipos;
-+			inode->i_blocks = (ipos + 511) >> 9;
-+
-+			T(YAFFS_TRACE_OS,
-+				(TSTR("yaffs_file_write size updated to %d bytes, "
-+				"%d blocks\n"),
-+				ipos, (int)(inode->i_blocks)));
-+		}
-+
-+	}
-+	yaffs_gross_unlock(dev);
-+	return (nWritten == 0) && (n > 0) ? -ENOSPC : nWritten;
-+}
-+
-+/* Space holding and freeing is done to ensure we have space available for write_begin/end */
-+/* For now we just assume few parallel writes and check against a small number. */
-+/* Todo: need to do this with a counter to handle parallel reads better */
-+
-+static ssize_t yaffs_hold_space(struct file *f)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev;
-+
-+	int n_free_chunks;
-+
-+
-+	obj = yaffs_dentry_to_obj(f->f_dentry);
-+
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	n_free_chunks = yaffs_get_n_free_chunks(dev);
-+
-+	yaffs_gross_unlock(dev);
-+
-+	return (n_free_chunks > 20) ? 1 : 0;
-+}
-+
-+static void yaffs_release_space(struct file *f)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev;
-+
-+
-+	obj = yaffs_dentry_to_obj(f->f_dentry);
-+
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+
-+	yaffs_gross_unlock(dev);
-+}
-+
-+
-+static loff_t yaffs_dir_llseek(struct file *file, loff_t offset, int origin)
-+{
-+	long long retval;
-+
-+	lock_kernel();
-+
-+	switch (origin){
-+	case 2:
-+		offset += i_size_read(file->f_path.dentry->d_inode);
-+		break;
-+	case 1:
-+		offset += file->f_pos;
-+	}
-+	retval = -EINVAL;
-+
-+	if (offset >= 0){
-+		if (offset != file->f_pos)
-+			file->f_pos = offset;
-+
-+		retval = offset;
-+	}
-+	unlock_kernel();
-+	return retval;
-+}
-+
-+
-+static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev;
-+        struct yaffs_SearchContext *sc;
-+	struct inode *inode = f->f_dentry->d_inode;
-+	unsigned long offset, curoffs;
-+	yaffs_obj_t *l;
-+        int retVal = 0;
-+
-+	char name[YAFFS_MAX_NAME_LENGTH + 1];
-+
-+	obj = yaffs_dentry_to_obj(f->f_dentry);
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	yaffs_dev_to_lc(dev)->readdirProcess = current;
-+
-+	offset = f->f_pos;
-+
-+        sc = yaffs_NewSearch(obj);
-+        if(!sc){
-+                retVal = -ENOMEM;
-+                goto out;
-+        }
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_readdir: starting at %d\n"), (int)offset));
-+
-+	if (offset == 0) {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_readdir: entry . ino %d \n"),
-+			(int)inode->i_ino));
-+		yaffs_gross_unlock(dev);
-+		if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0){
-+			yaffs_gross_lock(dev);
-+			goto out;
-+		}
-+		yaffs_gross_lock(dev);
-+		offset++;
-+		f->f_pos++;
-+	}
-+	if (offset == 1) {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_readdir: entry .. ino %d \n"),
-+			(int)f->f_dentry->d_parent->d_inode->i_ino));
-+		yaffs_gross_unlock(dev);
-+		if (filldir(dirent, "..", 2, offset,
-+			f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0){
-+			yaffs_gross_lock(dev);
-+			goto out;
-+		}
-+		yaffs_gross_lock(dev);
-+		offset++;
-+		f->f_pos++;
-+	}
-+
-+	curoffs = 1;
-+
-+	/* If the directory has changed since the open or last call to
-+	   readdir, rewind to after the 2 canned entries. */
-+	if (f->f_version != inode->i_version) {
-+		offset = 2;
-+		f->f_pos = offset;
-+		f->f_version = inode->i_version;
-+	}
-+
-+	while(sc->nextReturn){
-+		curoffs++;
-+                l = sc->nextReturn;
-+		if (curoffs >= offset) {
-+                        int this_inode = yaffs_get_obj_inode(l);
-+                        int this_type = yaffs_get_obj_type(l);
-+
-+			yaffs_get_obj_name(l, name,
-+					    YAFFS_MAX_NAME_LENGTH + 1);
-+			T(YAFFS_TRACE_OS,
-+			  (TSTR("yaffs_readdir: %s inode %d\n"),
-+			  name, yaffs_get_obj_inode(l)));
-+
-+                        yaffs_gross_unlock(dev);
-+
-+			if (filldir(dirent,
-+					name,
-+					strlen(name),
-+					offset,
-+					this_inode,
-+					this_type) < 0){
-+				yaffs_gross_lock(dev);
-+				goto out;
-+			}
-+
-+                        yaffs_gross_lock(dev);
-+
-+			offset++;
-+			f->f_pos++;
-+		}
-+                yaffs_search_advance(sc);
-+	}
-+
-+out:
-+	yaffs_search_end(sc);
-+	yaffs_dev_to_lc(dev)->readdirProcess = NULL;
-+	yaffs_gross_unlock(dev);
-+
-+	return retVal;
-+}
-+
-+
-+
-+/*
-+ * File creation. Allocate an inode, and we're done..
-+ */
-+
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
-+#define YCRED(x) x
-+#else
-+#define YCRED(x) (x->cred)
-+#endif
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
-+			dev_t rdev)
-+#else
-+static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
-+			int rdev)
-+#endif
-+{
-+	struct inode *inode;
-+
-+	yaffs_obj_t *obj = NULL;
-+	yaffs_dev_t *dev;
-+
-+	yaffs_obj_t *parent = yaffs_InodeToObject(dir);
-+
-+	int error = -ENOSPC;
-+	uid_t uid = YCRED(current)->fsuid;
-+	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-+
-+	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
-+		mode |= S_ISGID;
-+
-+	if (parent) {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_mknod: parent object %d type %d\n"),
-+			parent->obj_id, parent->variant_type));
-+	} else {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_mknod: could not get parent object\n")));
-+		return -EPERM;
-+	}
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making oject for %s, "
-+			"mode %x dev %x\n"),
-+			dentry->d_name.name, mode, rdev));
-+
-+	dev = parent->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	switch (mode & S_IFMT) {
-+	default:
-+		/* Special (socket, fifo, device...) */
-+		T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making special\n")));
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+		obj = yaffs_create_special(parent, dentry->d_name.name, mode, uid,
-+				gid, old_encode_dev(rdev));
-+#else
-+		obj = yaffs_create_special(parent, dentry->d_name.name, mode, uid,
-+				gid, rdev);
-+#endif
-+		break;
-+	case S_IFREG:		/* file          */
-+		T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making file\n")));
-+		obj = yaffs_create_file(parent, dentry->d_name.name, mode, uid,
-+				gid);
-+		break;
-+	case S_IFDIR:		/* directory */
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_mknod: making directory\n")));
-+		obj = yaffs_create_dir(parent, dentry->d_name.name, mode,
-+					uid, gid);
-+		break;
-+	case S_IFLNK:		/* symlink */
-+		T(YAFFS_TRACE_OS, (TSTR("yaffs_mknod: making symlink\n")));
-+		obj = NULL;	/* Do we ever get here? */
-+		break;
-+	}
-+
-+	/* Can not call yaffs_get_inode() with gross lock held */
-+	yaffs_gross_unlock(dev);
-+
-+	if (obj) {
-+		inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
-+		d_instantiate(dentry, inode);
-+		update_dir_time(dir);
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_mknod created object %d count = %d\n"),
-+			obj->obj_id, atomic_read(&inode->i_count)));
-+		error = 0;
-+		yaffs_fill_inode_from_obj(dir,parent);
-+	} else {
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_mknod failed making object\n")));
-+		error = -ENOMEM;
-+	}
-+
-+	return error;
-+}
-+
-+static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
-+{
-+	int retVal;
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_mkdir\n")));
-+	retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
-+	return retVal;
-+}
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
-+			struct nameidata *n)
-+#else
-+static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
-+#endif
-+{
-+	T(YAFFS_TRACE_OS,(TSTR("yaffs_create\n")));
-+	return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
-+}
-+
-+static int yaffs_unlink(struct inode *dir, struct dentry *dentry)
-+{
-+	int retVal;
-+
-+	yaffs_dev_t *dev;
-+	yaffs_obj_t *obj;
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_unlink %d:%s\n"),
-+		(int)(dir->i_ino),
-+		dentry->d_name.name));
-+	obj = yaffs_InodeToObject(dir);
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	retVal = yaffs_unlinker(obj, dentry->d_name.name);
-+
-+	if (retVal == YAFFS_OK) {
-+		dentry->d_inode->i_nlink--;
-+		dir->i_version++;
-+		yaffs_gross_unlock(dev);
-+		mark_inode_dirty(dentry->d_inode);
-+		update_dir_time(dir);
-+		return 0;
-+	}
-+	yaffs_gross_unlock(dev);
-+	return -ENOTEMPTY;
-+}
-+
-+/*
-+ * Create a link...
-+ */
-+static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
-+			struct dentry *dentry)
-+{
-+	struct inode *inode = old_dentry->d_inode;
-+	yaffs_obj_t *obj = NULL;
-+	yaffs_obj_t *link = NULL;
-+	yaffs_dev_t *dev;
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_link\n")));
-+
-+	obj = yaffs_InodeToObject(inode);
-+	dev = obj->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	if (!S_ISDIR(inode->i_mode))		/* Don't link directories */
-+		link = yaffs_link_obj(yaffs_InodeToObject(dir), dentry->d_name.name,
-+			obj);
-+
-+	if (link) {
-+		old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
-+		d_instantiate(dentry, old_dentry->d_inode);
-+		atomic_inc(&old_dentry->d_inode->i_count);
-+		T(YAFFS_TRACE_OS,
-+			(TSTR("yaffs_link link count %d i_count %d\n"),
-+			old_dentry->d_inode->i_nlink,
-+			atomic_read(&old_dentry->d_inode->i_count)));
-+	}
-+
-+	yaffs_gross_unlock(dev);
-+
-+	if (link){
-+		update_dir_time(dir);
-+		return 0;
-+	}
-+
-+	return -EPERM;
-+}
-+
-+static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
-+				const char *symname)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev;
-+	uid_t uid = YCRED(current)->fsuid;
-+	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_symlink\n")));
-+
-+	dev = yaffs_InodeToObject(dir)->my_dev;
-+	yaffs_gross_lock(dev);
-+	obj = yaffs_create_symlink(yaffs_InodeToObject(dir), dentry->d_name.name,
-+				S_IFLNK | S_IRWXUGO, uid, gid, symname);
-+	yaffs_gross_unlock(dev);
-+
-+	if (obj) {
-+		struct inode *inode;
-+
-+		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
-+		d_instantiate(dentry, inode);
-+		update_dir_time(dir);
-+		T(YAFFS_TRACE_OS, (TSTR("symlink created OK\n")));
-+		return 0;
-+	} else {
-+		T(YAFFS_TRACE_OS, (TSTR("symlink not created\n")));
-+	}
-+
-+	return -ENOMEM;
-+}
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34))
-+static int yaffs_sync_object(struct file *file, int datasync)
-+#else
-+static int yaffs_sync_object(struct file *file, struct dentry *dentry,
-+				int datasync)
-+#endif
-+{
-+
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev;
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34))
-+	struct dentry *dentry = file->f_path.dentry;
-+#endif
-+
-+	obj = yaffs_dentry_to_obj(dentry);
-+
-+	dev = obj->my_dev;
-+
-+	T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
-+		(TSTR("yaffs_sync_object\n")));
-+	yaffs_gross_lock(dev);
-+	yaffs_flush_file(obj, 1, datasync);
-+	yaffs_gross_unlock(dev);
-+	return 0;
-+}
-+
-+/*
-+ * The VFS layer already does all the dentry stuff for rename.
-+ *
-+ * NB: POSIX says you can rename an object over an old object of the same name
-+ */
-+static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
-+			struct inode *new_dir, struct dentry *new_dentry)
-+{
-+	yaffs_dev_t *dev;
-+	int retVal = YAFFS_FAIL;
-+	yaffs_obj_t *target;
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_rename\n")));
-+	dev = yaffs_InodeToObject(old_dir)->my_dev;
-+
-+	yaffs_gross_lock(dev);
-+
-+	/* Check if the target is an existing directory that is not empty. */
-+	target = yaffs_find_by_name(yaffs_InodeToObject(new_dir),
-+				new_dentry->d_name.name);
-+
-+
-+
-+	if (target && target->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY &&
-+		!ylist_empty(&target->variant.dir_variant.children)) {
-+
-+		T(YAFFS_TRACE_OS, (TSTR("target is non-empty dir\n")));
-+
-+		retVal = YAFFS_FAIL;
-+	} else {
-+		/* Now does unlinking internally using shadowing mechanism */
-+		T(YAFFS_TRACE_OS, (TSTR("calling yaffs_rename_obj\n")));
-+
-+		retVal = yaffs_rename_obj(yaffs_InodeToObject(old_dir),
-+				old_dentry->d_name.name,
-+				yaffs_InodeToObject(new_dir),
-+				new_dentry->d_name.name);
-+	}
-+	yaffs_gross_unlock(dev);
-+
-+	if (retVal == YAFFS_OK) {
-+		if (target) {
-+			new_dentry->d_inode->i_nlink--;
-+			mark_inode_dirty(new_dentry->d_inode);
-+		}
-+		
-+		update_dir_time(old_dir);
-+		if(old_dir != new_dir)
-+			update_dir_time(new_dir);
-+		return 0;
-+	} else {
-+		return -ENOTEMPTY;
-+	}
-+}
-+
-+static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	int error = 0;
-+	yaffs_dev_t *dev;
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_setattr of object %d\n"),
-+		yaffs_InodeToObject(inode)->obj_id));
-+
-+	/* Fail if a requested resize >= 2GB */		
-+	if (attr->ia_valid & ATTR_SIZE &&
-+		(attr->ia_size >> 31))
-+		error = -EINVAL;
-+
-+	if (error == 0)
-+		error = inode_change_ok(inode, attr);
-+	if (error == 0) {
-+		int result;
-+		if (!error){
-+			error = yaffs_vfs_setattr(inode, attr);
-+			T(YAFFS_TRACE_OS,(TSTR("inode_setattr called\n")));
-+			if (attr->ia_valid & ATTR_SIZE){
-+                        	yaffs_vfs_setsize(inode,attr->ia_size);
-+                        	inode->i_blocks = (inode->i_size + 511) >> 9;
-+			}
-+		}
-+		dev = yaffs_InodeToObject(inode)->my_dev;
-+		if (attr->ia_valid & ATTR_SIZE){
-+			T(YAFFS_TRACE_OS,(TSTR("resize to %d(%x)\n"),
-+				(int)(attr->ia_size),(int)(attr->ia_size)));
-+		}
-+		yaffs_gross_lock(dev);
-+		result = yaffs_set_attribs(yaffs_InodeToObject(inode), attr);
-+		if(result == YAFFS_OK) {
-+			error = 0;
-+		} else {
-+			error = -EPERM;
-+		}
-+		yaffs_gross_unlock(dev);
-+
-+	}
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_setattr done returning %d\n"),error));
-+
-+	return error;
-+}
-+
-+#ifdef CONFIG_YAFFS_XATTR
-+int yaffs_setxattr(struct dentry *dentry, const char *name,
-+			const void *value, size_t size, int flags)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	int error = 0;
-+	yaffs_dev_t *dev;
-+	yaffs_obj_t *obj = yaffs_InodeToObject(inode);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_setxattr of object %d\n"),
-+		obj->obj_id));
-+
-+
-+	if (error == 0) {
-+		int result;
-+		dev = obj->my_dev;
-+		yaffs_gross_lock(dev);
-+		result = yaffs_set_xattrib(obj, name, value, size, flags);
-+		if(result == YAFFS_OK)
-+			error = 0;
-+		else if(result < 0)
-+			error = result;
-+		yaffs_gross_unlock(dev);
-+
-+	}
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_setxattr done returning %d\n"),error));
-+
-+	return error;
-+}
-+
-+
-+ssize_t yaffs_getxattr(struct dentry *dentry, const char *name, void *buff,
-+			size_t size)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	int error = 0;
-+	yaffs_dev_t *dev;
-+	yaffs_obj_t *obj = yaffs_InodeToObject(inode);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_getxattr \"%s\" from object %d\n"),
-+		name, obj->obj_id));
-+
-+	if (error == 0) {
-+		dev = obj->my_dev;
-+		yaffs_gross_lock(dev);
-+		error = yaffs_get_xattrib(obj, name, buff, size);
-+		yaffs_gross_unlock(dev);
-+
-+	}
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_getxattr done returning %d\n"),error));
-+
-+	return error;
-+}
-+
-+int yaffs_removexattr(struct dentry *dentry, const char *name)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	int error = 0;
-+	yaffs_dev_t *dev;
-+	yaffs_obj_t *obj = yaffs_InodeToObject(inode);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_removexattr of object %d\n"),
-+		obj->obj_id));
-+
-+
-+	if (error == 0) {
-+		int result;
-+		dev = obj->my_dev;
-+		yaffs_gross_lock(dev);
-+		result = yaffs_remove_xattrib(obj, name);
-+		if(result == YAFFS_OK)
-+			error = 0;
-+		else if(result < 0)
-+			error = result;
-+		yaffs_gross_unlock(dev);
-+
-+	}
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_removexattr done returning %d\n"),error));
-+
-+	return error;
-+}
-+
-+ssize_t yaffs_listxattr(struct dentry *dentry, char *buff, size_t size)
-+{
-+	struct inode *inode = dentry->d_inode;
-+	int error = 0;
-+	yaffs_dev_t *dev;
-+	yaffs_obj_t *obj = yaffs_InodeToObject(inode);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_listxattr of object %d\n"),
-+		obj->obj_id));
-+
-+
-+	if (error == 0) {
-+		dev = obj->my_dev;
-+		yaffs_gross_lock(dev);
-+		error = yaffs_list_xattrib(obj, buff, size);
-+		yaffs_gross_unlock(dev);
-+
-+	}
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_listxattr done returning %d\n"),error));
-+
-+	return error;
-+}
-+
-+#endif
-+
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
-+{
-+	yaffs_dev_t *dev = yaffs_dentry_to_obj(dentry)->my_dev;
-+	struct super_block *sb = dentry->d_sb;
-+#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
-+{
-+	yaffs_dev_t *dev = yaffs_SuperToDevice(sb);
-+#else
-+static int yaffs_statfs(struct super_block *sb, struct statfs *buf)
-+{
-+	yaffs_dev_t *dev = yaffs_SuperToDevice(sb);
-+#endif
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_statfs\n")));
-+
-+	yaffs_gross_lock(dev);
-+
-+	buf->f_type = YAFFS_MAGIC;
-+	buf->f_bsize = sb->s_blocksize;
-+	buf->f_namelen = 255;
-+
-+	if (dev->data_bytes_per_chunk & (dev->data_bytes_per_chunk - 1)) {
-+		/* Do this if chunk size is not a power of 2 */
-+
-+		uint64_t bytesInDev;
-+		uint64_t bytesFree;
-+
-+		bytesInDev = ((uint64_t)((dev->param.end_block - dev->param.start_block + 1))) *
-+			((uint64_t)(dev->param.chunks_per_block * dev->data_bytes_per_chunk));
-+
-+		do_div(bytesInDev, sb->s_blocksize); /* bytesInDev becomes the number of blocks */
-+		buf->f_blocks = bytesInDev;
-+
-+		bytesFree  = ((uint64_t)(yaffs_get_n_free_chunks(dev))) *
-+			((uint64_t)(dev->data_bytes_per_chunk));
-+
-+		do_div(bytesFree, sb->s_blocksize);
-+
-+		buf->f_bfree = bytesFree;
-+
-+	} else if (sb->s_blocksize > dev->data_bytes_per_chunk) {
-+
-+		buf->f_blocks =
-+			(dev->param.end_block - dev->param.start_block + 1) *
-+			dev->param.chunks_per_block /
-+			(sb->s_blocksize / dev->data_bytes_per_chunk);
-+		buf->f_bfree =
-+			yaffs_get_n_free_chunks(dev) /
-+			(sb->s_blocksize / dev->data_bytes_per_chunk);
-+	} else {
-+		buf->f_blocks =
-+			(dev->param.end_block - dev->param.start_block + 1) *
-+			dev->param.chunks_per_block *
-+			(dev->data_bytes_per_chunk / sb->s_blocksize);
-+
-+		buf->f_bfree =
-+			yaffs_get_n_free_chunks(dev) *
-+			(dev->data_bytes_per_chunk / sb->s_blocksize);
-+	}
-+
-+	buf->f_files = 0;
-+	buf->f_ffree = 0;
-+	buf->f_bavail = buf->f_bfree;
-+
-+	yaffs_gross_unlock(dev);
-+	return 0;
-+}
-+
-+
-+
-+static void yaffs_flush_inodes(struct super_block *sb)
-+{
-+	struct inode *iptr;
-+	yaffs_obj_t *obj;
-+	
-+	list_for_each_entry(iptr,&sb->s_inodes, i_sb_list){
-+		obj = yaffs_InodeToObject(iptr);
-+		if(obj){
-+			T(YAFFS_TRACE_OS, (TSTR("flushing obj %d\n"),
-+				obj->obj_id));
-+			yaffs_flush_file(obj,1,0);
-+		}
-+	}
-+}
-+
-+
-+static void yaffs_flush_super(struct super_block *sb, int do_checkpoint)
-+{
-+	yaffs_dev_t *dev = yaffs_SuperToDevice(sb);	
-+	if(!dev)
-+		return;
-+	
-+	yaffs_flush_inodes(sb);
-+	yaffs_update_dirty_dirs(dev);
-+	yaffs_flush_whole_cache(dev);
-+	if(do_checkpoint)
-+		yaffs_checkpoint_save(dev);
-+}
-+
-+
-+static unsigned yaffs_bg_gc_urgency(yaffs_dev_t *dev)
-+{
-+	unsigned erasedChunks = dev->n_erased_blocks * dev->param.chunks_per_block;
-+	struct yaffs_LinuxContext *context = yaffs_dev_to_lc(dev);
-+	unsigned scatteredFree = 0; /* Free chunks not in an erased block */
-+
-+	if(erasedChunks < dev->n_free_chunks)
-+		scatteredFree = (dev->n_free_chunks - erasedChunks);
-+
-+	if(!context->bgRunning)
-+		return 0;
-+	else if(scatteredFree < (dev->param.chunks_per_block * 2))
-+		return 0;
-+	else if(erasedChunks > dev->n_free_chunks/2)
-+		return 0;
-+	else if(erasedChunks > dev->n_free_chunks/4)
-+		return 1;
-+	else
-+		return 2;
-+}
-+
-+static int yaffs_do_sync_fs(struct super_block *sb,
-+				int request_checkpoint)
-+{
-+
-+	yaffs_dev_t *dev = yaffs_SuperToDevice(sb);
-+	unsigned int oneshot_checkpoint = (yaffs_auto_checkpoint & 4);
-+	unsigned gc_urgent = yaffs_bg_gc_urgency(dev);
-+	int do_checkpoint;
-+
-+	T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
-+		(TSTR("yaffs_do_sync_fs: gc-urgency %d %s %s%s\n"),
-+		gc_urgent,
-+		sb->s_dirt ? "dirty" : "clean",
-+		request_checkpoint ? "checkpoint requested" : "no checkpoint",
-+		oneshot_checkpoint ? " one-shot" : "" ));
-+
-+	yaffs_gross_lock(dev);
-+	do_checkpoint = ((request_checkpoint && !gc_urgent) ||
-+			oneshot_checkpoint) &&
-+			!dev->is_checkpointed;
-+
-+	if (sb->s_dirt || do_checkpoint) {
-+		yaffs_flush_super(sb, !dev->is_checkpointed && do_checkpoint);
-+		sb->s_dirt = 0;
-+		if(oneshot_checkpoint)
-+			yaffs_auto_checkpoint &= ~4;
-+	}
-+	yaffs_gross_unlock(dev);
-+
-+	return 0;
-+}
-+
-+/*
-+ * yaffs background thread functions .
-+ * yaffs_bg_thread_fn() the thread function
-+ * yaffs_bg_start() launches the background thread.
-+ * yaffs_bg_stop() cleans up the background thread.
-+ *
-+ * NB: 
-+ * The thread should only run after the yaffs is initialised
-+ * The thread should be stopped before yaffs is unmounted.
-+ * The thread should not do any writing while the fs is in read only.
-+ */
-+
-+#ifdef YAFFS_COMPILE_BACKGROUND
-+
-+void yaffs_background_waker(unsigned long data)
-+{
-+	wake_up_process((struct task_struct *)data);
-+}
-+
-+static int yaffs_bg_thread_fn(void *data)
-+{
-+	yaffs_dev_t *dev = (yaffs_dev_t *)data;
-+	struct yaffs_LinuxContext *context = yaffs_dev_to_lc(dev);
-+	unsigned long now = jiffies;
-+	unsigned long next_dir_update = now;
-+	unsigned long next_gc = now;
-+	unsigned long expires;
-+	unsigned int urgency;
-+
-+	int gcResult;
-+	struct timer_list timer;
-+
-+	T(YAFFS_TRACE_BACKGROUND,
-+		(TSTR("yaffs_background starting for dev %p\n"),
-+		(void *)dev));
-+
-+#ifdef YAFFS_COMPILE_FREEZER
-+	set_freezable();
-+#endif
-+	while(context->bgRunning){
-+		T(YAFFS_TRACE_BACKGROUND,
-+			(TSTR("yaffs_background\n")));
-+
-+		if(kthread_should_stop())
-+			break;
-+
-+#ifdef YAFFS_COMPILE_FREEZER
-+		if(try_to_freeze())
-+			continue;
-+#endif
-+		yaffs_gross_lock(dev);
-+
-+		now = jiffies;
-+
-+		if(time_after(now, next_dir_update) && yaffs_bg_enable){
-+			yaffs_update_dirty_dirs(dev);
-+			next_dir_update = now + HZ;
-+		}
-+
-+		if(time_after(now,next_gc) && yaffs_bg_enable){
-+			if(!dev->is_checkpointed){
-+				urgency = yaffs_bg_gc_urgency(dev);
-+				gcResult = yaffs_bg_gc(dev, urgency);
-+				if(urgency > 1)
-+					next_gc = now + HZ/20+1;
-+				else if(urgency > 0)
-+					next_gc = now + HZ/10+1;
-+				else
-+					next_gc = now + HZ * 2;
-+			} else /*
-+				* gc not running so set to next_dir_update
-+				* to cut down on wake ups
-+				*/
-+				next_gc = next_dir_update;
-+		}
-+		yaffs_gross_unlock(dev);
-+#if 1
-+		expires = next_dir_update;
-+		if (time_before(next_gc,expires))
-+			expires = next_gc;
-+		if(time_before(expires,now))
-+			expires = now + HZ;
-+
-+		Y_INIT_TIMER(&timer);
-+		timer.expires = expires+1;
-+		timer.data = (unsigned long) current;
-+		timer.function = yaffs_background_waker;
-+
-+                set_current_state(TASK_INTERRUPTIBLE);
-+		add_timer(&timer);
-+		schedule();
-+		del_timer_sync(&timer);
-+#else
-+		msleep(10);
-+#endif
-+	}
-+
-+	return 0;
-+}
-+
-+static int yaffs_bg_start(yaffs_dev_t *dev)
-+{
-+	int retval = 0;
-+	struct yaffs_LinuxContext *context = yaffs_dev_to_lc(dev);
-+
-+	if(dev->read_only)
-+		return -1;
-+
-+	context->bgRunning = 1;
-+
-+	context->bgThread = kthread_run(yaffs_bg_thread_fn,
-+	                        (void *)dev,"yaffs-bg-%d",context->mount_id);
-+
-+	if(IS_ERR(context->bgThread)){
-+		retval = PTR_ERR(context->bgThread);
-+		context->bgThread = NULL;
-+		context->bgRunning = 0;
-+	}
-+	return retval;
-+}
-+
-+static void yaffs_bg_stop(yaffs_dev_t *dev)
-+{
-+	struct yaffs_LinuxContext *ctxt = yaffs_dev_to_lc(dev);
-+
-+	ctxt->bgRunning = 0;
-+
-+	if( ctxt->bgThread){
-+		kthread_stop(ctxt->bgThread);
-+		ctxt->bgThread = NULL;
-+	}
-+}
-+#else
-+static int yaffs_bg_thread_fn(void *data)
-+{
-+	return 0;
-+}
-+
-+static int yaffs_bg_start(yaffs_dev_t *dev)
-+{
-+	return 0;
-+}
-+
-+static void yaffs_bg_stop(yaffs_dev_t *dev)
-+{
-+}
-+#endif
-+
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static void yaffs_write_super(struct super_block *sb)
-+#else
-+static int yaffs_write_super(struct super_block *sb)
-+#endif
-+{
-+	unsigned request_checkpoint = (yaffs_auto_checkpoint >= 2);
-+
-+	T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC | YAFFS_TRACE_BACKGROUND,
-+		(TSTR("yaffs_write_super%s\n"),
-+		request_checkpoint ? " checkpt" : ""));
-+
-+	yaffs_do_sync_fs(sb, request_checkpoint);
-+
-+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
-+	return 0;
-+#endif
-+}
-+
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static int yaffs_sync_fs(struct super_block *sb, int wait)
-+#else
-+static int yaffs_sync_fs(struct super_block *sb)
-+#endif
-+{
-+	unsigned request_checkpoint = (yaffs_auto_checkpoint >= 1);
-+
-+	T(YAFFS_TRACE_OS | YAFFS_TRACE_SYNC,
-+		(TSTR("yaffs_sync_fs%s\n"),
-+		request_checkpoint ? " checkpt" : ""));
-+
-+	yaffs_do_sync_fs(sb, request_checkpoint);
-+
-+	return 0;
-+}
-+
-+#ifdef YAFFS_USE_OWN_IGET
-+
-+static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino)
-+{
-+	struct inode *inode;
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev = yaffs_SuperToDevice(sb);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_iget for %lu\n"), ino));
-+
-+	inode = iget_locked(sb, ino);
-+	if (!inode)
-+		return ERR_PTR(-ENOMEM);
-+	if (!(inode->i_state & I_NEW))
-+		return inode;
-+
-+	/* NB This is called as a side effect of other functions, but
-+	 * we had to release the lock to prevent deadlocks, so
-+	 * need to lock again.
-+	 */
-+
-+	yaffs_gross_lock(dev);
-+
-+	obj = yaffs_find_by_number(dev, inode->i_ino);
-+
-+	yaffs_fill_inode_from_obj(inode, obj);
-+
-+	yaffs_gross_unlock(dev);
-+
-+	unlock_new_inode(inode);
-+	return inode;
-+}
-+
-+#else
-+
-+static void yaffs_read_inode(struct inode *inode)
-+{
-+	/* NB This is called as a side effect of other functions, but
-+	 * we had to release the lock to prevent deadlocks, so
-+	 * need to lock again.
-+	 */
-+
-+	yaffs_obj_t *obj;
-+	yaffs_dev_t *dev = yaffs_SuperToDevice(inode->i_sb);
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_read_inode for %d\n"), (int)inode->i_ino));
-+
-+	if(current != yaffs_dev_to_lc(dev)->readdirProcess)
-+		yaffs_gross_lock(dev);
-+
-+	obj = yaffs_find_by_number(dev, inode->i_ino);
-+
-+	yaffs_fill_inode_from_obj(inode, obj);
-+
-+	if(current != yaffs_dev_to_lc(dev)->readdirProcess)
-+		yaffs_gross_unlock(dev);
-+}
-+
-+#endif
-+
-+static YLIST_HEAD(yaffs_context_list);
-+struct semaphore yaffs_context_lock;
-+
-+static void yaffs_put_super(struct super_block *sb)
-+{
-+	yaffs_dev_t *dev = yaffs_SuperToDevice(sb);
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_put_super\n")));
-+
-+	T(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
-+		(TSTR("Shutting down yaffs background thread\n")));
-+	yaffs_bg_stop(dev);
-+	T(YAFFS_TRACE_OS | YAFFS_TRACE_BACKGROUND,
-+		(TSTR("yaffs background thread shut down\n")));
-+
-+	yaffs_gross_lock(dev);
-+
-+	yaffs_flush_super(sb,1);
-+
-+	if (yaffs_dev_to_lc(dev)->putSuperFunc)
-+		yaffs_dev_to_lc(dev)->putSuperFunc(sb);
-+
-+
-+	yaffs_deinitialise(dev);
-+
-+	yaffs_gross_unlock(dev);
-+
-+	down(&yaffs_context_lock);
-+	ylist_del_init(&(yaffs_dev_to_lc(dev)->contextList));
-+	up(&yaffs_context_lock);
-+
-+	if (yaffs_dev_to_lc(dev)->spareBuffer) {
-+		YFREE(yaffs_dev_to_lc(dev)->spareBuffer);
-+		yaffs_dev_to_lc(dev)->spareBuffer = NULL;
-+	}
-+
-+	kfree(dev);
-+}
-+
-+
-+static void yaffs_MTDPutSuper(struct super_block *sb)
-+{
-+	struct mtd_info *mtd = yaffs_dev_to_mtd(yaffs_SuperToDevice(sb));
-+
-+	if (mtd->sync)
-+		mtd->sync(mtd);
-+
-+	put_mtd_device(mtd);
-+}
-+
-+
-+static void yaffs_touch_super(yaffs_dev_t *dev)
-+{
-+	struct super_block *sb = yaffs_dev_to_lc(dev)->superBlock;
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_touch_super() sb = %p\n"), sb));
-+	if (sb)
-+		sb->s_dirt = 1;
-+}
-+
-+typedef struct {
-+	int inband_tags;
-+	int skip_checkpoint_read;
-+	int skip_checkpoint_write;
-+	int no_cache;
-+	int tags_ecc_on;
-+	int tags_ecc_overridden;
-+	int lazy_loading_enabled;
-+	int lazy_loading_overridden;
-+	int empty_lost_and_found;
-+	int empty_lost_and_found_overridden;
-+} yaffs_options;
-+
-+#define MAX_OPT_LEN 30
-+static int yaffs_parse_options(yaffs_options *options, const char *options_str)
-+{
-+	char cur_opt[MAX_OPT_LEN + 1];
-+	int p;
-+	int error = 0;
-+
-+	/* Parse through the options which is a comma seperated list */
-+
-+	while (options_str && *options_str && !error) {
-+		memset(cur_opt, 0, MAX_OPT_LEN + 1);
-+		p = 0;
-+
-+		while(*options_str == ',')
-+			options_str++;
-+
-+		while (*options_str && *options_str != ',') {
-+			if (p < MAX_OPT_LEN) {
-+				cur_opt[p] = *options_str;
-+				p++;
-+			}
-+			options_str++;
-+		}
-+
-+		if (!strcmp(cur_opt, "inband-tags"))
-+			options->inband_tags = 1;
-+		else if (!strcmp(cur_opt, "tags-ecc-off")){
-+			options->tags_ecc_on = 0;
-+			options->tags_ecc_overridden=1;
-+		} else if (!strcmp(cur_opt, "tags-ecc-on")){
-+			options->tags_ecc_on = 1;
-+			options->tags_ecc_overridden = 1;
-+		} else if (!strcmp(cur_opt, "lazy-loading-off")){
-+			options->lazy_loading_enabled = 0;
-+			options->lazy_loading_overridden=1;
-+		} else if (!strcmp(cur_opt, "lazy-loading-on")){
-+			options->lazy_loading_enabled = 1;
-+			options->lazy_loading_overridden = 1;
-+		} else if (!strcmp(cur_opt, "empty-lost-and-found-off")){
-+			options->empty_lost_and_found = 0;
-+			options->empty_lost_and_found_overridden=1;
-+		} else if (!strcmp(cur_opt, "empty-lost-and-found-on")){
-+			options->empty_lost_and_found = 1;
-+			options->empty_lost_and_found_overridden=1;
-+		} else if (!strcmp(cur_opt, "no-cache"))
-+			options->no_cache = 1;
-+		else if (!strcmp(cur_opt, "no-checkpoint-read"))
-+			options->skip_checkpoint_read = 1;
-+		else if (!strcmp(cur_opt, "no-checkpoint-write"))
-+			options->skip_checkpoint_write = 1;
-+		else if (!strcmp(cur_opt, "no-checkpoint")) {
-+			options->skip_checkpoint_read = 1;
-+			options->skip_checkpoint_write = 1;
-+		} else {
-+			printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
-+					cur_opt);
-+			error = 1;
-+		}
-+	}
-+
-+	return error;
-+}
-+
-+static struct super_block *yaffs_internal_read_super(int yaffs_version,
-+						struct super_block *sb,
-+						void *data, int silent)
-+{
-+	int nBlocks;
-+	struct inode *inode = NULL;
-+	struct dentry *root;
-+	yaffs_dev_t *dev = 0;
-+	char devname_buf[BDEVNAME_SIZE + 1];
-+	struct mtd_info *mtd;
-+	int err;
-+	char *data_str = (char *)data;
-+	struct yaffs_LinuxContext *context = NULL;
-+	yaffs_param_t *param;
-+
-+	int read_only = 0;
-+
-+	yaffs_options options;
-+
-+	unsigned mount_id;
-+	int found;
-+	struct yaffs_LinuxContext *context_iterator;
-+	struct ylist_head *l;
-+
-+	sb->s_magic = YAFFS_MAGIC;
-+	sb->s_op = &yaffs_super_ops;
-+	sb->s_flags |= MS_NOATIME;
-+
-+	read_only =((sb->s_flags & MS_RDONLY) != 0);
-+
-+
-+#ifdef YAFFS_COMPILE_EXPORTFS
-+	sb->s_export_op = &yaffs_export_ops;
-+#endif
-+
-+	if (!sb)
-+		printk(KERN_INFO "yaffs: sb is NULL\n");
-+	else if (!sb->s_dev)
-+		printk(KERN_INFO "yaffs: sb->s_dev is NULL\n");
-+	else if (!yaffs_devname(sb, devname_buf))
-+		printk(KERN_INFO "yaffs: devname is NULL\n");
-+	else
-+		printk(KERN_INFO "yaffs: dev is %d name is \"%s\" %s\n",
-+		       sb->s_dev,
-+		       yaffs_devname(sb, devname_buf),
-+		       read_only ? "ro" : "rw");
-+
-+	if (!data_str)
-+		data_str = "";
-+
-+	printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
-+
-+	memset(&options, 0, sizeof(options));
-+
-+	if (yaffs_parse_options(&options, data_str)) {
-+		/* Option parsing failed */
-+		return NULL;
-+	}
-+
-+
-+	sb->s_blocksize = PAGE_CACHE_SIZE;
-+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
-+
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_read_super: Using yaffs%d\n"), yaffs_version));
-+	T(YAFFS_TRACE_OS,
-+		(TSTR("yaffs_read_super: block size %d\n"),
-+		(int)(sb->s_blocksize)));
-+
-+	T(YAFFS_TRACE_ALWAYS,
-+		(TSTR("yaffs: Attempting MTD mount of %u.%u,\"%s\"\n"),
-+	       MAJOR(sb->s_dev), MINOR(sb->s_dev),
-+	       yaffs_devname(sb, devname_buf)));
-+
-+	/* Check it's an mtd device..... */
-+	if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR)
-+		return NULL;	/* This isn't an mtd device */
-+
-+	/* Get the device */
-+	mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
-+	if (!mtd) {
-+		T(YAFFS_TRACE_ALWAYS,
-+			(TSTR("yaffs: MTD device #%u doesn't appear to exist\n"),
-+			MINOR(sb->s_dev)));
-+		return NULL;
-+	}
-+	/* Check it's NAND */
-+	if (mtd->type != MTD_NANDFLASH) {
-+		T(YAFFS_TRACE_ALWAYS,
-+			(TSTR("yaffs: MTD device is not NAND it's type %d\n"),
-+			mtd->type));
-+		return NULL;
-+	}
-+
-+	T(YAFFS_TRACE_OS, (TSTR(" erase %p\n"), mtd->erase));
-+	T(YAFFS_TRACE_OS, (TSTR(" read %p\n"), mtd->read));
-+	T(YAFFS_TRACE_OS, (TSTR(" write %p\n"), mtd->write));
-+	T(YAFFS_TRACE_OS, (TSTR(" readoob %p\n"), mtd->read_oob));
-+	T(YAFFS_TRACE_OS, (TSTR(" writeoob %p\n"), mtd->write_oob));
-+	T(YAFFS_TRACE_OS, (TSTR(" block_isbad %p\n"), mtd->block_isbad));
-+	T(YAFFS_TRACE_OS, (TSTR(" block_markbad %p\n"), mtd->block_markbad));
-+	T(YAFFS_TRACE_OS, (TSTR(" %s %d\n"), WRITE_SIZE_STR, WRITE_SIZE(mtd)));
-+	T(YAFFS_TRACE_OS, (TSTR(" oobsize %d\n"), mtd->oobsize));
-+	T(YAFFS_TRACE_OS, (TSTR(" erasesize %d\n"), mtd->erasesize));
-+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
-+	T(YAFFS_TRACE_OS, (TSTR(" size %u\n"), mtd->size));
-+#else
-+	T(YAFFS_TRACE_OS, (TSTR(" size %lld\n"), mtd->size));
-+#endif
-+
-+#ifdef CONFIG_YAFFS_AUTO_YAFFS2
-+
-+	if (yaffs_version == 1 && WRITE_SIZE(mtd) >= 2048) {
-+		T(YAFFS_TRACE_ALWAYS,
-+			(TSTR("yaffs: auto selecting yaffs2\n")));
-+		yaffs_version = 2;
-+	}
-+
-+	/* Added NCB 26/5/2006 for completeness */
-+	if (yaffs_version == 2 && !options.inband_tags && WRITE_SIZE(mtd) == 512) {
-+		T(YAFFS_TRACE_ALWAYS,
-+			(TSTR("yaffs: auto selecting yaffs1\n")));
-+		yaffs_version = 1;
-+	}
-+
-+#endif
-+
-+	if (yaffs_version == 2) {
-+		/* Check for version 2 style functions */
-+		if (!mtd->erase ||
-+		    !mtd->block_isbad ||
-+		    !mtd->block_markbad ||
-+		    !mtd->read ||
-+		    !mtd->write ||
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+		    !mtd->read_oob || !mtd->write_oob) {
-+#else
-+		    !mtd->write_ecc ||
-+		    !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {
-+#endif
-+			T(YAFFS_TRACE_ALWAYS,
-+			  (TSTR("yaffs: MTD device does not support required "
-+			   "functions\n")));
-+			return NULL;
-+		}
-+
-+		if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
-+		    mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&
-+		    !options.inband_tags) {
-+			T(YAFFS_TRACE_ALWAYS,
-+			  (TSTR("yaffs: MTD device does not have the "
-+			   "right page sizes\n")));
-+			return NULL;
-+		}
-+	} else {
-+		/* Check for V1 style functions */
-+		if (!mtd->erase ||
-+		    !mtd->read ||
-+		    !mtd->write ||
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+		    !mtd->read_oob || !mtd->write_oob) {
-+#else
-+		    !mtd->write_ecc ||
-+		    !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) {
-+#endif
-+			T(YAFFS_TRACE_ALWAYS,
-+			  (TSTR("yaffs: MTD device does not support required "
-+			   "functions\n")));
-+			return NULL;
-+		}
-+
-+		if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK ||
-+		    mtd->oobsize != YAFFS_BYTES_PER_SPARE) {
-+			T(YAFFS_TRACE_ALWAYS,
-+			  (TSTR("yaffs: MTD device does not support have the "
-+			   "right page sizes\n")));
-+			return NULL;
-+		}
-+	}
-+
-+	/* OK, so if we got here, we have an MTD that's NAND and looks
-+	 * like it has the right capabilities
-+	 * Set the yaffs_dev_t up for mtd
-+	 */
-+
-+	if (!read_only && !(mtd->flags & MTD_WRITEABLE)){
-+		read_only = 1;
-+		printk(KERN_INFO "yaffs: mtd is read only, setting superblock read only");
-+		sb->s_flags |= MS_RDONLY;
-+	}
-+
-+	dev = kmalloc(sizeof(yaffs_dev_t), GFP_KERNEL);
-+	context = kmalloc(sizeof(struct yaffs_LinuxContext),GFP_KERNEL);
-+	
-+	if(!dev || !context ){
-+		if(dev)
-+			kfree(dev);
-+		if(context)
-+			kfree(context);
-+		dev = NULL;
-+		context = NULL;
-+	}
-+
-+	if (!dev) {
-+		/* Deep shit could not allocate device structure */
-+		T(YAFFS_TRACE_ALWAYS,
-+		  (TSTR("yaffs_read_super: Failed trying to allocate "
-+		   "yaffs_dev_t. \n")));
-+		return NULL;
-+	}
-+	memset(dev, 0, sizeof(yaffs_dev_t));
-+	param = &(dev->param);
-+
-+	memset(context,0,sizeof(struct yaffs_LinuxContext));
-+	dev->os_context = context;
-+	YINIT_LIST_HEAD(&(context->contextList));
-+	context->dev = dev;
-+	context->superBlock = sb;
-+
-+	dev->read_only = read_only;
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+	sb->s_fs_info = dev;
-+#else
-+	sb->u.generic_sbp = dev;
-+#endif
-+	
-+	dev->driver_context = mtd;
-+	param->name = mtd->name;
-+
-+	/* Set up the memory size parameters.... */
-+
-+	nBlocks = YCALCBLOCKS(mtd->size, (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK));
-+
-+	param->start_block = 0;
-+	param->end_block = nBlocks - 1;
-+	param->chunks_per_block = YAFFS_CHUNKS_PER_BLOCK;
-+	param->total_bytes_per_chunk = YAFFS_BYTES_PER_CHUNK;
-+	param->n_reserved_blocks = 5;
-+	param->n_caches = (options.no_cache) ? 0 : 10;
-+	param->inband_tags = options.inband_tags;
-+
-+#ifdef CONFIG_YAFFS_DISABLE_LAZY_LOAD
-+	param->disable_lazy_load = 1;
-+#endif
-+#ifdef CONFIG_YAFFS_XATTR
-+	param->enable_xattr = 1;
-+#endif
-+	if(options.lazy_loading_overridden)
-+		param->disable_lazy_load = !options.lazy_loading_enabled;
-+
-+#ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC
-+	param->no_tags_ecc = 1;
-+#endif
-+
-+#ifdef CONFIG_YAFFS_DISABLE_BACKGROUND
-+#else
-+	param->defered_dir_update = 1;
-+#endif
-+
-+	if(options.tags_ecc_overridden)
-+		param->no_tags_ecc = !options.tags_ecc_on;
-+
-+#ifdef CONFIG_YAFFS_EMPTY_LOST_AND_FOUND
-+	param->empty_lost_n_found = 1;
-+#endif
-+
-+#ifdef CONFIG_YAFFS_DISABLE_BLOCK_REFRESHING
-+	param->refresh_period = 0;
-+#else
-+	param->refresh_period = 500;
-+#endif
-+
-+#ifdef CONFIG_YAFFS__ALWAYS_CHECK_CHUNK_ERASED
-+	param->always_check_erased = 1;
-+#endif
-+
-+	if(options.empty_lost_and_found_overridden)
-+		param->empty_lost_n_found = options.empty_lost_and_found;
-+
-+	/* ... and the functions. */
-+	if (yaffs_version == 2) {
-+		param->write_chunk_tags_fn =
-+		    nandmtd2_WriteChunkWithTagsToNAND;
-+		param->read_chunk_tags_fn =
-+		    nandmtd2_ReadChunkWithTagsFromNAND;
-+		param->bad_block_fn = nandmtd2_MarkNANDBlockBad;
-+		param->query_block_fn = nandmtd2_QueryNANDBlock;
-+		yaffs_dev_to_lc(dev)->spareBuffer = YMALLOC(mtd->oobsize);
-+		param->is_yaffs2 = 1;
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+		param->total_bytes_per_chunk = mtd->writesize;
-+		param->chunks_per_block = mtd->erasesize / mtd->writesize;
-+#else
-+		param->total_bytes_per_chunk = mtd->oobblock;
-+		param->chunks_per_block = mtd->erasesize / mtd->oobblock;
-+#endif
-+		nBlocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
-+
-+		param->start_block = 0;
-+		param->end_block = nBlocks - 1;
-+	} else {
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+		/* use the MTD interface in yaffs_mtdif1.c */
-+		param->write_chunk_tags_fn =
-+			nandmtd1_WriteChunkWithTagsToNAND;
-+		param->read_chunk_tags_fn =
-+			nandmtd1_ReadChunkWithTagsFromNAND;
-+		param->bad_block_fn = nandmtd1_MarkNANDBlockBad;
-+		param->query_block_fn = nandmtd1_QueryNANDBlock;
-+#else
-+		param->write_chunk_fn = nandmtd_WriteChunkToNAND;
-+		param->read_chunk_fn = nandmtd_ReadChunkFromNAND;
-+#endif
-+		param->is_yaffs2 = 0;
-+	}
-+	/* ... and common functions */
-+	param->erase_fn = nandmtd_EraseBlockInNAND;
-+	param->initialise_flash_fn = nandmtd_InitialiseNAND;
-+
-+	yaffs_dev_to_lc(dev)->putSuperFunc = yaffs_MTDPutSuper;
-+
-+	param->sb_dirty_fn = yaffs_touch_super;
-+	param->gc_control = yaffs_gc_control_callback;
-+
-+	yaffs_dev_to_lc(dev)->superBlock= sb;
-+	
-+
-+#ifndef CONFIG_YAFFS_DOES_ECC
-+	param->use_nand_ecc = 1;
-+#endif
-+
-+#ifdef CONFIG_YAFFS_DISABLE_WIDE_TNODES
-+	param->wide_tnodes_disabled = 1;
-+#endif
-+
-+	param->skip_checkpt_rd = options.skip_checkpoint_read;
-+	param->skip_checkpt_wr = options.skip_checkpoint_write;
-+
-+	down(&yaffs_context_lock);
-+	/* Get a mount id */
-+	found = 0;
-+	for(mount_id=0; ! found; mount_id++){
-+		found = 1;
-+		ylist_for_each(l,&yaffs_context_list){
-+			context_iterator = ylist_entry(l,struct yaffs_LinuxContext,contextList);
-+			if(context_iterator->mount_id == mount_id)
-+				found = 0;
-+		}
-+	}
-+	context->mount_id = mount_id;
-+
-+	ylist_add_tail(&(yaffs_dev_to_lc(dev)->contextList), &yaffs_context_list);
-+	up(&yaffs_context_lock);
-+
-+        /* Directory search handling...*/
-+        YINIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->searchContexts));
-+        param->remove_obj_fn = yaffs_remove_obj_callback;
-+
-+	init_MUTEX(&(yaffs_dev_to_lc(dev)->grossLock));
-+
-+	yaffs_gross_lock(dev);
-+
-+	err = yaffs_guts_initialise(dev);
-+
-+	T(YAFFS_TRACE_OS,
-+	  (TSTR("yaffs_read_super: guts initialised %s\n"),
-+	   (err == YAFFS_OK) ? "OK" : "FAILED"));
-+	   
-+	if(err == YAFFS_OK)
-+		yaffs_bg_start(dev);
-+		
-+	if(!context->bgThread)
-+		param->defered_dir_update = 0;
-+
-+
-+	/* Release lock before yaffs_get_inode() */
-+	yaffs_gross_unlock(dev);
-+
-+	/* Create root inode */
-+	if (err == YAFFS_OK)
-+		inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0,
-+					yaffs_root(dev));
-+
-+	if (!inode)
-+		return NULL;
-+
-+	inode->i_op = &yaffs_dir_inode_operations;
-+	inode->i_fop = &yaffs_dir_operations;
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_read_super: got root inode\n")));
-+
-+	root = d_alloc_root(inode);
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_read_super: d_alloc_root done\n")));
-+
-+	if (!root) {
-+		iput(inode);
-+		return NULL;
-+	}
-+	sb->s_root = root;
-+	sb->s_dirt = !dev->is_checkpointed;
-+	T(YAFFS_TRACE_ALWAYS,
-+		(TSTR("yaffs_read_super: is_checkpointed %d\n"),
-+		dev->is_checkpointed));
-+
-+	T(YAFFS_TRACE_OS, (TSTR("yaffs_read_super: done\n")));
-+	return sb;
-+}
-+
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
-+					 int silent)
-+{
-+	return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
-+}
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static int yaffs_read_super(struct file_system_type *fs,
-+			    int flags, const char *dev_name,
-+			    void *data, struct vfsmount *mnt)
-+{
-+
-+	return get_sb_bdev(fs, flags, dev_name, data,
-+			   yaffs_internal_read_super_mtd, mnt);
-+}
-+#else
-+static struct super_block *yaffs_read_super(struct file_system_type *fs,
-+					    int flags, const char *dev_name,
-+					    void *data)
-+{
-+
-+	return get_sb_bdev(fs, flags, dev_name, data,
-+			   yaffs_internal_read_super_mtd);
-+}
-+#endif
-+
-+static struct file_system_type yaffs_fs_type = {
-+	.owner = THIS_MODULE,
-+	.name = "yaffs",
-+	.get_sb = yaffs_read_super,
-+	.kill_sb = kill_block_super,
-+	.fs_flags = FS_REQUIRES_DEV,
-+};
-+#else
-+static struct super_block *yaffs_read_super(struct super_block *sb, void *data,
-+					    int silent)
-+{
-+	return yaffs_internal_read_super(1, sb, data, silent);
-+}
-+
-+static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super,
-+		      FS_REQUIRES_DEV);
-+#endif
-+
-+
-+#ifdef CONFIG_YAFFS_YAFFS2
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
-+static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
-+					  int silent)
-+{
-+	return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
-+}
-+
-+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
-+static int yaffs2_read_super(struct file_system_type *fs,
-+			int flags, const char *dev_name, void *data,
-+			struct vfsmount *mnt)
-+{
-+	return get_sb_bdev(fs, flags, dev_name, data,
-+			yaffs2_internal_read_super_mtd, mnt);
-+}
-+#else
-+static struct super_block *yaffs2_read_super(struct file_system_type *fs,
-+					     int flags, const char *dev_name,
-+					     void *data)
-+{
-+
-+	return get_sb_bdev(fs, flags, dev_name, data,
-+			   yaffs2_internal_read_super_mtd);
-+}
-+#endif
-+
-+static struct file_system_type yaffs2_fs_type = {
-+	.owner = THIS_MODULE,
-+	.name = "yaffs2",
-+	.get_sb = yaffs2_read_super,
-+	.kill_sb = kill_block_super,
-+	.fs_flags = FS_REQUIRES_DEV,
-+};
-+#else
-+static struct super_block *yaffs2_read_super(struct super_block *sb,
-+					     void *data, int silent)
-+{
-+	return yaffs_internal_read_super(2, sb, data, silent);
-+}
-+
-+static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super,
-+		      FS_REQUIRES_DEV);
-+#endif
-+
-+#endif				/* CONFIG_YAFFS_YAFFS2 */
-+
-+static struct proc_dir_entry *my_proc_entry;
-+static struct proc_dir_entry *debug_proc_entry;
-+
-+static char *yaffs_dump_dev_part0(char *buf, yaffs_dev_t * dev)
-+{
-+	buf += sprintf(buf, "start_block.......... %d\n", dev->param.start_block);
-+	buf += sprintf(buf, "end_block............ %d\n", dev->param.end_block);
-+	buf += sprintf(buf, "total_bytes_per_chunk %d\n", dev->param.total_bytes_per_chunk);
-+	buf += sprintf(buf, "use_nand_ecc......... %d\n", dev->param.use_nand_ecc);
-+	buf += sprintf(buf, "no_tags_ecc.......... %d\n", dev->param.no_tags_ecc);
-+	buf += sprintf(buf, "is_yaffs2............ %d\n", dev->param.is_yaffs2);
-+	buf += sprintf(buf, "inband_tags.......... %d\n", dev->param.inband_tags);
-+	buf += sprintf(buf, "empty_lost_n_found... %d\n", dev->param.empty_lost_n_found);
-+	buf += sprintf(buf, "disable_lazy_load.... %d\n", dev->param.disable_lazy_load);
-+	buf += sprintf(buf, "refresh_period....... %d\n", dev->param.refresh_period);
-+	buf += sprintf(buf, "n_caches............. %d\n", dev->param.n_caches);
-+	buf += sprintf(buf, "n_reserved_blocks.... %d\n", dev->param.n_reserved_blocks);
-+	buf += sprintf(buf, "always_check_erased.. %d\n", dev->param.always_check_erased);
-+
-+	buf += sprintf(buf, "\n");
-+
-+	return buf;
-+}
-+
-+
-+static char *yaffs_dump_dev_part1(char *buf, yaffs_dev_t * dev)
-+{
-+	buf += sprintf(buf, "data_bytes_per_chunk. %d\n", dev->data_bytes_per_chunk);
-+	buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);
-+	buf += sprintf(buf, "chunk_grp_size....... %d\n", dev->chunk_grp_size);
-+	buf += sprintf(buf, "n_erased_blocks...... %d\n", dev->n_erased_blocks);
-+	buf += sprintf(buf, "blocks_in_checkpt.... %d\n", dev->blocks_in_checkpt);
-+	buf += sprintf(buf, "\n");
-+	buf += sprintf(buf, "n_tnodes............. %d\n", dev->n_tnodes);
-+	buf += sprintf(buf, "n_obj................ %d\n", dev->n_obj);
-+	buf += sprintf(buf, "n_free_chunks........ %d\n", dev->n_free_chunks);
-+	buf += sprintf(buf, "\n");
-+	buf += sprintf(buf, "n_page_writes........ %u\n", dev->n_page_writes);
-+	buf += sprintf(buf, "n_page_reads......... %u\n", dev->n_page_reads);
-+	buf += sprintf(buf, "n_erasures........... %u\n", dev->n_erasures);
-+	buf += sprintf(buf, "n_gc_copies.......... %u\n", dev->n_gc_copies);
-+	buf += sprintf(buf, "all_gcs.............. %u\n", dev->all_gcs);
-+	buf += sprintf(buf, "passive_gc_count..... %u\n", dev->passive_gc_count);
-+	buf += sprintf(buf, "oldest_dirty_gc_count %u\n", dev->oldest_dirty_gc_count);
-+	buf += sprintf(buf, "n_gc_blocks.......... %u\n", dev->n_gc_blocks);
-+	buf += sprintf(buf, "bg_gcs............... %u\n", dev->bg_gcs);
-+	buf += sprintf(buf, "n_retired_writes..... %u\n", dev->n_retired_writes);
-+	buf += sprintf(buf, "nRetireBlocks........ %u\n", dev->n_retired_blocks);
-+	buf += sprintf(buf, "n_ecc_fixed.......... %u\n", dev->n_ecc_fixed);
-+	buf += sprintf(buf, "n_ecc_unfixed........ %u\n", dev->n_ecc_unfixed);
-+	buf += sprintf(buf, "n_tags_ecc_fixed..... %u\n", dev->n_tags_ecc_fixed);
-+	buf += sprintf(buf, "n_tags_ecc_unfixed... %u\n", dev->n_tags_ecc_unfixed);
-+	buf += sprintf(buf, "cache_hits........... %u\n", dev->cache_hits);
-+	buf += sprintf(buf, "n_deleted_files...... %u\n", dev->n_deleted_files);
-+	buf += sprintf(buf, "n_unlinked_files..... %u\n", dev->n_unlinked_files);
-+	buf += sprintf(buf, "refresh_count........ %u\n", dev->refresh_count);
-+	buf += sprintf(buf, "n_bg_deletions....... %u\n", dev->n_bg_deletions);
-+
-+	return buf;
-+}
-+
-+static int yaffs_proc_read(char *page,
-+			   char **start,
-+			   off_t offset, int count, int *eof, void *data)
-+{
-+	struct ylist_head *item;
-+	char *buf = page;
-+	int step = offset;
-+	int n = 0;
-+
-+	/* Get proc_file_read() to step 'offset' by one on each sucessive call.
-+	 * We use 'offset' (*ppos) to indicate where we are in dev_list.
-+	 * This also assumes the user has posted a read buffer large
-+	 * enough to hold the complete output; but that's life in /proc.
-+	 */
-+
-+	*(int *)start = 1;
-+
-+	/* Print header first */
-+	if (step == 0)
-+		buf += sprintf(buf, "Multi-version YAFFS built:" __DATE__ " " __TIME__"\n");
-+	else if (step == 1)
-+		buf += sprintf(buf,"\n");
-+	else {
-+		step-=2;
-+		
-+		down(&yaffs_context_lock);
-+
-+		/* Locate and print the Nth entry.  Order N-squared but N is small. */
-+		ylist_for_each(item, &yaffs_context_list) {
-+			struct yaffs_LinuxContext *dc = ylist_entry(item, struct yaffs_LinuxContext, contextList);
-+			yaffs_dev_t *dev = dc->dev;
-+
-+			if (n < (step & ~1)) {
-+				n+=2;
-+				continue;
-+			}
-+			if((step & 1)==0){
-+				buf += sprintf(buf, "\nDevice %d \"%s\"\n", n, dev->param.name);
-+				buf = yaffs_dump_dev_part0(buf, dev);
-+			} else
-+				buf = yaffs_dump_dev_part1(buf, dev);
-+			
-+			break;
-+		}
-+		up(&yaffs_context_lock);
-+	}
-+
-+	return buf - page < count ? buf - page : count;
-+}
-+
-+static int yaffs_stats_proc_read(char *page,
-+				char **start,
-+				off_t offset, int count, int *eof, void *data)
-+{
-+	struct ylist_head *item;
-+	char *buf = page;
-+	int n = 0;
-+
-+	down(&yaffs_context_lock);
-+
-+	/* Locate and print the Nth entry.  Order N-squared but N is small. */
-+	ylist_for_each(item, &yaffs_context_list) {
-+		struct yaffs_LinuxContext *dc = ylist_entry(item, struct yaffs_LinuxContext, contextList);
-+		yaffs_dev_t *dev = dc->dev;
-+
-+		int erasedChunks;
-+
-+		erasedChunks = dev->n_erased_blocks * dev->param.chunks_per_block;
-+		
-+		buf += sprintf(buf,"%d, %d, %d, %u, %u, %u, %u\n",
-+				n, dev->n_free_chunks, erasedChunks,
-+				dev->bg_gcs, dev->oldest_dirty_gc_count,
-+				dev->n_obj, dev->n_tnodes);
-+	}
-+	up(&yaffs_context_lock);
-+
-+
-+	return buf - page < count ? buf - page : count;
-+}
-+
-+/**
-+ * Set the verbosity of the warnings and error messages.
-+ *
-+ * Note that the names can only be a..z or _ with the current code.
-+ */
-+
-+static struct {
-+	char *mask_name;
-+	unsigned mask_bitfield;
-+} mask_flags[] = {
-+	{"allocate", YAFFS_TRACE_ALLOCATE},
-+	{"always", YAFFS_TRACE_ALWAYS},
-+	{"background", YAFFS_TRACE_BACKGROUND},
-+	{"bad_blocks", YAFFS_TRACE_BAD_BLOCKS},
-+	{"buffers", YAFFS_TRACE_BUFFERS},
-+	{"bug", YAFFS_TRACE_BUG},
-+	{"checkpt", YAFFS_TRACE_CHECKPOINT},
-+	{"deletion", YAFFS_TRACE_DELETION},
-+	{"erase", YAFFS_TRACE_ERASE},
-+	{"error", YAFFS_TRACE_ERROR},
-+	{"gc_detail", YAFFS_TRACE_GC_DETAIL},
-+	{"gc", YAFFS_TRACE_GC},
-+	{"lock", YAFFS_TRACE_LOCK},
-+	{"mtd", YAFFS_TRACE_MTD},
-+	{"nandaccess", YAFFS_TRACE_NANDACCESS},
-+	{"os", YAFFS_TRACE_OS},
-+	{"scan_debug", YAFFS_TRACE_SCAN_DEBUG},
-+	{"scan", YAFFS_TRACE_SCAN},
-+	{"tracing", YAFFS_TRACE_TRACING},
-+	{"sync", YAFFS_TRACE_SYNC},
-+	{"write", YAFFS_TRACE_WRITE},
-+
-+	{"verify", YAFFS_TRACE_VERIFY},
-+	{"verify_nand", YAFFS_TRACE_VERIFY_NAND},
-+	{"verify_full", YAFFS_TRACE_VERIFY_FULL},
-+	{"verify_all", YAFFS_TRACE_VERIFY_ALL},
-+
-+	{"all", 0xffffffff},
-+	{"none", 0},
-+	{NULL, 0},
-+};
-+
-+#define MAX_MASK_NAME_LENGTH 40
-+static int yaffs_proc_write_trace_options(struct file *file, const char *buf,
-+					 unsigned long count, void *data)
-+{
-+	unsigned rg = 0, mask_bitfield;
-+	char *end;
-+	char *mask_name;
-+	const char *x;
-+	char substring[MAX_MASK_NAME_LENGTH + 1];
-+	int i;
-+	int done = 0;
-+	int add, len = 0;
-+	int pos = 0;
-+
-+	rg = yaffs_trace_mask;
-+
-+	while (!done && (pos < count)) {
-+		done = 1;
-+		while ((pos < count) && isspace(buf[pos]))
-+			pos++;
-+
-+		switch (buf[pos]) {
-+		case '+':
-+		case '-':
-+		case '=':
-+			add = buf[pos];
-+			pos++;
-+			break;
-+
-+		default:
-+			add = ' ';
-+			break;
-+		}
-+		mask_name = NULL;
-+
-+		mask_bitfield = simple_strtoul(buf + pos, &end, 0);
-+
-+		if (end > buf + pos) {
-+			mask_name = "numeral";
-+			len = end - (buf + pos);
-+			pos += len;
-+			done = 0;
-+		} else {
-+			for (x = buf + pos, i = 0;
-+			    (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
-+			    i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
-+				substring[i] = *x;
-+			substring[i] = '\0';
-+
-+			for (i = 0; mask_flags[i].mask_name != NULL; i++) {
-+				if (strcmp(substring, mask_flags[i].mask_name) == 0) {
-+					mask_name = mask_flags[i].mask_name;
-+					mask_bitfield = mask_flags[i].mask_bitfield;
-+					done = 0;
-+					break;
-+				}
-+			}
-+		}
-+
-+		if (mask_name != NULL) {
-+			done = 0;
-+			switch (add) {
-+			case '-':
-+				rg &= ~mask_bitfield;
-+				break;
-+			case '+':
-+				rg |= mask_bitfield;
-+				break;
-+			case '=':
-+				rg = mask_bitfield;
-+				break;
-+			default:
-+				rg |= mask_bitfield;
-+				break;
-+			}
-+		}
-+	}
-+
-+	yaffs_trace_mask = rg | YAFFS_TRACE_ALWAYS;
-+
-+	printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_trace_mask);
-+
-+	if (rg & YAFFS_TRACE_ALWAYS) {
-+		for (i = 0; mask_flags[i].mask_name != NULL; i++) {
-+			char flag;
-+			flag = ((rg & mask_flags[i].mask_bitfield) ==
-+				mask_flags[i].mask_bitfield) ? '+' : '-';
-+			printk(KERN_DEBUG "%c%s\n", flag, mask_flags[i].mask_name);
-+		}
-+	}
-+
-+	return count;
-+}
-+
-+
-+static int yaffs_proc_write(struct file *file, const char *buf,
-+					 unsigned long count, void *data)
-+{
-+        return yaffs_proc_write_trace_options(file, buf, count, data);
-+}
-+
-+/* Stuff to handle installation of file systems */
-+struct file_system_to_install {
-+	struct file_system_type *fst;
-+	int installed;
-+};
-+
-+static struct file_system_to_install fs_to_install[] = {
-+	{&yaffs_fs_type, 0},
-+	{&yaffs2_fs_type, 0},
-+	{NULL, 0}
-+};
-+
-+static int __init init_yaffs_fs(void)
-+{
-+	int error = 0;
-+	struct file_system_to_install *fsinst;
-+
-+	T(YAFFS_TRACE_ALWAYS,
-+	  (TSTR("yaffs built " __DATE__ " " __TIME__ " Installing. \n")));
-+
-+#ifdef CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED
-+	T(YAFFS_TRACE_ALWAYS,
-+	  (TSTR(" \n\n\n\nYAFFS-WARNING CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED selected.\n\n\n\n")));
-+#endif
-+
-+
-+
-+
-+	init_MUTEX(&yaffs_context_lock);
-+
-+	/* Install the proc_fs entries */
-+	my_proc_entry = create_proc_entry("yaffs",
-+					       S_IRUGO | S_IFREG,
-+					       YPROC_ROOT);
-+
-+	if (my_proc_entry) {
-+		my_proc_entry->write_proc = yaffs_proc_write;
-+		my_proc_entry->read_proc = yaffs_proc_read;
-+		my_proc_entry->data = NULL;
-+	} else
-+		return -ENOMEM;
-+
-+	debug_proc_entry = create_proc_entry("yaffs_stats",
-+					       S_IRUGO | S_IFREG,
-+					       YPROC_ROOT);
-+
-+	if (debug_proc_entry) {
-+		debug_proc_entry->write_proc = NULL;
-+		debug_proc_entry->read_proc = yaffs_stats_proc_read;
-+		debug_proc_entry->data = NULL;
-+	} else
-+		return -ENOMEM;
-+
-+	/* Now add the file system entries */
-+
-+	fsinst = fs_to_install;
-+
-+	while (fsinst->fst && !error) {
-+		error = register_filesystem(fsinst->fst);
-+		if (!error)
-+			fsinst->installed = 1;
-+		fsinst++;
-+	}
-+
-+	/* Any errors? uninstall  */
-+	if (error) {
-+		fsinst = fs_to_install;
-+
-+		while (fsinst->fst) {
-+			if (fsinst->installed) {
-+				unregister_filesystem(fsinst->fst);
-+				fsinst->installed = 0;
-+			}
-+			fsinst++;
-+		}
-+	}
-+
-+	return error;
-+}
-+
-+static void __exit exit_yaffs_fs(void)
-+{
-+
-+	struct file_system_to_install *fsinst;
-+
-+	T(YAFFS_TRACE_ALWAYS,
-+		(TSTR("yaffs built " __DATE__ " " __TIME__ " removing. \n")));
-+
-+	remove_proc_entry("yaffs", YPROC_ROOT);
-+	remove_proc_entry("yaffs_stats", YPROC_ROOT);
-+
-+	fsinst = fs_to_install;
-+
-+	while (fsinst->fst) {
-+		if (fsinst->installed) {
-+			unregister_filesystem(fsinst->fst);
-+			fsinst->installed = 0;
-+		}
-+		fsinst++;
-+	}
-+}
-+
-+module_init(init_yaffs_fs)
-+module_exit(exit_yaffs_fs)
-+
-+MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
-+MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2010");
-+MODULE_LICENSE("GPL");
---- /dev/null
-+++ b/fs/yaffs2/yaffs_yaffs1.c
-@@ -0,0 +1,465 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#include "yaffs_yaffs1.h"
-+#include "yportenv.h"
-+#include "yaffs_trace.h"
-+#include "yaffs_bitmap.h"
-+#include "yaffs_getblockinfo.h"
-+#include "yaffs_nand.h"
-+
-+
-+int yaffs1_scan(yaffs_dev_t *dev)
-+{
-+	yaffs_ext_tags tags;
-+	int blk;
-+	int blockIterator;
-+	int startIterator;
-+	int endIterator;
-+	int result;
-+
-+	int chunk;
-+	int c;
-+	int deleted;
-+	yaffs_block_state_t state;
-+	yaffs_obj_t *hard_list = NULL;
-+	yaffs_block_info_t *bi;
-+	__u32 seq_number;
-+	yaffs_obj_header *oh;
-+	yaffs_obj_t *in;
-+	yaffs_obj_t *parent;
-+
-+	int alloc_failed = 0;
-+
-+	struct yaffs_shadow_fixer_s *shadowFixerList = NULL;
-+
-+
-+	__u8 *chunkData;
-+
-+
-+
-+	T(YAFFS_TRACE_SCAN,
-+	  (TSTR("yaffs1_scan starts  intstartblk %d intendblk %d..." TENDSTR),
-+	   dev->internal_start_block, dev->internal_end_block));
-+
-+	chunkData = yaffs_get_temp_buffer(dev, __LINE__);
-+
-+	dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;
-+
-+	/* Scan all the blocks to determine their state */
-+	bi = dev->block_info;
-+	for (blk = dev->internal_start_block; blk <= dev->internal_end_block; blk++) {
-+		yaffs_clear_chunk_bits(dev, blk);
-+		bi->pages_in_use = 0;
-+		bi->soft_del_pages = 0;
-+
-+		yaffs_query_init_block_state(dev, blk, &state, &seq_number);
-+
-+		bi->block_state = state;
-+		bi->seq_number = seq_number;
-+
-+		if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
-+			bi->block_state = state = YAFFS_BLOCK_STATE_DEAD;
-+
-+		T(YAFFS_TRACE_SCAN_DEBUG,
-+		  (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
-+		   state, seq_number));
-+
-+		if (state == YAFFS_BLOCK_STATE_DEAD) {
-+			T(YAFFS_TRACE_BAD_BLOCKS,
-+			  (TSTR("block %d is bad" TENDSTR), blk));
-+		} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
-+			T(YAFFS_TRACE_SCAN_DEBUG,
-+			  (TSTR("Block empty " TENDSTR)));
-+			dev->n_erased_blocks++;
-+			dev->n_free_chunks += dev->param.chunks_per_block;
-+		}
-+		bi++;
-+	}
-+
-+	startIterator = dev->internal_start_block;
-+	endIterator = dev->internal_end_block;
-+
-+	/* For each block.... */
-+	for (blockIterator = startIterator; !alloc_failed && blockIterator <= endIterator;
-+	     blockIterator++) {
-+
-+		YYIELD();
-+
-+		YYIELD();
-+
-+		blk = blockIterator;
-+
-+		bi = yaffs_get_block_info(dev, blk);
-+		state = bi->block_state;
-+
-+		deleted = 0;
-+
-+		/* For each chunk in each block that needs scanning....*/
-+		for (c = 0; !alloc_failed && c < dev->param.chunks_per_block &&
-+		     state == YAFFS_BLOCK_STATE_NEEDS_SCANNING; c++) {
-+			/* Read the tags and decide what to do */
-+			chunk = blk * dev->param.chunks_per_block + c;
-+
-+			result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL,
-+							&tags);
-+
-+			/* Let's have a good look at this chunk... */
-+
-+			if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED || tags.is_deleted) {
-+				/* YAFFS1 only...
-+				 * A deleted chunk
-+				 */
-+				deleted++;
-+				dev->n_free_chunks++;
-+				/*T((" %d %d deleted\n",blk,c)); */
-+			} else if (!tags.chunk_used) {
-+				/* An unassigned chunk in the block
-+				 * This means that either the block is empty or
-+				 * this is the one being allocated from
-+				 */
-+
-+				if (c == 0) {
-+					/* We're looking at the first chunk in the block so the block is unused */
-+					state = YAFFS_BLOCK_STATE_EMPTY;
-+					dev->n_erased_blocks++;
-+				} else {
-+					/* this is the block being allocated from */
-+					T(YAFFS_TRACE_SCAN,
-+					  (TSTR
-+					   (" Allocating from %d %d" TENDSTR),
-+					   blk, c));
-+					state = YAFFS_BLOCK_STATE_ALLOCATING;
-+					dev->alloc_block = blk;
-+					dev->alloc_page = c;
-+					dev->alloc_block_finder = blk;
-+					/* Set block finder here to encourage the allocator to go forth from here. */
-+
-+				}
-+
-+				dev->n_free_chunks += (dev->param.chunks_per_block - c);
-+			} else if (tags.chunk_id > 0) {
-+				/* chunk_id > 0 so it is a data chunk... */
-+				unsigned int endpos;
-+
-+				yaffs_set_chunk_bit(dev, blk, c);
-+				bi->pages_in_use++;
-+
-+				in = yaffs_find_or_create_by_number(dev,
-+								      tags.
-+								      obj_id,
-+								      YAFFS_OBJECT_TYPE_FILE);
-+				/* PutChunkIntoFile checks for a clash (two data chunks with
-+				 * the same chunk_id).
-+				 */
-+
-+				if (!in)
-+					alloc_failed = 1;
-+
-+				if (in) {
-+					if (!yaffs_put_chunk_in_file(in, tags.chunk_id, chunk, 1))
-+						alloc_failed = 1;
-+				}
-+
-+				endpos =
-+				    (tags.chunk_id - 1) * dev->data_bytes_per_chunk +
-+				    tags.n_bytes;
-+				if (in &&
-+				    in->variant_type == YAFFS_OBJECT_TYPE_FILE
-+				    && in->variant.file_variant.scanned_size <
-+				    endpos) {
-+					in->variant.file_variant.
-+					    scanned_size = endpos;
-+					if (!dev->param.use_header_file_size) {
-+						in->variant.file_variant.
-+						    file_size =
-+						    in->variant.file_variant.
-+						    scanned_size;
-+					}
-+
-+				}
-+				/* T((" %d %d data %d %d\n",blk,c,tags.obj_id,tags.chunk_id));   */
-+			} else {
-+				/* chunk_id == 0, so it is an ObjectHeader.
-+				 * Thus, we read in the object header and make the object
-+				 */
-+				yaffs_set_chunk_bit(dev, blk, c);
-+				bi->pages_in_use++;
-+
-+				result = yaffs_rd_chunk_tags_nand(dev, chunk,
-+								chunkData,
-+								NULL);
-+
-+				oh = (yaffs_obj_header *) chunkData;
-+
-+				in = yaffs_find_by_number(dev,
-+							      tags.obj_id);
-+				if (in && in->variant_type != oh->type) {
-+					/* This should not happen, but somehow
-+					 * Wev'e ended up with an obj_id that has been reused but not yet
-+					 * deleted, and worse still it has changed type. Delete the old object.
-+					 */
-+
-+					yaffs_del_obj(in);
-+
-+					in = 0;
-+				}
-+
-+				in = yaffs_find_or_create_by_number(dev,
-+								      tags.
-+								      obj_id,
-+								      oh->type);
-+
-+				if (!in)
-+					alloc_failed = 1;
-+
-+				if (in && oh->shadows_obj > 0) {
-+
-+					struct yaffs_shadow_fixer_s *fixer;
-+					fixer = YMALLOC(sizeof(struct yaffs_shadow_fixer_s));
-+					if (fixer) {
-+						fixer->next = shadowFixerList;
-+						shadowFixerList = fixer;
-+						fixer->obj_id = tags.obj_id;
-+						fixer->shadowed_id = oh->shadows_obj;
-+						T(YAFFS_TRACE_SCAN,
-+						  (TSTR
-+						   (" Shadow fixer: %d shadows %d" TENDSTR),
-+						   fixer->obj_id, fixer->shadowed_id));
-+
-+					}
-+
-+				}
-+
-+				if (in && in->valid) {
-+					/* We have already filled this one. We have a duplicate and need to resolve it. */
-+
-+					unsigned existingSerial = in->serial;
-+					unsigned newSerial = tags.serial_number;
-+
-+					if (((existingSerial + 1) & 3) == newSerial) {
-+						/* Use new one - destroy the exisiting one */
-+						yaffs_chunk_del(dev,
-+								  in->hdr_chunk,
-+								  1, __LINE__);
-+						in->valid = 0;
-+					} else {
-+						/* Use existing - destroy this one. */
-+						yaffs_chunk_del(dev, chunk, 1,
-+								  __LINE__);
-+					}
-+				}
-+
-+				if (in && !in->valid &&
-+				    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
-+				     tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND)) {
-+					/* We only load some info, don't fiddle with directory structure */
-+					in->valid = 1;
-+					in->variant_type = oh->type;
-+
-+					in->yst_mode = oh->yst_mode;
-+#ifdef CONFIG_YAFFS_WINCE
-+					in->win_atime[0] = oh->win_atime[0];
-+					in->win_ctime[0] = oh->win_ctime[0];
-+					in->win_mtime[0] = oh->win_mtime[0];
-+					in->win_atime[1] = oh->win_atime[1];
-+					in->win_ctime[1] = oh->win_ctime[1];
-+					in->win_mtime[1] = oh->win_mtime[1];
-+#else
-+					in->yst_uid = oh->yst_uid;
-+					in->yst_gid = oh->yst_gid;
-+					in->yst_atime = oh->yst_atime;
-+					in->yst_mtime = oh->yst_mtime;
-+					in->yst_ctime = oh->yst_ctime;
-+					in->yst_rdev = oh->yst_rdev;
-+#endif
-+					in->hdr_chunk = chunk;
-+					in->serial = tags.serial_number;
-+
-+				} else if (in && !in->valid) {
-+					/* we need to load this info */
-+
-+					in->valid = 1;
-+					in->variant_type = oh->type;
-+
-+					in->yst_mode = oh->yst_mode;
-+#ifdef CONFIG_YAFFS_WINCE
-+					in->win_atime[0] = oh->win_atime[0];
-+					in->win_ctime[0] = oh->win_ctime[0];
-+					in->win_mtime[0] = oh->win_mtime[0];
-+					in->win_atime[1] = oh->win_atime[1];
-+					in->win_ctime[1] = oh->win_ctime[1];
-+					in->win_mtime[1] = oh->win_mtime[1];
-+#else
-+					in->yst_uid = oh->yst_uid;
-+					in->yst_gid = oh->yst_gid;
-+					in->yst_atime = oh->yst_atime;
-+					in->yst_mtime = oh->yst_mtime;
-+					in->yst_ctime = oh->yst_ctime;
-+					in->yst_rdev = oh->yst_rdev;
-+#endif
-+					in->hdr_chunk = chunk;
-+					in->serial = tags.serial_number;
-+
-+					yaffs_set_obj_name_from_oh(in, oh);
-+					in->dirty = 0;
-+
-+					/* directory stuff...
-+					 * hook up to parent
-+					 */
-+
-+					parent =
-+					    yaffs_find_or_create_by_number
-+					    (dev, oh->parent_obj_id,
-+					     YAFFS_OBJECT_TYPE_DIRECTORY);
-+					if (!parent)
-+						alloc_failed = 1;
-+					if (parent && parent->variant_type ==
-+					    YAFFS_OBJECT_TYPE_UNKNOWN) {
-+						/* Set up as a directory */
-+						parent->variant_type =
-+							YAFFS_OBJECT_TYPE_DIRECTORY;
-+						YINIT_LIST_HEAD(&parent->variant.
-+								dir_variant.
-+								children);
-+					} else if (!parent || parent->variant_type !=
-+						   YAFFS_OBJECT_TYPE_DIRECTORY) {
-+						/* Hoosterman, another problem....
-+						 * We're trying to use a non-directory as a directory
-+						 */
-+
-+						T(YAFFS_TRACE_ERROR,
-+						  (TSTR
-+						   ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
-+						    TENDSTR)));
-+						parent = dev->lost_n_found;
-+					}
-+
-+					yaffs_add_obj_to_dir(parent, in);
-+
-+					if (0 && (parent == dev->del_dir ||
-+						  parent == dev->unlinked_dir)) {
-+						in->deleted = 1;	/* If it is unlinked at start up then it wants deleting */
-+						dev->n_deleted_files++;
-+					}
-+					/* Note re hardlinks.
-+					 * Since we might scan a hardlink before its equivalent object is scanned
-+					 * we put them all in a list.
-+					 * After scanning is complete, we should have all the objects, so we run through this
-+					 * list and fix up all the chains.
-+					 */
-+
-+					switch (in->variant_type) {
-+					case YAFFS_OBJECT_TYPE_UNKNOWN:
-+						/* Todo got a problem */
-+						break;
-+					case YAFFS_OBJECT_TYPE_FILE:
-+						if (dev->param.use_header_file_size)
-+
-+							in->variant.file_variant.
-+							    file_size =
-+							    oh->file_size;
-+
-+						break;
-+					case YAFFS_OBJECT_TYPE_HARDLINK:
-+						in->variant.hardlink_variant.
-+							equiv_id =
-+							oh->equiv_id;
-+						in->hard_links.next =
-+							(struct ylist_head *)
-+							hard_list;
-+						hard_list = in;
-+						break;
-+					case YAFFS_OBJECT_TYPE_DIRECTORY:
-+						/* Do nothing */
-+						break;
-+					case YAFFS_OBJECT_TYPE_SPECIAL:
-+						/* Do nothing */
-+						break;
-+					case YAFFS_OBJECT_TYPE_SYMLINK:
-+						in->variant.symlink_variant.alias =
-+						    yaffs_clone_str(oh->alias);
-+						if (!in->variant.symlink_variant.alias)
-+							alloc_failed = 1;
-+						break;
-+					}
-+
-+				}
-+			}
-+		}
-+
-+		if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-+			/* If we got this far while scanning, then the block is fully allocated.*/
-+			state = YAFFS_BLOCK_STATE_FULL;
-+		}
-+
-+		if (state == YAFFS_BLOCK_STATE_ALLOCATING) {
-+			/* If the block was partially allocated then treat it as fully allocated.*/
-+			state = YAFFS_BLOCK_STATE_FULL;
-+			dev->alloc_block = -1;
-+		}
-+
-+		bi->block_state = state;
-+
-+		/* Now let's see if it was dirty */
-+		if (bi->pages_in_use == 0 &&
-+		    !bi->has_shrink_hdr &&
-+		    bi->block_state == YAFFS_BLOCK_STATE_FULL) {
-+			yaffs_block_became_dirty(dev, blk);
-+		}
-+
-+	}
-+
-+
-+	/* Ok, we've done all the scanning.
-+	 * Fix up the hard link chains.
-+	 * We should now have scanned all the objects, now it's time to add these
-+	 * hardlinks.
-+	 */
-+
-+	yaffs_link_fixup(dev, hard_list);
-+
-+	/* Fix up any shadowed objects */
-+	{
-+		struct yaffs_shadow_fixer_s *fixer;
-+		yaffs_obj_t *obj;
-+
-+		while (shadowFixerList) {
-+			fixer = shadowFixerList;
-+			shadowFixerList = fixer->next;
-+			/* Complete the rename transaction by deleting the shadowed object
-+			 * then setting the object header to unshadowed.
-+			 */
-+			obj = yaffs_find_by_number(dev, fixer->shadowed_id);
-+			if (obj)
-+				yaffs_del_obj(obj);
-+
-+			obj = yaffs_find_by_number(dev, fixer->obj_id);
-+
-+			if (obj)
-+				yaffs_update_oh(obj, NULL, 1, 0, 0, NULL);
-+
-+			YFREE(fixer);
-+		}
-+	}
-+
-+	yaffs_release_temp_buffer(dev, chunkData, __LINE__);
-+
-+	if (alloc_failed)
-+		return YAFFS_FAIL;
-+
-+	T(YAFFS_TRACE_SCAN, (TSTR("yaffs1_scan ends" TENDSTR)));
-+
-+
-+	return YAFFS_OK;
-+}
-+
---- /dev/null
-+++ b/fs/yaffs2/yaffs_yaffs1.h
-@@ -0,0 +1,22 @@
-+/*
-+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU Lesser General Public License version 2.1 as
-+ * published by the Free Software Foundation.
-+ *
-+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
-+ */
-+
-+#ifndef __YAFFS_YAFFS1_H__
-+#define __YAFFS_YAFFS1_H__
-+
-+#include "yaffs_guts.h"
-+int yaffs1_scan(yaffs_dev_t *dev);
-+
-+#endif
---- /dev/null
-+++ b/fs/yaffs2/yaffs_yaffs2.c
-@@ -0,0 +1,1540 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+
-+#include "yaffs_guts.h"
-+#include "yaffs_trace.h"
-+#include "yaffs_yaffs2.h"
-+#include "yaffs_checkptrw.h"
-+#include "yaffs_bitmap.h"
-+#include "yaffs_qsort.h"
-+#include "yaffs_nand.h"
-+#include "yaffs_getblockinfo.h"
-+#include "yaffs_verify.h"
-+
-+/*
-+ * Checkpoints are really no benefit on very small partitions.
-+ *
-+ * To save space on small partitions don't bother with checkpoints unless
-+ * the partition is at least this big.
-+ */
-+#define YAFFS_CHECKPOINT_MIN_BLOCKS 60
-+
-+#define YAFFS_SMALL_HOLE_THRESHOLD 4
-+
-+
-+/*
-+ * Oldest Dirty Sequence Number handling.
-+ */
-+ 
-+/* yaffs_calc_oldest_dirty_seq()
-+ * yaffs2_find_oldest_dirty_seq()
-+ * Calculate the oldest dirty sequence number if we don't know it.
-+ */
-+void yaffs_calc_oldest_dirty_seq(yaffs_dev_t *dev)
-+{
-+	int i;
-+	unsigned seq;
-+	unsigned block_no = 0;
-+	yaffs_block_info_t *b;
-+
-+	if(!dev->param.is_yaffs2)
-+		return;
-+
-+	/* Find the oldest dirty sequence number. */
-+	seq = dev->seq_number + 1;
-+	b = dev->block_info;
-+	for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
-+		if (b->block_state == YAFFS_BLOCK_STATE_FULL &&
-+			(b->pages_in_use - b->soft_del_pages) < dev->param.chunks_per_block &&
-+			b->seq_number < seq) {
-+			seq = b->seq_number;
-+			block_no = i;
-+		}
-+		b++;
-+	}
-+
-+	if(block_no){
-+		dev->oldest_dirty_seq = seq;
-+		dev->oldest_dirty_block = block_no;
-+	}
-+
-+}
-+
-+
-+void yaffs2_find_oldest_dirty_seq(yaffs_dev_t *dev)
-+{
-+	if(!dev->param.is_yaffs2)
-+		return;
-+
-+	if(!dev->oldest_dirty_seq)
-+		yaffs_calc_oldest_dirty_seq(dev);
-+}
-+
-+/*
-+ * yaffs_clear_oldest_dirty_seq()
-+ * Called when a block is erased or marked bad. (ie. when its seq_number
-+ * becomes invalid). If the value matches the oldest then we clear 
-+ * dev->oldest_dirty_seq to force its recomputation.
-+ */
-+void yaffs2_clear_oldest_dirty_seq(yaffs_dev_t *dev, yaffs_block_info_t *bi)
-+{
-+
-+	if(!dev->param.is_yaffs2)
-+		return;
-+
-+	if(!bi || bi->seq_number == dev->oldest_dirty_seq){
-+		dev->oldest_dirty_seq = 0;
-+		dev->oldest_dirty_block = 0;
-+	}
-+}
-+
-+/*
-+ * yaffs2_update_oldest_dirty_seq()
-+ * Update the oldest dirty sequence number whenever we dirty a block.
-+ * Only do this if the oldest_dirty_seq is actually being tracked.
-+ */
-+void yaffs2_update_oldest_dirty_seq(yaffs_dev_t *dev, unsigned block_no, yaffs_block_info_t *bi)
-+{
-+	if(!dev->param.is_yaffs2)
-+		return;
-+
-+	if(dev->oldest_dirty_seq){
-+		if(dev->oldest_dirty_seq > bi->seq_number){
-+			dev->oldest_dirty_seq = bi->seq_number;
-+			dev->oldest_dirty_block = block_no;
-+		}
-+	}
-+}
-+
-+int yaffs_block_ok_for_gc(yaffs_dev_t *dev,
-+					yaffs_block_info_t *bi)
-+{
-+
-+	if (!dev->param.is_yaffs2)
-+		return 1;	/* disqualification only applies to yaffs2. */
-+
-+	if (!bi->has_shrink_hdr)
-+		return 1;	/* can gc */
-+
-+	yaffs2_find_oldest_dirty_seq(dev);
-+
-+	/* Can't do gc of this block if there are any blocks older than this one that have
-+	 * discarded pages.
-+	 */
-+	return (bi->seq_number <= dev->oldest_dirty_seq);
-+}
-+
-+/*
-+ * yaffs2_find_refresh_block()
-+ * periodically finds the oldest full block by sequence number for refreshing.
-+ * Only for yaffs2.
-+ */
-+__u32 yaffs2_find_refresh_block(yaffs_dev_t *dev)
-+{
-+	__u32 b ;
-+
-+	__u32 oldest = 0;
-+	__u32 oldestSequence = 0;
-+
-+	yaffs_block_info_t *bi;
-+
-+	if(!dev->param.is_yaffs2)
-+		return oldest;
-+
-+	/*
-+	 * If refresh period < 10 then refreshing is disabled.
-+	 */
-+	if(dev->param.refresh_period < 10)
-+	        return oldest;
-+
-+        /*
-+         * Fix broken values.
-+         */
-+        if(dev->refresh_skip > dev->param.refresh_period)
-+                dev->refresh_skip = dev->param.refresh_period;
-+
-+	if(dev->refresh_skip > 0)
-+	        return oldest;
-+
-+	/*
-+	 * Refresh skip is now zero.
-+	 * We'll do a refresh this time around....
-+	 * Update the refresh skip and find the oldest block.
-+	 */
-+	dev->refresh_skip = dev->param.refresh_period;
-+	dev->refresh_count++;
-+	bi = dev->block_info;
-+	for (b = dev->internal_start_block; b <=dev->internal_end_block; b++){
-+
-+		if (bi->block_state == YAFFS_BLOCK_STATE_FULL){
-+
-+			if(oldest < 1 ||
-+                                bi->seq_number < oldestSequence){
-+                                oldest = b;
-+                                oldestSequence = bi->seq_number;
-+                        }
-+		}
-+		bi++;
-+	}
-+
-+	if (oldest > 0) {
-+		T(YAFFS_TRACE_GC,
-+		  (TSTR("GC refresh count %d selected block %d with seq_number %d" TENDSTR),
-+		   dev->refresh_count, oldest, oldestSequence));
-+	}
-+
-+	return oldest;
-+}
-+
-+int yaffs2_checkpt_required(yaffs_dev_t *dev)
-+{
-+	int nblocks;
-+	
-+	if(!dev->param.is_yaffs2)
-+		return 0;
-+	
-+	nblocks = dev->internal_end_block - dev->internal_start_block + 1 ;
-+
-+	return 	!dev->param.skip_checkpt_wr &&
-+		!dev->read_only &&
-+		(nblocks >= YAFFS_CHECKPOINT_MIN_BLOCKS);
-+}
-+
-+int yaffs_calc_checkpt_blocks_required(yaffs_dev_t *dev)
-+{
-+	int retval;
-+
-+	if(!dev->param.is_yaffs2)
-+		return 0;
-+
-+	if (!dev->checkpoint_blocks_required &&
-+		yaffs2_checkpt_required(dev)){
-+		/* Not a valid value so recalculate */
-+		int n_bytes = 0;
-+		int nBlocks;
-+		int devBlocks = (dev->param.end_block - dev->param.start_block + 1);
-+
-+		n_bytes += sizeof(yaffs_checkpt_validty_t);
-+		n_bytes += sizeof(yaffs_checkpt_dev_t);
-+		n_bytes += devBlocks * sizeof(yaffs_block_info_t);
-+		n_bytes += devBlocks * dev->chunk_bit_stride;
-+		n_bytes += (sizeof(yaffs_checkpt_obj_t) + sizeof(__u32)) * (dev->n_obj);
-+		n_bytes += (dev->tnode_size + sizeof(__u32)) * (dev->n_tnodes);
-+		n_bytes += sizeof(yaffs_checkpt_validty_t);
-+		n_bytes += sizeof(__u32); /* checksum*/
-+
-+		/* Round up and add 2 blocks to allow for some bad blocks, so add 3 */
-+
-+		nBlocks = (n_bytes/(dev->data_bytes_per_chunk * dev->param.chunks_per_block)) + 3;
-+
-+		dev->checkpoint_blocks_required = nBlocks;
-+	}
-+
-+	retval = dev->checkpoint_blocks_required - dev->blocks_in_checkpt;
-+	if(retval < 0)
-+		retval = 0;
-+	return retval;
-+}
-+
-+/*--------------------- Checkpointing --------------------*/
-+
-+
-+static int yaffs2_wr_checkpt_validity_marker(yaffs_dev_t *dev, int head)
-+{
-+	yaffs_checkpt_validty_t cp;
-+
-+	memset(&cp, 0, sizeof(cp));
-+
-+	cp.struct_type = sizeof(cp);
-+	cp.magic = YAFFS_MAGIC;
-+	cp.version = YAFFS_CHECKPOINT_VERSION;
-+	cp.head = (head) ? 1 : 0;
-+
-+	return (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)) ?
-+		1 : 0;
-+}
-+
-+static int yaffs2_rd_checkpt_validty_marker(yaffs_dev_t *dev, int head)
-+{
-+	yaffs_checkpt_validty_t cp;
-+	int ok;
-+
-+	ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
-+
-+	if (ok)
-+		ok = (cp.struct_type == sizeof(cp)) &&
-+		     (cp.magic == YAFFS_MAGIC) &&
-+		     (cp.version == YAFFS_CHECKPOINT_VERSION) &&
-+		     (cp.head == ((head) ? 1 : 0));
-+	return ok ? 1 : 0;
-+}
-+
-+static void yaffs2_dev_to_checkpt_dev(yaffs_checkpt_dev_t *cp,
-+					   yaffs_dev_t *dev)
-+{
-+	cp->n_erased_blocks = dev->n_erased_blocks;
-+	cp->alloc_block = dev->alloc_block;
-+	cp->alloc_page = dev->alloc_page;
-+	cp->n_free_chunks = dev->n_free_chunks;
-+
-+	cp->n_deleted_files = dev->n_deleted_files;
-+	cp->n_unlinked_files = dev->n_unlinked_files;
-+	cp->n_bg_deletions = dev->n_bg_deletions;
-+	cp->seq_number = dev->seq_number;
-+
-+}
-+
-+static void yaffs_checkpt_dev_to_dev(yaffs_dev_t *dev,
-+					   yaffs_checkpt_dev_t *cp)
-+{
-+	dev->n_erased_blocks = cp->n_erased_blocks;
-+	dev->alloc_block = cp->alloc_block;
-+	dev->alloc_page = cp->alloc_page;
-+	dev->n_free_chunks = cp->n_free_chunks;
-+
-+	dev->n_deleted_files = cp->n_deleted_files;
-+	dev->n_unlinked_files = cp->n_unlinked_files;
-+	dev->n_bg_deletions = cp->n_bg_deletions;
-+	dev->seq_number = cp->seq_number;
-+}
-+
-+
-+static int yaffs2_wr_checkpt_dev(yaffs_dev_t *dev)
-+{
-+	yaffs_checkpt_dev_t cp;
-+	__u32 n_bytes;
-+	__u32 nBlocks = (dev->internal_end_block - dev->internal_start_block + 1);
-+
-+	int ok;
-+
-+	/* Write device runtime values*/
-+	yaffs2_dev_to_checkpt_dev(&cp, dev);
-+	cp.struct_type = sizeof(cp);
-+
-+	ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
-+
-+	/* Write block info */
-+	if (ok) {
-+		n_bytes = nBlocks * sizeof(yaffs_block_info_t);
-+		ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) == n_bytes);
-+	}
-+
-+	/* Write chunk bits */
-+	if (ok) {
-+		n_bytes = nBlocks * dev->chunk_bit_stride;
-+		ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) == n_bytes);
-+	}
-+	return	 ok ? 1 : 0;
-+
-+}
-+
-+static int yaffs2_rd_checkpt_dev(yaffs_dev_t *dev)
-+{
-+	yaffs_checkpt_dev_t cp;
-+	__u32 n_bytes;
-+	__u32 nBlocks = (dev->internal_end_block - dev->internal_start_block + 1);
-+
-+	int ok;
-+
-+	ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
-+	if (!ok)
-+		return 0;
-+
-+	if (cp.struct_type != sizeof(cp))
-+		return 0;
-+
-+
-+	yaffs_checkpt_dev_to_dev(dev, &cp);
-+
-+	n_bytes = nBlocks * sizeof(yaffs_block_info_t);
-+
-+	ok = (yaffs2_checkpt_rd(dev, dev->block_info, n_bytes) == n_bytes);
-+
-+	if (!ok)
-+		return 0;
-+	n_bytes = nBlocks * dev->chunk_bit_stride;
-+
-+	ok = (yaffs2_checkpt_rd(dev, dev->chunk_bits, n_bytes) == n_bytes);
-+
-+	return ok ? 1 : 0;
-+}
-+
-+static void yaffs2_obj_checkpt_obj(yaffs_checkpt_obj_t *cp,
-+					   yaffs_obj_t *obj)
-+{
-+
-+	cp->obj_id = obj->obj_id;
-+	cp->parent_id = (obj->parent) ? obj->parent->obj_id : 0;
-+	cp->hdr_chunk = obj->hdr_chunk;
-+	cp->variant_type = obj->variant_type;
-+	cp->deleted = obj->deleted;
-+	cp->soft_del = obj->soft_del;
-+	cp->unlinked = obj->unlinked;
-+	cp->fake = obj->fake;
-+	cp->rename_allowed = obj->rename_allowed;
-+	cp->unlink_allowed = obj->unlink_allowed;
-+	cp->serial = obj->serial;
-+	cp->n_data_chunks = obj->n_data_chunks;
-+
-+	if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
-+		cp->size_or_equiv_obj = obj->variant.file_variant.file_size;
-+	else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
-+		cp->size_or_equiv_obj = obj->variant.hardlink_variant.equiv_id;
-+}
-+
-+static int taffs2_checkpt_obj_to_obj(yaffs_obj_t *obj, yaffs_checkpt_obj_t *cp)
-+{
-+
-+	yaffs_obj_t *parent;
-+
-+	if (obj->variant_type != cp->variant_type) {
-+		T(YAFFS_TRACE_ERROR, (TSTR("Checkpoint read object %d type %d "
-+			TCONT("chunk %d does not match existing object type %d")
-+			TENDSTR), cp->obj_id, cp->variant_type, cp->hdr_chunk,
-+			obj->variant_type));
-+		return 0;
-+	}
-+
-+	obj->obj_id = cp->obj_id;
-+
-+	if (cp->parent_id)
-+		parent = yaffs_find_or_create_by_number(
-+					obj->my_dev,
-+					cp->parent_id,
-+					YAFFS_OBJECT_TYPE_DIRECTORY);
-+	else
-+		parent = NULL;
-+
-+	if (parent) {
-+		if (parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
-+			T(YAFFS_TRACE_ALWAYS, (TSTR("Checkpoint read object %d parent %d type %d"
-+				TCONT(" chunk %d Parent type, %d, not directory")
-+				TENDSTR),
-+				cp->obj_id, cp->parent_id, cp->variant_type,
-+				cp->hdr_chunk, parent->variant_type));
-+			return 0;
-+		}
-+		yaffs_add_obj_to_dir(parent, obj);
-+	}
-+
-+	obj->hdr_chunk = cp->hdr_chunk;
-+	obj->variant_type = cp->variant_type;
-+	obj->deleted = cp->deleted;
-+	obj->soft_del = cp->soft_del;
-+	obj->unlinked = cp->unlinked;
-+	obj->fake = cp->fake;
-+	obj->rename_allowed = cp->rename_allowed;
-+	obj->unlink_allowed = cp->unlink_allowed;
-+	obj->serial = cp->serial;
-+	obj->n_data_chunks = cp->n_data_chunks;
-+
-+	if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
-+		obj->variant.file_variant.file_size = cp->size_or_equiv_obj;
-+	else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
-+		obj->variant.hardlink_variant.equiv_id = cp->size_or_equiv_obj;
-+
-+	if (obj->hdr_chunk > 0)
-+		obj->lazy_loaded = 1;
-+	return 1;
-+}
-+
-+
-+
-+static int yaffs2_checkpt_tnode_worker(yaffs_obj_t *in, yaffs_tnode_t *tn,
-+					__u32 level, int chunk_offset)
-+{
-+	int i;
-+	yaffs_dev_t *dev = in->my_dev;
-+	int ok = 1;
-+
-+	if (tn) {
-+		if (level > 0) {
-+
-+			for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
-+				if (tn->internal[i]) {
-+					ok = yaffs2_checkpt_tnode_worker(in,
-+							tn->internal[i],
-+							level - 1,
-+							(chunk_offset<<YAFFS_TNODES_INTERNAL_BITS) + i);
-+				}
-+			}
-+		} else if (level == 0) {
-+			__u32 baseOffset = chunk_offset <<  YAFFS_TNODES_LEVEL0_BITS;
-+			ok = (yaffs2_checkpt_wr(dev, &baseOffset, sizeof(baseOffset)) == sizeof(baseOffset));
-+			if (ok)
-+				ok = (yaffs2_checkpt_wr(dev, tn, dev->tnode_size) == dev->tnode_size);
-+		}
-+	}
-+
-+	return ok;
-+
-+}
-+
-+static int yaffs2_wr_checkpt_tnodes(yaffs_obj_t *obj)
-+{
-+	__u32 endMarker = ~0;
-+	int ok = 1;
-+
-+	if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) {
-+		ok = yaffs2_checkpt_tnode_worker(obj,
-+					    obj->variant.file_variant.top,
-+					    obj->variant.file_variant.top_level,
-+					    0);
-+		if (ok)
-+			ok = (yaffs2_checkpt_wr(obj->my_dev, &endMarker, sizeof(endMarker)) ==
-+				sizeof(endMarker));
-+	}
-+
-+	return ok ? 1 : 0;
-+}
-+
-+static int yaffs2_rd_checkpt_tnodes(yaffs_obj_t *obj)
-+{
-+	__u32 baseChunk;
-+	int ok = 1;
-+	yaffs_dev_t *dev = obj->my_dev;
-+	yaffs_file_s *fileStructPtr = &obj->variant.file_variant;
-+	yaffs_tnode_t *tn;
-+	int nread = 0;
-+
-+	ok = (yaffs2_checkpt_rd(dev, &baseChunk, sizeof(baseChunk)) == sizeof(baseChunk));
-+
-+	while (ok && (~baseChunk)) {
-+		nread++;
-+		/* Read level 0 tnode */
-+
-+
-+		tn = yaffs_get_tnode(dev);
-+		if (tn){
-+			ok = (yaffs2_checkpt_rd(dev, tn, dev->tnode_size) == dev->tnode_size);
-+		} else
-+			ok = 0;
-+
-+		if (tn && ok)
-+			ok = yaffs_add_find_tnode_0(dev,
-+							fileStructPtr,
-+							baseChunk,
-+							tn) ? 1 : 0;
-+
-+		if (ok)
-+			ok = (yaffs2_checkpt_rd(dev, &baseChunk, sizeof(baseChunk)) == sizeof(baseChunk));
-+
-+	}
-+
-+	T(YAFFS_TRACE_CHECKPOINT, (
-+		TSTR("Checkpoint read tnodes %d records, last %d. ok %d" TENDSTR),
-+		nread, baseChunk, ok));
-+
-+	return ok ? 1 : 0;
-+}
-+
-+
-+static int yaffs2_wr_checkpt_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_checkpt_obj_t cp;
-+	int i;
-+	int ok = 1;
-+	struct ylist_head *lh;
-+
-+
-+	/* Iterate through the objects in each hash entry,
-+	 * dumping them to the checkpointing stream.
-+	 */
-+
-+	for (i = 0; ok &&  i <  YAFFS_NOBJECT_BUCKETS; i++) {
-+		ylist_for_each(lh, &dev->obj_bucket[i].list) {
-+			if (lh) {
-+				obj = ylist_entry(lh, yaffs_obj_t, hash_link);
-+				if (!obj->defered_free) {
-+					yaffs2_obj_checkpt_obj(&cp, obj);
-+					cp.struct_type = sizeof(cp);
-+
-+					T(YAFFS_TRACE_CHECKPOINT, (
-+						TSTR("Checkpoint write object %d parent %d type %d chunk %d obj addr %p" TENDSTR),
-+						cp.obj_id, cp.parent_id, cp.variant_type, cp.hdr_chunk, obj));
-+
-+					ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
-+
-+					if (ok && obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
-+						ok = yaffs2_wr_checkpt_tnodes(obj);
-+				}
-+			}
-+		}
-+	}
-+
-+	/* Dump end of list */
-+	memset(&cp, 0xFF, sizeof(yaffs_checkpt_obj_t));
-+	cp.struct_type = sizeof(cp);
-+
-+	if (ok)
-+		ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
-+
-+	return ok ? 1 : 0;
-+}
-+
-+static int yaffs2_rd_checkpt_objs(yaffs_dev_t *dev)
-+{
-+	yaffs_obj_t *obj;
-+	yaffs_checkpt_obj_t cp;
-+	int ok = 1;
-+	int done = 0;
-+	yaffs_obj_t *hard_list = NULL;
-+
-+	while (ok && !done) {
-+		ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
-+		if (cp.struct_type != sizeof(cp)) {
-+			T(YAFFS_TRACE_CHECKPOINT, (TSTR("struct size %d instead of %d ok %d"TENDSTR),
-+				cp.struct_type, (int)sizeof(cp), ok));
-+			ok = 0;
-+		}
-+
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("Checkpoint read object %d parent %d type %d chunk %d " TENDSTR),
-+			cp.obj_id, cp.parent_id, cp.variant_type, cp.hdr_chunk));
-+
-+		if (ok && cp.obj_id == ~0)
-+			done = 1;
-+		else if (ok) {
-+			obj = yaffs_find_or_create_by_number(dev, cp.obj_id, cp.variant_type);
-+			if (obj) {
-+				ok = taffs2_checkpt_obj_to_obj(obj, &cp);
-+				if (!ok)
-+					break;
-+				if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) {
-+					ok = yaffs2_rd_checkpt_tnodes(obj);
-+				} else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) {
-+					obj->hard_links.next =
-+						(struct ylist_head *) hard_list;
-+					hard_list = obj;
-+				}
-+			} else
-+				ok = 0;
-+		}
-+	}
-+
-+	if (ok)
-+		yaffs_link_fixup(dev, hard_list);
-+
-+	return ok ? 1 : 0;
-+}
-+
-+static int yaffs2_wr_checkpt_sum(yaffs_dev_t *dev)
-+{
-+	__u32 checkpt_sum;
-+	int ok;
-+
-+	yaffs2_get_checkpt_sum(dev, &checkpt_sum);
-+
-+	ok = (yaffs2_checkpt_wr(dev, &checkpt_sum, sizeof(checkpt_sum)) == sizeof(checkpt_sum));
-+
-+	if (!ok)
-+		return 0;
-+
-+	return 1;
-+}
-+
-+static int yaffs2_rd_checkpt_sum(yaffs_dev_t *dev)
-+{
-+	__u32 checkpt_sum0;
-+	__u32 checkpt_sum1;
-+	int ok;
-+
-+	yaffs2_get_checkpt_sum(dev, &checkpt_sum0);
-+
-+	ok = (yaffs2_checkpt_rd(dev, &checkpt_sum1, sizeof(checkpt_sum1)) == sizeof(checkpt_sum1));
-+
-+	if (!ok)
-+		return 0;
-+
-+	if (checkpt_sum0 != checkpt_sum1)
-+		return 0;
-+
-+	return 1;
-+}
-+
-+
-+static int yaffs2_wr_checkpt_data(yaffs_dev_t *dev)
-+{
-+	int ok = 1;
-+
-+	if (!yaffs2_checkpt_required(dev)) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint write" TENDSTR)));
-+		ok = 0;
-+	}
-+
-+	if (ok)
-+		ok = yaffs2_checkpt_open(dev, 1);
-+
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint validity" TENDSTR)));
-+		ok = yaffs2_wr_checkpt_validity_marker(dev, 1);
-+	}
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint device" TENDSTR)));
-+		ok = yaffs2_wr_checkpt_dev(dev);
-+	}
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint objects" TENDSTR)));
-+		ok = yaffs2_wr_checkpt_objs(dev);
-+	}
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("write checkpoint validity" TENDSTR)));
-+		ok = yaffs2_wr_checkpt_validity_marker(dev, 0);
-+	}
-+
-+	if (ok)
-+		ok = yaffs2_wr_checkpt_sum(dev);
-+
-+	if (!yaffs_checkpt_close(dev))
-+		ok = 0;
-+
-+	if (ok)
-+		dev->is_checkpointed = 1;
-+	else
-+		dev->is_checkpointed = 0;
-+
-+	return dev->is_checkpointed;
-+}
-+
-+static int yaffs2_rd_checkpt_data(yaffs_dev_t *dev)
-+{
-+	int ok = 1;
-+	
-+	if(!dev->param.is_yaffs2)
-+		ok = 0;
-+
-+	if (ok && dev->param.skip_checkpt_rd) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("skipping checkpoint read" TENDSTR)));
-+		ok = 0;
-+	}
-+
-+	if (ok)
-+		ok = yaffs2_checkpt_open(dev, 0); /* open for read */
-+
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint validity" TENDSTR)));
-+		ok = yaffs2_rd_checkpt_validty_marker(dev, 1);
-+	}
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint device" TENDSTR)));
-+		ok = yaffs2_rd_checkpt_dev(dev);
-+	}
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint objects" TENDSTR)));
-+		ok = yaffs2_rd_checkpt_objs(dev);
-+	}
-+	if (ok) {
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint validity" TENDSTR)));
-+		ok = yaffs2_rd_checkpt_validty_marker(dev, 0);
-+	}
-+
-+	if (ok) {
-+		ok = yaffs2_rd_checkpt_sum(dev);
-+		T(YAFFS_TRACE_CHECKPOINT, (TSTR("read checkpoint checksum %d" TENDSTR), ok));
-+	}
-+
-+	if (!yaffs_checkpt_close(dev))
-+		ok = 0;
-+
-+	if (ok)
-+		dev->is_checkpointed = 1;
-+	else
-+		dev->is_checkpointed = 0;
-+
-+	return ok ? 1 : 0;
-+
-+}
-+
-+void yaffs2_checkpt_invalidate(yaffs_dev_t *dev)
-+{
-+	if (dev->is_checkpointed ||
-+			dev->blocks_in_checkpt > 0) {
-+		dev->is_checkpointed = 0;
-+		yaffs2_checkpt_invalidate_stream(dev);
-+	}
-+	if (dev->param.sb_dirty_fn)
-+		dev->param.sb_dirty_fn(dev);
-+}
-+
-+
-+int yaffs_checkpoint_save(yaffs_dev_t *dev)
-+{
-+
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("save entry: is_checkpointed %d"TENDSTR), dev->is_checkpointed));
-+
-+	yaffs_verify_objects(dev);
-+	yaffs_verify_blocks(dev);
-+	yaffs_verify_free_chunks(dev);
-+
-+	if (!dev->is_checkpointed) {
-+		yaffs2_checkpt_invalidate(dev);
-+		yaffs2_wr_checkpt_data(dev);
-+	}
-+
-+	T(YAFFS_TRACE_ALWAYS, (TSTR("save exit: is_checkpointed %d"TENDSTR), dev->is_checkpointed));
-+
-+	return dev->is_checkpointed;
-+}
-+
-+int yaffs2_checkpt_restore(yaffs_dev_t *dev)
-+{
-+	int retval;
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("restore entry: is_checkpointed %d"TENDSTR), dev->is_checkpointed));
-+
-+	retval = yaffs2_rd_checkpt_data(dev);
-+
-+	if (dev->is_checkpointed) {
-+		yaffs_verify_objects(dev);
-+		yaffs_verify_blocks(dev);
-+		yaffs_verify_free_chunks(dev);
-+	}
-+
-+	T(YAFFS_TRACE_CHECKPOINT, (TSTR("restore exit: is_checkpointed %d"TENDSTR), dev->is_checkpointed));
-+
-+	return retval;
-+}
-+
-+int yaffs2_handle_hole(yaffs_obj_t *obj, loff_t new_size)
-+{
-+	/* if newsSize > oldFileSize.
-+	 * We're going to be writing a hole.
-+	 * If the hole is small then write zeros otherwise write a start of hole marker.
-+	 */
-+		
-+
-+	loff_t oldFileSize;
-+	int increase;
-+	int smallHole   ;
-+	int result = YAFFS_OK;
-+	yaffs_dev_t *dev = NULL;
-+
-+	__u8 *localBuffer = NULL;
-+	
-+	int smallIncreaseOk = 0;
-+	
-+	if(!obj)
-+		return YAFFS_FAIL;
-+
-+	if(obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
-+		return YAFFS_FAIL;
-+	
-+	dev = obj->my_dev;
-+	
-+	/* Bail out if not yaffs2 mode */
-+	if(!dev->param.is_yaffs2)
-+		return YAFFS_OK;
-+
-+	oldFileSize = obj->variant.file_variant.file_size;
-+
-+	if (new_size <= oldFileSize)
-+		return YAFFS_OK;
-+
-+	increase = new_size - oldFileSize;
-+
-+	if(increase < YAFFS_SMALL_HOLE_THRESHOLD * dev->data_bytes_per_chunk &&
-+		yaffs_check_alloc_available(dev, YAFFS_SMALL_HOLE_THRESHOLD + 1))
-+		smallHole = 1;
-+	else
-+		smallHole = 0;
-+
-+	if(smallHole)
-+		localBuffer= yaffs_get_temp_buffer(dev, __LINE__);
-+	
-+	if(localBuffer){
-+		/* fill hole with zero bytes */
-+		int pos = oldFileSize;
-+		int thisWrite;
-+		int written;
-+		memset(localBuffer,0,dev->data_bytes_per_chunk);
-+		smallIncreaseOk = 1;
-+
-+		while(increase > 0 && smallIncreaseOk){
-+			thisWrite = increase;
-+			if(thisWrite > dev->data_bytes_per_chunk)
-+				thisWrite = dev->data_bytes_per_chunk;
-+			written = yaffs_do_file_wr(obj,localBuffer,pos,thisWrite,0);
-+			if(written == thisWrite){
-+				pos += thisWrite;
-+				increase -= thisWrite;
-+			} else
-+				smallIncreaseOk = 0;
-+		}
-+
-+		yaffs_release_temp_buffer(dev,localBuffer,__LINE__);
-+
-+		/* If we were out of space then reverse any chunks we've added */		
-+		if(!smallIncreaseOk)
-+			yaffs_resize_file_down(obj, oldFileSize);
-+	}
-+	
-+	if (!smallIncreaseOk &&
-+		obj->parent &&
-+		obj->parent->obj_id != YAFFS_OBJECTID_UNLINKED &&
-+		obj->parent->obj_id != YAFFS_OBJECTID_DELETED){
-+		/* Write a hole start header with the old file size */
-+		yaffs_update_oh(obj, NULL, 0, 1, 0, NULL);
-+	}
-+
-+	return result;
-+
-+}
-+
-+
-+typedef struct {
-+	int seq;
-+	int block;
-+} yaffs_BlockIndex;
-+
-+
-+static int yaffs2_ybicmp(const void *a, const void *b)
-+{
-+	register int aseq = ((yaffs_BlockIndex *)a)->seq;
-+	register int bseq = ((yaffs_BlockIndex *)b)->seq;
-+	register int ablock = ((yaffs_BlockIndex *)a)->block;
-+	register int bblock = ((yaffs_BlockIndex *)b)->block;
-+	if (aseq == bseq)
-+		return ablock - bblock;
-+	else
-+		return aseq - bseq;
-+}
-+
-+int yaffs2_scan_backwards(yaffs_dev_t *dev)
-+{
-+	yaffs_ext_tags tags;
-+	int blk;
-+	int blockIterator;
-+	int startIterator;
-+	int endIterator;
-+	int nBlocksToScan = 0;
-+
-+	int chunk;
-+	int result;
-+	int c;
-+	int deleted;
-+	yaffs_block_state_t state;
-+	yaffs_obj_t *hard_list = NULL;
-+	yaffs_block_info_t *bi;
-+	__u32 seq_number;
-+	yaffs_obj_header *oh;
-+	yaffs_obj_t *in;
-+	yaffs_obj_t *parent;
-+	int nBlocks = dev->internal_end_block - dev->internal_start_block + 1;
-+	int itsUnlinked;
-+	__u8 *chunkData;
-+
-+	int file_size;
-+	int is_shrink;
-+	int foundChunksInBlock;
-+	int equiv_id;
-+	int alloc_failed = 0;
-+
-+
-+	yaffs_BlockIndex *blockIndex = NULL;
-+	int altBlockIndex = 0;
-+
-+	T(YAFFS_TRACE_SCAN,
-+	  (TSTR
-+	   ("yaffs2_scan_backwards starts  intstartblk %d intendblk %d..."
-+	    TENDSTR), dev->internal_start_block, dev->internal_end_block));
-+
-+
-+	dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;
-+
-+	blockIndex = YMALLOC(nBlocks * sizeof(yaffs_BlockIndex));
-+
-+	if (!blockIndex) {
-+		blockIndex = YMALLOC_ALT(nBlocks * sizeof(yaffs_BlockIndex));
-+		altBlockIndex = 1;
-+	}
-+
-+	if (!blockIndex) {
-+		T(YAFFS_TRACE_SCAN,
-+		  (TSTR("yaffs2_scan_backwards() could not allocate block index!" TENDSTR)));
-+		return YAFFS_FAIL;
-+	}
-+
-+	dev->blocks_in_checkpt = 0;
-+
-+	chunkData = yaffs_get_temp_buffer(dev, __LINE__);
-+
-+	/* Scan all the blocks to determine their state */
-+	bi = dev->block_info;
-+	for (blk = dev->internal_start_block; blk <= dev->internal_end_block; blk++) {
-+		yaffs_clear_chunk_bits(dev, blk);
-+		bi->pages_in_use = 0;
-+		bi->soft_del_pages = 0;
-+
-+		yaffs_query_init_block_state(dev, blk, &state, &seq_number);
-+
-+		bi->block_state = state;
-+		bi->seq_number = seq_number;
-+
-+		if (bi->seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA)
-+			bi->block_state = state = YAFFS_BLOCK_STATE_CHECKPOINT;
-+		if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
-+			bi->block_state = state = YAFFS_BLOCK_STATE_DEAD;
-+
-+		T(YAFFS_TRACE_SCAN_DEBUG,
-+		  (TSTR("Block scanning block %d state %d seq %d" TENDSTR), blk,
-+		   state, seq_number));
-+
-+
-+		if (state == YAFFS_BLOCK_STATE_CHECKPOINT) {
-+			dev->blocks_in_checkpt++;
-+
-+		} else if (state == YAFFS_BLOCK_STATE_DEAD) {
-+			T(YAFFS_TRACE_BAD_BLOCKS,
-+			  (TSTR("block %d is bad" TENDSTR), blk));
-+		} else if (state == YAFFS_BLOCK_STATE_EMPTY) {
-+			T(YAFFS_TRACE_SCAN_DEBUG,
-+			  (TSTR("Block empty " TENDSTR)));
-+			dev->n_erased_blocks++;
-+			dev->n_free_chunks += dev->param.chunks_per_block;
-+		} else if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-+
-+			/* Determine the highest sequence number */
-+			if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
-+			    seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
-+
-+				blockIndex[nBlocksToScan].seq = seq_number;
-+				blockIndex[nBlocksToScan].block = blk;
-+
-+				nBlocksToScan++;
-+
-+				if (seq_number >= dev->seq_number)
-+					dev->seq_number = seq_number;
-+			} else {
-+				/* TODO: Nasty sequence number! */
-+				T(YAFFS_TRACE_SCAN,
-+				  (TSTR
-+				   ("Block scanning block %d has bad sequence number %d"
-+				    TENDSTR), blk, seq_number));
-+
-+			}
-+		}
-+		bi++;
-+	}
-+
-+	T(YAFFS_TRACE_SCAN,
-+	(TSTR("%d blocks to be sorted..." TENDSTR), nBlocksToScan));
-+
-+
-+
-+	YYIELD();
-+
-+	/* Sort the blocks by sequence number*/
-+	yaffs_qsort(blockIndex, nBlocksToScan, sizeof(yaffs_BlockIndex), yaffs2_ybicmp);
-+
-+	YYIELD();
-+
-+	T(YAFFS_TRACE_SCAN, (TSTR("...done" TENDSTR)));
-+
-+	/* Now scan the blocks looking at the data. */
-+	startIterator = 0;
-+	endIterator = nBlocksToScan - 1;
-+	T(YAFFS_TRACE_SCAN_DEBUG,
-+	  (TSTR("%d blocks to be scanned" TENDSTR), nBlocksToScan));
-+
-+	/* For each block.... backwards */
-+	for (blockIterator = endIterator; !alloc_failed && blockIterator >= startIterator;
-+			blockIterator--) {
-+		/* Cooperative multitasking! This loop can run for so
-+		   long that watchdog timers expire. */
-+		YYIELD();
-+
-+		/* get the block to scan in the correct order */
-+		blk = blockIndex[blockIterator].block;
-+
-+		bi = yaffs_get_block_info(dev, blk);
-+
-+
-+		state = bi->block_state;
-+
-+		deleted = 0;
-+
-+		/* For each chunk in each block that needs scanning.... */
-+		foundChunksInBlock = 0;
-+		for (c = dev->param.chunks_per_block - 1;
-+		     !alloc_failed && c >= 0 &&
-+		     (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
-+		      state == YAFFS_BLOCK_STATE_ALLOCATING); c--) {
-+			/* Scan backwards...
-+			 * Read the tags and decide what to do
-+			 */
-+
-+			chunk = blk * dev->param.chunks_per_block + c;
-+
-+			result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL,
-+							&tags);
-+
-+			/* Let's have a good look at this chunk... */
-+
-+			if (!tags.chunk_used) {
-+				/* An unassigned chunk in the block.
-+				 * If there are used chunks after this one, then
-+				 * it is a chunk that was skipped due to failing the erased
-+				 * check. Just skip it so that it can be deleted.
-+				 * But, more typically, We get here when this is an unallocated
-+				 * chunk and his means that either the block is empty or
-+				 * this is the one being allocated from
-+				 */
-+
-+				if (foundChunksInBlock) {
-+					/* This is a chunk that was skipped due to failing the erased check */
-+				} else if (c == 0) {
-+					/* We're looking at the first chunk in the block so the block is unused */
-+					state = YAFFS_BLOCK_STATE_EMPTY;
-+					dev->n_erased_blocks++;
-+				} else {
-+					if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
-+					    state == YAFFS_BLOCK_STATE_ALLOCATING) {
-+						if (dev->seq_number == bi->seq_number) {
-+							/* this is the block being allocated from */
-+
-+							T(YAFFS_TRACE_SCAN,
-+							  (TSTR
-+							   (" Allocating from %d %d"
-+							    TENDSTR), blk, c));
-+
-+							state = YAFFS_BLOCK_STATE_ALLOCATING;
-+							dev->alloc_block = blk;
-+							dev->alloc_page = c;
-+							dev->alloc_block_finder = blk;
-+						} else {
-+							/* This is a partially written block that is not
-+							 * the current allocation block.
-+							 */
-+
-+							 T(YAFFS_TRACE_SCAN,
-+							 (TSTR("Partially written block %d detected" TENDSTR),
-+							 blk));
-+						}
-+					}
-+				}
-+
-+				dev->n_free_chunks++;
-+
-+			} else if (tags.ecc_result == YAFFS_ECC_RESULT_UNFIXED) {
-+				T(YAFFS_TRACE_SCAN,
-+				  (TSTR(" Unfixed ECC in chunk(%d:%d), chunk ignored"TENDSTR),
-+				  blk, c));
-+
-+				  dev->n_free_chunks++;
-+
-+			} else if (tags.obj_id > YAFFS_MAX_OBJECT_ID ||
-+				tags.chunk_id > YAFFS_MAX_CHUNK_ID ||
-+				(tags.chunk_id > 0 && tags.n_bytes > dev->data_bytes_per_chunk) ||
-+				tags.seq_number != bi->seq_number ) {
-+				T(YAFFS_TRACE_SCAN,
-+				  (TSTR("Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored"TENDSTR),
-+				  blk, c,tags.obj_id, tags.chunk_id, tags.n_bytes));
-+
-+				  dev->n_free_chunks++;
-+
-+			} else if (tags.chunk_id > 0) {
-+				/* chunk_id > 0 so it is a data chunk... */
-+				unsigned int endpos;
-+				__u32 chunkBase =
-+				    (tags.chunk_id - 1) * dev->data_bytes_per_chunk;
-+
-+				foundChunksInBlock = 1;
-+
-+
-+				yaffs_set_chunk_bit(dev, blk, c);
-+				bi->pages_in_use++;
-+
-+				in = yaffs_find_or_create_by_number(dev,
-+								      tags.
-+								      obj_id,
-+								      YAFFS_OBJECT_TYPE_FILE);
-+				if (!in) {
-+					/* Out of memory */
-+					alloc_failed = 1;
-+				}
-+
-+				if (in &&
-+				    in->variant_type == YAFFS_OBJECT_TYPE_FILE
-+				    && chunkBase < in->variant.file_variant.shrink_size) {
-+					/* This has not been invalidated by a resize */
-+					if (!yaffs_put_chunk_in_file(in, tags.chunk_id, chunk, -1)) {
-+						alloc_failed = 1;
-+					}
-+
-+					/* File size is calculated by looking at the data chunks if we have not
-+					 * seen an object header yet. Stop this practice once we find an object header.
-+					 */
-+					endpos = chunkBase + tags.n_bytes;
-+
-+					if (!in->valid &&	/* have not got an object header yet */
-+					    in->variant.file_variant.scanned_size < endpos) {
-+						in->variant.file_variant.scanned_size = endpos;
-+						in->variant.file_variant.file_size = endpos;
-+					}
-+
-+				} else if (in) {
-+					/* This chunk has been invalidated by a resize, or a past file deletion
-+					 * so delete the chunk*/
-+					yaffs_chunk_del(dev, chunk, 1, __LINE__);
-+
-+				}
-+			} else {
-+				/* chunk_id == 0, so it is an ObjectHeader.
-+				 * Thus, we read in the object header and make the object
-+				 */
-+				foundChunksInBlock = 1;
-+
-+				yaffs_set_chunk_bit(dev, blk, c);
-+				bi->pages_in_use++;
-+
-+				oh = NULL;
-+				in = NULL;
-+
-+				if (tags.extra_available) {
-+					in = yaffs_find_or_create_by_number(dev,
-+						tags.obj_id,
-+						tags.extra_obj_type);
-+					if (!in)
-+						alloc_failed = 1;
-+				}
-+
-+				if (!in ||
-+				    (!in->valid && dev->param.disable_lazy_load) ||
-+				    tags.extra_shadows ||
-+				    (!in->valid &&
-+				    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
-+				     tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND))) {
-+
-+					/* If we don't have  valid info then we need to read the chunk
-+					 * TODO In future we can probably defer reading the chunk and
-+					 * living with invalid data until needed.
-+					 */
-+
-+					result = yaffs_rd_chunk_tags_nand(dev,
-+									chunk,
-+									chunkData,
-+									NULL);
-+
-+					oh = (yaffs_obj_header *) chunkData;
-+
-+					if (dev->param.inband_tags) {
-+						/* Fix up the header if they got corrupted by inband tags */
-+						oh->shadows_obj = oh->inband_shadowed_obj_id;
-+						oh->is_shrink = oh->inband_is_shrink;
-+					}
-+
-+					if (!in) {
-+						in = yaffs_find_or_create_by_number(dev, tags.obj_id, oh->type);
-+						if (!in)
-+							alloc_failed = 1;
-+					}
-+
-+				}
-+
-+				if (!in) {
-+					/* TODO Hoosterman we have a problem! */
-+					T(YAFFS_TRACE_ERROR,
-+					  (TSTR
-+					   ("yaffs tragedy: Could not make object for object  %d at chunk %d during scan"
-+					    TENDSTR), tags.obj_id, chunk));
-+					continue;
-+				}
-+
-+				if (in->valid) {
-+					/* We have already filled this one.
-+					 * We have a duplicate that will be discarded, but
-+					 * we first have to suck out resize info if it is a file.
-+					 */
-+
-+					if ((in->variant_type == YAFFS_OBJECT_TYPE_FILE) &&
-+					     ((oh &&
-+					       oh->type == YAFFS_OBJECT_TYPE_FILE) ||
-+					      (tags.extra_available  &&
-+					       tags.extra_obj_type == YAFFS_OBJECT_TYPE_FILE))) {
-+						__u32 thisSize =
-+						    (oh) ? oh->file_size : tags.
-+						    extra_length;
-+						__u32 parent_obj_id =
-+						    (oh) ? oh->
-+						    parent_obj_id : tags.
-+						    extra_parent_id;
-+
-+
-+						is_shrink =
-+						    (oh) ? oh->is_shrink : tags.
-+						    extra_is_shrink;
-+
-+						/* If it is deleted (unlinked at start also means deleted)
-+						 * we treat the file size as being zeroed at this point.
-+						 */
-+						if (parent_obj_id ==
-+						    YAFFS_OBJECTID_DELETED
-+						    || parent_obj_id ==
-+						    YAFFS_OBJECTID_UNLINKED) {
-+							thisSize = 0;
-+							is_shrink = 1;
-+						}
-+
-+						if (is_shrink && in->variant.file_variant.shrink_size > thisSize)
-+							in->variant.file_variant.shrink_size = thisSize;
-+
-+						if (is_shrink)
-+							bi->has_shrink_hdr = 1;
-+
-+					}
-+					/* Use existing - destroy this one. */
-+					yaffs_chunk_del(dev, chunk, 1, __LINE__);
-+
-+				}
-+
-+				if (!in->valid && in->variant_type !=
-+				    (oh ? oh->type : tags.extra_obj_type))
-+					T(YAFFS_TRACE_ERROR, (
-+						TSTR("yaffs tragedy: Bad object type, "
-+					    TCONT("%d != %d, for object %d at chunk ")
-+					    TCONT("%d during scan")
-+						TENDSTR), oh ?
-+					    oh->type : tags.extra_obj_type,
-+					    in->variant_type, tags.obj_id,
-+					    chunk));
-+
-+				if (!in->valid &&
-+				    (tags.obj_id == YAFFS_OBJECTID_ROOT ||
-+				     tags.obj_id ==
-+				     YAFFS_OBJECTID_LOSTNFOUND)) {
-+					/* We only load some info, don't fiddle with directory structure */
-+					in->valid = 1;
-+
-+					if (oh) {
-+
-+						in->yst_mode = oh->yst_mode;
-+#ifdef CONFIG_YAFFS_WINCE
-+						in->win_atime[0] = oh->win_atime[0];
-+						in->win_ctime[0] = oh->win_ctime[0];
-+						in->win_mtime[0] = oh->win_mtime[0];
-+						in->win_atime[1] = oh->win_atime[1];
-+						in->win_ctime[1] = oh->win_ctime[1];
-+						in->win_mtime[1] = oh->win_mtime[1];
-+#else
-+						in->yst_uid = oh->yst_uid;
-+						in->yst_gid = oh->yst_gid;
-+						in->yst_atime = oh->yst_atime;
-+						in->yst_mtime = oh->yst_mtime;
-+						in->yst_ctime = oh->yst_ctime;
-+						in->yst_rdev = oh->yst_rdev;
-+
-+						in->lazy_loaded = 0;
-+
-+#endif
-+					} else
-+						in->lazy_loaded = 1;
-+
-+					in->hdr_chunk = chunk;
-+
-+				} else if (!in->valid) {
-+					/* we need to load this info */
-+
-+					in->valid = 1;
-+					in->hdr_chunk = chunk;
-+
-+					if (oh) {
-+						in->variant_type = oh->type;
-+
-+						in->yst_mode = oh->yst_mode;
-+#ifdef CONFIG_YAFFS_WINCE
-+						in->win_atime[0] = oh->win_atime[0];
-+						in->win_ctime[0] = oh->win_ctime[0];
-+						in->win_mtime[0] = oh->win_mtime[0];
-+						in->win_atime[1] = oh->win_atime[1];
-+						in->win_ctime[1] = oh->win_ctime[1];
-+						in->win_mtime[1] = oh->win_mtime[1];
-+#else
-+						in->yst_uid = oh->yst_uid;
-+						in->yst_gid = oh->yst_gid;
-+						in->yst_atime = oh->yst_atime;
-+						in->yst_mtime = oh->yst_mtime;
-+						in->yst_ctime = oh->yst_ctime;
-+						in->yst_rdev = oh->yst_rdev;
-+#endif
-+
-+						if (oh->shadows_obj > 0)
-+							yaffs_handle_shadowed_obj(dev,
-+									   oh->
-+									   shadows_obj,
-+									   1);
-+							
-+
-+
-+						yaffs_set_obj_name_from_oh(in, oh);
-+						parent =
-+						    yaffs_find_or_create_by_number
-+							(dev, oh->parent_obj_id,
-+							 YAFFS_OBJECT_TYPE_DIRECTORY);
-+
-+						 file_size = oh->file_size;
-+						 is_shrink = oh->is_shrink;
-+						 equiv_id = oh->equiv_id;
-+
-+					} else {
-+						in->variant_type = tags.extra_obj_type;
-+						parent =
-+						    yaffs_find_or_create_by_number
-+							(dev, tags.extra_parent_id,
-+							 YAFFS_OBJECT_TYPE_DIRECTORY);
-+						 file_size = tags.extra_length;
-+						 is_shrink = tags.extra_is_shrink;
-+						 equiv_id = tags.extra_equiv_id;
-+						in->lazy_loaded = 1;
-+
-+					}
-+					in->dirty = 0;
-+
-+					if (!parent)
-+						alloc_failed = 1;
-+
-+					/* directory stuff...
-+					 * hook up to parent
-+					 */
-+
-+					if (parent && parent->variant_type ==
-+					    YAFFS_OBJECT_TYPE_UNKNOWN) {
-+						/* Set up as a directory */
-+						parent->variant_type =
-+							YAFFS_OBJECT_TYPE_DIRECTORY;
-+						YINIT_LIST_HEAD(&parent->variant.
-+							dir_variant.
-+							children);
-+					} else if (!parent || parent->variant_type !=
-+						   YAFFS_OBJECT_TYPE_DIRECTORY) {
-+						/* Hoosterman, another problem....
-+						 * We're trying to use a non-directory as a directory
-+						 */
-+
-+						T(YAFFS_TRACE_ERROR,
-+						  (TSTR
-+						   ("yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
-+						    TENDSTR)));
-+						parent = dev->lost_n_found;
-+					}
-+
-+					yaffs_add_obj_to_dir(parent, in);
-+
-+					itsUnlinked = (parent == dev->del_dir) ||
-+						      (parent == dev->unlinked_dir);
-+
-+					if (is_shrink) {
-+						/* Mark the block as having a shrinkHeader */
-+						bi->has_shrink_hdr = 1;
-+					}
-+
-+					/* Note re hardlinks.
-+					 * Since we might scan a hardlink before its equivalent object is scanned
-+					 * we put them all in a list.
-+					 * After scanning is complete, we should have all the objects, so we run
-+					 * through this list and fix up all the chains.
-+					 */
-+
-+					switch (in->variant_type) {
-+					case YAFFS_OBJECT_TYPE_UNKNOWN:
-+						/* Todo got a problem */
-+						break;
-+					case YAFFS_OBJECT_TYPE_FILE:
-+
-+						if (in->variant.file_variant.
-+						    scanned_size < file_size) {
-+							/* This covers the case where the file size is greater
-+							 * than where the data is
-+							 * This will happen if the file is resized to be larger
-+							 * than its current data extents.
-+							 */
-+							in->variant.file_variant.file_size = file_size;
-+							in->variant.file_variant.scanned_size = file_size;
-+						}
-+
-+						if (in->variant.file_variant.shrink_size > file_size)
-+							in->variant.file_variant.shrink_size = file_size;
-+				
-+
-+						break;
-+					case YAFFS_OBJECT_TYPE_HARDLINK:
-+						if (!itsUnlinked) {
-+							in->variant.hardlink_variant.equiv_id =
-+								equiv_id;
-+							in->hard_links.next =
-+								(struct ylist_head *) hard_list;
-+							hard_list = in;
-+						}
-+						break;
-+					case YAFFS_OBJECT_TYPE_DIRECTORY:
-+						/* Do nothing */
-+						break;
-+					case YAFFS_OBJECT_TYPE_SPECIAL:
-+						/* Do nothing */
-+						break;
-+					case YAFFS_OBJECT_TYPE_SYMLINK:
-+						if (oh) {
-+							in->variant.symlink_variant.alias =
-+								yaffs_clone_str(oh->alias);
-+							if (!in->variant.symlink_variant.alias)
-+								alloc_failed = 1;
-+						}
-+						break;
-+					}
-+
-+				}
-+
-+			}
-+
-+		} /* End of scanning for each chunk */
-+
-+		if (state == YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
-+			/* If we got this far while scanning, then the block is fully allocated. */
-+			state = YAFFS_BLOCK_STATE_FULL;
-+		}
-+
-+
-+		bi->block_state = state;
-+
-+		/* Now let's see if it was dirty */
-+		if (bi->pages_in_use == 0 &&
-+		    !bi->has_shrink_hdr &&
-+		    bi->block_state == YAFFS_BLOCK_STATE_FULL) {
-+			yaffs_block_became_dirty(dev, blk);
-+		}
-+
-+	}
-+	
-+	yaffs_skip_rest_of_block(dev);
-+
-+	if (altBlockIndex)
-+		YFREE_ALT(blockIndex);
-+	else
-+		YFREE(blockIndex);
-+
-+	/* Ok, we've done all the scanning.
-+	 * Fix up the hard link chains.
-+	 * We should now have scanned all the objects, now it's time to add these
-+	 * hardlinks.
-+	 */
-+	yaffs_link_fixup(dev, hard_list);
-+
-+
-+	yaffs_release_temp_buffer(dev, chunkData, __LINE__);
-+
-+	if (alloc_failed)
-+		return YAFFS_FAIL;
-+
-+	T(YAFFS_TRACE_SCAN, (TSTR("yaffs2_scan_backwards ends" TENDSTR)));
-+
-+	return YAFFS_OK;
-+}
---- /dev/null
-+++ b/fs/yaffs2/yaffs_yaffs2.h
-@@ -0,0 +1,36 @@
-+/*
-+ * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
-+ *
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-+ *   for Toby Churchill Ltd and Brightstar Engineering
-+ *
-+ * Created by Charles Manning <charles@aleph1.co.uk>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#ifndef __YAFFS_YAFFS2_H__
-+#define __YAFFS_YAFFS2_H__
-+
-+#include "yaffs_guts.h"
-+
-+void yaffs_calc_oldest_dirty_seq(yaffs_dev_t *dev);
-+void yaffs2_find_oldest_dirty_seq(yaffs_dev_t *dev);
-+void yaffs2_clear_oldest_dirty_seq(yaffs_dev_t *dev, yaffs_block_info_t *bi);
-+void yaffs2_update_oldest_dirty_seq(yaffs_dev_t *dev, unsigned block_no, yaffs_block_info_t *bi);
-+int yaffs_block_ok_for_gc(yaffs_dev_t *dev, yaffs_block_info_t *bi);
-+__u32 yaffs2_find_refresh_block(yaffs_dev_t *dev);
-+int yaffs2_checkpt_required(yaffs_dev_t *dev);
-+int yaffs_calc_checkpt_blocks_required(yaffs_dev_t *dev);
-+
-+
-+void yaffs2_checkpt_invalidate(yaffs_dev_t *dev);
-+int yaffs2_checkpt_save(yaffs_dev_t *dev);
-+int yaffs2_checkpt_restore(yaffs_dev_t *dev);
-+
-+int yaffs2_handle_hole(yaffs_obj_t *obj, loff_t new_size);
-+int yaffs2_scan_backwards(yaffs_dev_t *dev);
-+
-+#endif
---- a/fs/yaffs2/yportenv.h
-+++ b/fs/yaffs2/yportenv.h
-@@ -1,7 +1,7 @@
- /*
-  * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
-  *
-- * Copyright (C) 2002-2007 Aleph One Ltd.
-+ * Copyright (C) 2002-2010 Aleph One Ltd.
-  *   for Toby Churchill Ltd and Brightstar Engineering
-  *
-  * Created by Charles Manning <charles@aleph1.co.uk>
-@@ -41,12 +41,14 @@
- #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
- #include <linux/config.h>
- #endif
-+
- #include <linux/kernel.h>
- #include <linux/mm.h>
- #include <linux/sched.h>
- #include <linux/string.h>
- #include <linux/slab.h>
- #include <linux/vmalloc.h>
-+#include <linux/xattr.h>
- 
- #define YCHAR char
- #define YUCHAR unsigned char
-@@ -55,11 +57,11 @@
- #define yaffs_strcpy(a, b)     strcpy(a, b)
- #define yaffs_strncpy(a, b, c) strncpy(a, b, c)
- #define yaffs_strncmp(a, b, c) strncmp(a, b, c)
--#define yaffs_strlen(s)	       strlen(s)
-+#define yaffs_strnlen(s,m)	strnlen(s,m)
- #define yaffs_sprintf	       sprintf
- #define yaffs_toupper(a)       toupper(a)
- 
--#define Y_INLINE inline
-+#define Y_INLINE __inline__
- 
- #define YAFFS_LOSTNFOUND_NAME		"lost+found"
- #define YAFFS_LOSTNFOUND_PREFIX		"obj"
-@@ -71,11 +73,11 @@
- #define YFREE_ALT(x)   vfree(x)
- #define YMALLOC_DMA(x) YMALLOC(x)
- 
--/* KR - added for use in scan so processes aren't blocked indefinitely. */
- #define YYIELD() schedule()
-+#define Y_DUMP_STACK() dump_stack()
- 
--#define YAFFS_ROOT_MODE			0666
--#define YAFFS_LOSTNFOUND_MODE		0666
-+#define YAFFS_ROOT_MODE			0755
-+#define YAFFS_LOSTNFOUND_MODE		0700
- 
- #if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
- #define Y_CURRENT_TIME CURRENT_TIME.tv_sec
-@@ -85,19 +87,14 @@
- #define Y_TIME_CONVERT(x) (x)
- #endif
- 
--#define yaffs_SumCompare(x, y) ((x) == (y))
-+#define yaffs_sum_cmp(x, y) ((x) == (y))
- #define yaffs_strcmp(a, b) strcmp(a, b)
- 
- #define TENDSTR "\n"
--#define TSTR(x) KERN_WARNING x
-+#define TSTR(x) KERN_DEBUG x
- #define TCONT(x) x
- #define TOUT(p) printk p
- 
--#define yaffs_trace(mask, fmt, args...) \
--	do { if ((mask) & (yaffs_traceMask|YAFFS_TRACE_ERROR)) \
--		printk(KERN_WARNING "yaffs: " fmt, ## args); \
--	} while (0)
--
- #define compile_time_assertion(assertion) \
- 	({ int x = __builtin_choose_expr(assertion, 0, (void)0); (void) x; })
- 
-@@ -116,7 +113,6 @@
- #include "stdio.h"
- #include "string.h"
- 
--#include "devextras.h"
- 
- #define YMALLOC(x) malloc(x)
- #define YFREE(x)   free(x)
-@@ -129,7 +125,7 @@
- #define yaffs_strcat(a, b)     strcat(a, b)
- #define yaffs_strcpy(a, b)     strcpy(a, b)
- #define yaffs_strncpy(a, b, c) strncpy(a, b, c)
--#define yaffs_strlen(s)	       strlen(s)
-+#define yaffs_strnlen(s,m)	       strnlen(s,m)
- #define yaffs_sprintf	       sprintf
- #define yaffs_toupper(a)       toupper(a)
- 
-@@ -146,10 +142,10 @@
- #define YAFFS_LOSTNFOUND_PREFIX		"obj"
- /* #define YPRINTF(x) printf x */
- 
--#define YAFFS_ROOT_MODE				0666
--#define YAFFS_LOSTNFOUND_MODE		0666
-+#define YAFFS_ROOT_MODE			0755
-+#define YAFFS_LOSTNFOUND_MODE		0700
- 
--#define yaffs_SumCompare(x, y) ((x) == (y))
-+#define yaffs_sum_cmp(x, y) ((x) == (y))
- #define yaffs_strcmp(a, b) strcmp(a, b)
- 
- #else
-@@ -158,46 +154,180 @@
- 
- #endif
- 
--/* see yaffs_fs.c */
--extern unsigned int yaffs_traceMask;
--extern unsigned int yaffs_wr_attempts;
-+#if defined(CONFIG_YAFFS_DIRECT) || defined(CONFIG_YAFFS_WINCE)
- 
--/*
-- * Tracing flags.
-- * The flags masked in YAFFS_TRACE_ALWAYS are always traced.
-- */
-+#ifdef CONFIG_YAFFSFS_PROVIDE_VALUES
-+
-+#ifndef O_RDONLY
-+#define O_RDONLY        00
-+#endif
-+
-+#ifndef O_WRONLY
-+#define O_WRONLY	01
-+#endif
-+
-+#ifndef O_RDWR
-+#define O_RDWR		02
-+#endif
-+
-+#ifndef O_CREAT		
-+#define O_CREAT 	0100
-+#endif
-+
-+#ifndef O_EXCL
-+#define O_EXCL		0200
-+#endif
-+
-+#ifndef O_TRUNC
-+#define O_TRUNC		01000
-+#endif
-+
-+#ifndef O_APPEND
-+#define O_APPEND	02000
-+#endif
-+
-+#ifndef SEEK_SET
-+#define SEEK_SET	0
-+#endif
-+
-+#ifndef SEEK_CUR
-+#define SEEK_CUR	1
-+#endif
-+
-+#ifndef SEEK_END
-+#define SEEK_END	2
-+#endif
-+
-+#ifndef EBUSY
-+#define EBUSY	16
-+#endif
-+
-+#ifndef ENODEV
-+#define ENODEV	19
-+#endif
-+
-+#ifndef EINVAL
-+#define EINVAL	22
-+#endif
-+
-+#ifndef EBADF
-+#define EBADF	9
-+#endif
-+
-+#ifndef EACCES
-+#define EACCES	13
-+#endif
-+
-+#ifndef EXDEV	
-+#define EXDEV	18
-+#endif
-+
-+#ifndef ENOENT
-+#define ENOENT	2
-+#endif
-+
-+#ifndef ENOSPC
-+#define ENOSPC	28
-+#endif
-+
-+#ifndef ERANGE
-+#define ERANGE 34
-+#endif
-+
-+#ifndef ENODATA
-+#define ENODATA 61
-+#endif
-+
-+#ifndef ENOTEMPTY
-+#define ENOTEMPTY 39
-+#endif
-+
-+#ifndef ENAMETOOLONG
-+#define ENAMETOOLONG 36
-+#endif
-+
-+#ifndef ENOMEM
-+#define ENOMEM 12
-+#endif
-+
-+#ifndef EEXIST
-+#define EEXIST 17
-+#endif
-+
-+#ifndef ENOTDIR
-+#define ENOTDIR 20
-+#endif
-+
-+#ifndef EISDIR
-+#define EISDIR 21
-+#endif
-+
-+
-+// Mode flags
-+
-+#ifndef S_IFMT
-+#define S_IFMT		0170000
-+#endif
-+
-+#ifndef S_IFLNK
-+#define S_IFLNK		0120000
-+#endif
- 
--#define YAFFS_TRACE_OS			0x00000002
--#define YAFFS_TRACE_ALLOCATE		0x00000004
--#define YAFFS_TRACE_SCAN		0x00000008
--#define YAFFS_TRACE_BAD_BLOCKS		0x00000010
--#define YAFFS_TRACE_ERASE		0x00000020
--#define YAFFS_TRACE_GC			0x00000040
--#define YAFFS_TRACE_WRITE		0x00000080
--#define YAFFS_TRACE_TRACING		0x00000100
--#define YAFFS_TRACE_DELETION		0x00000200
--#define YAFFS_TRACE_BUFFERS		0x00000400
--#define YAFFS_TRACE_NANDACCESS		0x00000800
--#define YAFFS_TRACE_GC_DETAIL		0x00001000
--#define YAFFS_TRACE_SCAN_DEBUG		0x00002000
--#define YAFFS_TRACE_MTD			0x00004000
--#define YAFFS_TRACE_CHECKPOINT		0x00008000
--
--#define YAFFS_TRACE_VERIFY		0x00010000
--#define YAFFS_TRACE_VERIFY_NAND		0x00020000
--#define YAFFS_TRACE_VERIFY_FULL		0x00040000
--#define YAFFS_TRACE_VERIFY_ALL		0x000F0000
--
--
--#define YAFFS_TRACE_ERROR		0x40000000
--#define YAFFS_TRACE_BUG			0x80000000
--#define YAFFS_TRACE_ALWAYS		0xF0000000
-+#ifndef S_IFDIR
-+#define S_IFDIR		0040000
-+#endif
-+
-+#ifndef S_IFREG
-+#define S_IFREG		0100000
-+#endif
- 
-+#ifndef S_IREAD 
-+#define S_IREAD		0000400
-+#endif
-+
-+#ifndef S_IWRITE
-+#define	S_IWRITE	0000200
-+#endif
- 
--#define T(mask, p) do { if ((mask) & (yaffs_traceMask | YAFFS_TRACE_ALWAYS)) TOUT(p); } while (0)
-+#ifndef S_IEXEC
-+#define	S_IEXEC	0000100
-+#endif
-+
-+#ifndef XATTR_CREATE
-+#define XATTR_CREATE 1
-+#endif
-+
-+#ifndef XATTR_REPLACE
-+#define XATTR_REPLACE 2
-+#endif
-+
-+#ifndef R_OK
-+#define R_OK	4
-+#define W_OK	2
-+#define X_OK	1
-+#define F_OK	0
-+#endif
-+
-+#else
-+#include <errno.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#endif
-+
-+#endif
-+
-+#ifndef Y_DUMP_STACK
-+#define Y_DUMP_STACK() do { } while (0)
-+#endif
- 
- #ifndef YBUG
--#define YBUG() do {T(YAFFS_TRACE_BUG, (TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR), __LINE__)); } while (0)
-+#define YBUG() do {\
-+	T(YAFFS_TRACE_BUG,\
-+		(TSTR("==>> yaffs bug: " __FILE__ " %d" TENDSTR),\
-+		__LINE__));\
-+	Y_DUMP_STACK();\
-+} while (0)
- #endif
- 
-+
- #endif
diff --git a/target/linux/generic/patches-2.6.38/503-yaffs_symlink_bug.patch b/target/linux/generic/patches-2.6.38/503-yaffs_symlink_bug.patch
deleted file mode 100644
index dabf2871bf..0000000000
--- a/target/linux/generic/patches-2.6.38/503-yaffs_symlink_bug.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- a/fs/yaffs2/yaffs_guts.c
-+++ b/fs/yaffs2/yaffs_guts.c
-@@ -1709,11 +1709,11 @@ static int yaffs_change_obj_name(yaffs_o
- 	}
- 
- 	/* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
--	if (obj->my_dev->param.is_yaffs2)
-+	// if (obj->my_dev->param.is_yaffs2) 
- 		unlinkOp = (new_dir == obj->my_dev->unlinked_dir);
--	else
-+	/* else
- 		unlinkOp = (new_dir == obj->my_dev->unlinked_dir
--			    && obj->variant_type == YAFFS_OBJECT_TYPE_FILE);
-+			    && obj->variant_type == YAFFS_OBJECT_TYPE_FILE); */
- 
- 	deleteOp = (new_dir == obj->my_dev->del_dir);
- 
diff --git a/target/linux/generic/patches-2.6.38/504-yaffs_mutex_fix.patch b/target/linux/generic/patches-2.6.38/504-yaffs_mutex_fix.patch
deleted file mode 100644
index b34b12f785..0000000000
--- a/target/linux/generic/patches-2.6.38/504-yaffs_mutex_fix.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/fs/yaffs2/yaffs_vfs_glue.c
-+++ b/fs/yaffs2/yaffs_vfs_glue.c
-@@ -3036,7 +3036,7 @@ static struct super_block *yaffs_interna
-         YINIT_LIST_HEAD(&(yaffs_dev_to_lc(dev)->searchContexts));
-         param->remove_obj_fn = yaffs_remove_obj_callback;
- 
--	init_MUTEX(&(yaffs_dev_to_lc(dev)->grossLock));
-+	sema_init(&(yaffs_dev_to_lc(dev)->grossLock), 1);
- 
- 	yaffs_gross_lock(dev);
- 
-@@ -3494,7 +3494,7 @@ static int __init init_yaffs_fs(void)
- 
- 
- 
--	init_MUTEX(&yaffs_context_lock);
-+	sema_init((&yaffs_context_lock), 1);
- 
- 	/* Install the proc_fs entries */
- 	my_proc_entry = create_proc_entry("yaffs",
diff --git a/target/linux/generic/patches-2.6.38/510-jffs2_make_lzma_available.patch b/target/linux/generic/patches-2.6.38/510-jffs2_make_lzma_available.patch
deleted file mode 100644
index f1ad92d7c0..0000000000
--- a/target/linux/generic/patches-2.6.38/510-jffs2_make_lzma_available.patch
+++ /dev/null
@@ -1,5142 +0,0 @@
---- a/fs/jffs2/Kconfig
-+++ b/fs/jffs2/Kconfig
-@@ -139,6 +139,15 @@ config JFFS2_LZO
- 	  This feature was added in July, 2007. Say 'N' if you need
- 	  compatibility with older bootloaders or kernels.
- 
-+config JFFS2_LZMA
-+	bool "JFFS2 LZMA compression support" if JFFS2_COMPRESSION_OPTIONS
-+	select LZMA_COMPRESS
-+	select LZMA_DECOMPRESS
-+	depends on JFFS2_FS
-+	default n
-+	help
-+	  JFFS2 wrapper to the LZMA C SDK
-+
- config JFFS2_RTIME
- 	bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
- 	depends on JFFS2_FS
---- a/fs/jffs2/Makefile
-+++ b/fs/jffs2/Makefile
-@@ -18,4 +18,7 @@ jffs2-$(CONFIG_JFFS2_RUBIN)	+= compr_rub
- jffs2-$(CONFIG_JFFS2_RTIME)	+= compr_rtime.o
- jffs2-$(CONFIG_JFFS2_ZLIB)	+= compr_zlib.o
- jffs2-$(CONFIG_JFFS2_LZO)	+= compr_lzo.o
-+jffs2-$(CONFIG_JFFS2_LZMA)      += compr_lzma.o
- jffs2-$(CONFIG_JFFS2_SUMMARY)   += summary.o
-+
-+CFLAGS_compr_lzma.o += -Iinclude/linux -Ilib/lzma
---- a/fs/jffs2/compr.c
-+++ b/fs/jffs2/compr.c
-@@ -320,6 +320,9 @@ int __init jffs2_compressors_init(void)
- #ifdef CONFIG_JFFS2_LZO
- 	jffs2_lzo_init();
- #endif
-+#ifdef CONFIG_JFFS2_LZMA
-+        jffs2_lzma_init();
-+#endif
- /* Setting default compression mode */
- #ifdef CONFIG_JFFS2_CMODE_NONE
- 	jffs2_compression_mode = JFFS2_COMPR_MODE_NONE;
-@@ -343,6 +346,9 @@ int __init jffs2_compressors_init(void)
- int jffs2_compressors_exit(void)
- {
- /* Unregistering compressors */
-+#ifdef CONFIG_JFFS2_LZMA
-+        jffs2_lzma_exit();
-+#endif
- #ifdef CONFIG_JFFS2_LZO
- 	jffs2_lzo_exit();
- #endif
---- a/fs/jffs2/compr.h
-+++ b/fs/jffs2/compr.h
-@@ -29,9 +29,9 @@
- #define JFFS2_DYNRUBIN_PRIORITY  20
- #define JFFS2_LZARI_PRIORITY     30
- #define JFFS2_RTIME_PRIORITY     50
--#define JFFS2_ZLIB_PRIORITY      60
--#define JFFS2_LZO_PRIORITY       80
--
-+#define JFFS2_LZMA_PRIORITY      70
-+#define JFFS2_ZLIB_PRIORITY      80
-+#define JFFS2_LZO_PRIORITY       90
- 
- #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */
- #define JFFS2_DYNRUBIN_DISABLED  /*	   for decompression */
-@@ -99,5 +99,9 @@ void jffs2_zlib_exit(void);
- int jffs2_lzo_init(void);
- void jffs2_lzo_exit(void);
- #endif
-+#ifdef CONFIG_JFFS2_LZMA
-+int jffs2_lzma_init(void);
-+void jffs2_lzma_exit(void);
-+#endif
- 
- #endif /* __JFFS2_COMPR_H__ */
---- /dev/null
-+++ b/fs/jffs2/compr_lzma.c
-@@ -0,0 +1,128 @@
-+/*
-+ * JFFS2 -- Journalling Flash File System, Version 2.
-+ *
-+ * For licensing information, see the file 'LICENCE' in this directory.
-+ *
-+ * JFFS2 wrapper to the LZMA C SDK
-+ *
-+ */
-+
-+#include <linux/lzma.h>
-+#include "compr.h"
-+
-+#ifdef __KERNEL__
-+	static DEFINE_MUTEX(deflate_mutex);
-+#endif
-+
-+CLzmaEncHandle *p;
-+Byte propsEncoded[LZMA_PROPS_SIZE];
-+SizeT propsSize = sizeof(propsEncoded);
-+
-+STATIC void lzma_free_workspace(void)
-+{
-+	LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc);
-+}
-+
-+STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props)
-+{
-+	if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL)
-+	{
-+		PRINT_ERROR("Failed to allocate lzma deflate workspace\n");
-+		return -ENOMEM;
-+	}
-+
-+	if (LzmaEnc_SetProps(p, props) != SZ_OK)
-+	{
-+		lzma_free_workspace();
-+		return -1;
-+	}
-+	
-+	if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK)
-+	{
-+		lzma_free_workspace();
-+		return -1;
-+	}
-+
-+        return 0;
-+}
-+
-+STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out,
-+			      uint32_t *sourcelen, uint32_t *dstlen)
-+{
-+	SizeT compress_size = (SizeT)(*dstlen);
-+	int ret;
-+
-+	#ifdef __KERNEL__
-+		mutex_lock(&deflate_mutex);
-+	#endif
-+
-+	ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen,
-+		0, NULL, &lzma_alloc, &lzma_alloc);
-+
-+	#ifdef __KERNEL__
-+		mutex_unlock(&deflate_mutex);
-+	#endif
-+
-+	if (ret != SZ_OK)
-+		return -1;
-+
-+	*dstlen = (uint32_t)compress_size;
-+
-+	return 0;
-+}
-+
-+STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out,
-+				 uint32_t srclen, uint32_t destlen)
-+{
-+	int ret;
-+	SizeT dl = (SizeT)destlen;
-+	SizeT sl = (SizeT)srclen;
-+	ELzmaStatus status;
-+	
-+	ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded,
-+		propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc);
-+
-+	if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen)
-+		return -1;
-+
-+	return 0;
-+}
-+
-+static struct jffs2_compressor jffs2_lzma_comp = {
-+	.priority = JFFS2_LZMA_PRIORITY,
-+	.name = "lzma",
-+	.compr = JFFS2_COMPR_LZMA,
-+	.compress = &jffs2_lzma_compress,
-+	.decompress = &jffs2_lzma_decompress,
-+	.disabled = 0,
-+};
-+
-+int INIT jffs2_lzma_init(void)
-+{
-+        int ret;
-+	CLzmaEncProps props;
-+	LzmaEncProps_Init(&props);
-+
-+        props.dictSize = LZMA_BEST_DICT(0x2000);
-+        props.level = LZMA_BEST_LEVEL;
-+        props.lc = LZMA_BEST_LC;
-+        props.lp = LZMA_BEST_LP;
-+        props.pb = LZMA_BEST_PB;
-+        props.fb = LZMA_BEST_FB;
-+
-+	ret = lzma_alloc_workspace(&props);
-+        if (ret < 0)
-+                return ret;
-+
-+	ret = jffs2_register_compressor(&jffs2_lzma_comp);
-+	if (ret)
-+		lzma_free_workspace();
-+	
-+        return ret;
-+}
-+
-+void jffs2_lzma_exit(void)
-+{
-+	jffs2_unregister_compressor(&jffs2_lzma_comp);
-+	lzma_free_workspace();
-+}
---- a/fs/jffs2/super.c
-+++ b/fs/jffs2/super.c
-@@ -255,14 +255,41 @@ static int __init init_jffs2_fs(void)
- 	BUILD_BUG_ON(sizeof(struct jffs2_raw_inode) != 68);
- 	BUILD_BUG_ON(sizeof(struct jffs2_raw_summary) != 32);
- 
--	printk(KERN_INFO "JFFS2 version 2.2."
-+	printk(KERN_INFO "JFFS2 version 2.2"
- #ifdef CONFIG_JFFS2_FS_WRITEBUFFER
- 	       " (NAND)"
- #endif
- #ifdef CONFIG_JFFS2_SUMMARY
--	       " (SUMMARY) "
-+	       " (SUMMARY)"
- #endif
--	       " © 2001-2006 Red Hat, Inc.\n");
-+#ifdef CONFIG_JFFS2_ZLIB
-+	       " (ZLIB)"
-+#endif
-+#ifdef CONFIG_JFFS2_LZO
-+	       " (LZO)"
-+#endif
-+#ifdef CONFIG_JFFS2_LZMA
-+	       " (LZMA)"
-+#endif
-+#ifdef CONFIG_JFFS2_RTIME
-+	       " (RTIME)"
-+#endif
-+#ifdef CONFIG_JFFS2_RUBIN
-+	       " (RUBIN)"
-+#endif
-+#ifdef  CONFIG_JFFS2_CMODE_NONE
-+	       " (CMODE_NONE)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_PRIORITY
-+	       " (CMODE_PRIORITY)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_SIZE
-+	       " (CMODE_SIZE)"
-+#endif
-+#ifdef CONFIG_JFFS2_CMODE_FAVOURLZO
-+	       " (CMODE_FAVOURLZO)"
-+#endif
-+	       " (c) 2001-2006 Red Hat, Inc.\n");
- 
- 	jffs2_inode_cachep = kmem_cache_create("jffs2_i",
- 					     sizeof(struct jffs2_inode_info),
---- a/include/linux/jffs2.h
-+++ b/include/linux/jffs2.h
-@@ -46,6 +46,7 @@
- #define JFFS2_COMPR_DYNRUBIN	0x05
- #define JFFS2_COMPR_ZLIB	0x06
- #define JFFS2_COMPR_LZO		0x07
-+#define JFFS2_COMPR_LZMA	0x08
- /* Compatibility flags. */
- #define JFFS2_COMPAT_MASK 0xc000      /* What do to if an unknown nodetype is found */
- #define JFFS2_NODE_ACCURATE 0x2000
---- /dev/null
-+++ b/include/linux/lzma.h
-@@ -0,0 +1,62 @@
-+#ifndef __LZMA_H__
-+#define __LZMA_H__
-+
-+#ifdef __KERNEL__
-+	#include <linux/kernel.h>
-+	#include <linux/sched.h>
-+	#include <linux/slab.h>
-+	#include <linux/vmalloc.h>
-+	#include <linux/init.h>
-+	#define LZMA_MALLOC vmalloc
-+	#define LZMA_FREE vfree
-+	#define PRINT_ERROR(msg) printk(KERN_WARNING #msg)
-+	#define INIT __init
-+	#define STATIC static
-+#else
-+	#include <stdint.h>
-+	#include <stdlib.h>
-+	#include <stdio.h>
-+	#include <unistd.h>
-+	#include <string.h>
-+	#include <asm/types.h>
-+	#include <errno.h>
-+	#include <linux/jffs2.h>
-+	#ifndef PAGE_SIZE
-+		extern int page_size;
-+		#define PAGE_SIZE page_size
-+	#endif
-+	#define LZMA_MALLOC malloc
-+	#define LZMA_FREE free
-+	#define PRINT_ERROR(msg) fprintf(stderr, msg)
-+	#define INIT
-+	#define STATIC
-+#endif
-+
-+#include "lzma/LzmaDec.h"
-+#include "lzma/LzmaEnc.h"
-+
-+#define LZMA_BEST_LEVEL (9)
-+#define LZMA_BEST_LC    (0)
-+#define LZMA_BEST_LP    (0)
-+#define LZMA_BEST_PB    (0)
-+#define LZMA_BEST_FB  (273)
-+
-+#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2)
-+
-+static void *p_lzma_malloc(void *p, size_t size)
-+{
-+        if (size == 0)
-+                return NULL;
-+
-+        return LZMA_MALLOC(size);
-+}
-+
-+static void p_lzma_free(void *p, void *address)
-+{
-+        if (address != NULL)
-+                LZMA_FREE(address);
-+}
-+
-+static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free};
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzFind.h
-@@ -0,0 +1,115 @@
-+/* LzFind.h -- Match finder for LZ algorithms
-+2009-04-22 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZ_FIND_H
-+#define __LZ_FIND_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+typedef UInt32 CLzRef;
-+
-+typedef struct _CMatchFinder
-+{
-+  Byte *buffer;
-+  UInt32 pos;
-+  UInt32 posLimit;
-+  UInt32 streamPos;
-+  UInt32 lenLimit;
-+
-+  UInt32 cyclicBufferPos;
-+  UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
-+
-+  UInt32 matchMaxLen;
-+  CLzRef *hash;
-+  CLzRef *son;
-+  UInt32 hashMask;
-+  UInt32 cutValue;
-+
-+  Byte *bufferBase;
-+  ISeqInStream *stream;
-+  int streamEndWasReached;
-+
-+  UInt32 blockSize;
-+  UInt32 keepSizeBefore;
-+  UInt32 keepSizeAfter;
-+
-+  UInt32 numHashBytes;
-+  int directInput;
-+  size_t directInputRem;
-+  int btMode;
-+  int bigHash;
-+  UInt32 historySize;
-+  UInt32 fixedHashSize;
-+  UInt32 hashSizeSum;
-+  UInt32 numSons;
-+  SRes result;
-+  UInt32 crc[256];
-+} CMatchFinder;
-+
-+#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
-+#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
-+
-+#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
-+
-+int MatchFinder_NeedMove(CMatchFinder *p);
-+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
-+void MatchFinder_MoveBlock(CMatchFinder *p);
-+void MatchFinder_ReadIfRequired(CMatchFinder *p);
-+
-+void MatchFinder_Construct(CMatchFinder *p);
-+
-+/* Conditions:
-+     historySize <= 3 GB
-+     keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
-+*/
-+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
-+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-+    ISzAlloc *alloc);
-+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
-+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
-+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
-+
-+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
-+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
-+    UInt32 *distances, UInt32 maxLen);
-+
-+/*
-+Conditions:
-+  Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
-+  Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
-+*/
-+
-+typedef void (*Mf_Init_Func)(void *object);
-+typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
-+typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
-+typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
-+typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
-+typedef void (*Mf_Skip_Func)(void *object, UInt32);
-+
-+typedef struct _IMatchFinder
-+{
-+  Mf_Init_Func Init;
-+  Mf_GetIndexByte_Func GetIndexByte;
-+  Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
-+  Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
-+  Mf_GetMatches_Func GetMatches;
-+  Mf_Skip_Func Skip;
-+} IMatchFinder;
-+
-+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
-+
-+void MatchFinder_Init(CMatchFinder *p);
-+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
-+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzHash.h
-@@ -0,0 +1,54 @@
-+/* LzHash.h -- HASH functions for LZ algorithms
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZ_HASH_H
-+#define __LZ_HASH_H
-+
-+#define kHash2Size (1 << 10)
-+#define kHash3Size (1 << 16)
-+#define kHash4Size (1 << 20)
-+
-+#define kFix3HashSize (kHash2Size)
-+#define kFix4HashSize (kHash2Size + kHash3Size)
-+#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
-+
-+#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
-+
-+#define HASH3_CALC { \
-+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+  hash2Value = temp & (kHash2Size - 1); \
-+  hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
-+
-+#define HASH4_CALC { \
-+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+  hash2Value = temp & (kHash2Size - 1); \
-+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+  hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
-+
-+#define HASH5_CALC { \
-+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+  hash2Value = temp & (kHash2Size - 1); \
-+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
-+  hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
-+  hash4Value &= (kHash4Size - 1); }
-+
-+/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
-+#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
-+
-+
-+#define MT_HASH2_CALC \
-+  hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
-+
-+#define MT_HASH3_CALC { \
-+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+  hash2Value = temp & (kHash2Size - 1); \
-+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
-+
-+#define MT_HASH4_CALC { \
-+  UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
-+  hash2Value = temp & (kHash2Size - 1); \
-+  hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
-+  hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzmaDec.h
-@@ -0,0 +1,231 @@
-+/* LzmaDec.h -- LZMA Decoder
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZMA_DEC_H
-+#define __LZMA_DEC_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* #define _LZMA_PROB32 */
-+/* _LZMA_PROB32 can increase the speed on some CPUs,
-+   but memory usage for CLzmaDec::probs will be doubled in that case */
-+
-+#ifdef _LZMA_PROB32
-+#define CLzmaProb UInt32
-+#else
-+#define CLzmaProb UInt16
-+#endif
-+
-+
-+/* ---------- LZMA Properties ---------- */
-+
-+#define LZMA_PROPS_SIZE 5
-+
-+typedef struct _CLzmaProps
-+{
-+  unsigned lc, lp, pb;
-+  UInt32 dicSize;
-+} CLzmaProps;
-+
-+/* LzmaProps_Decode - decodes properties
-+Returns:
-+  SZ_OK
-+  SZ_ERROR_UNSUPPORTED - Unsupported properties
-+*/
-+
-+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
-+
-+
-+/* ---------- LZMA Decoder state ---------- */
-+
-+/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
-+   Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
-+
-+#define LZMA_REQUIRED_INPUT_MAX 20
-+
-+typedef struct
-+{
-+  CLzmaProps prop;
-+  CLzmaProb *probs;
-+  Byte *dic;
-+  const Byte *buf;
-+  UInt32 range, code;
-+  SizeT dicPos;
-+  SizeT dicBufSize;
-+  UInt32 processedPos;
-+  UInt32 checkDicSize;
-+  unsigned state;
-+  UInt32 reps[4];
-+  unsigned remainLen;
-+  int needFlush;
-+  int needInitState;
-+  UInt32 numProbs;
-+  unsigned tempBufSize;
-+  Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
-+} CLzmaDec;
-+
-+#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
-+
-+void LzmaDec_Init(CLzmaDec *p);
-+
-+/* There are two types of LZMA streams:
-+     0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
-+     1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
-+
-+typedef enum
-+{
-+  LZMA_FINISH_ANY,   /* finish at any point */
-+  LZMA_FINISH_END    /* block must be finished at the end */
-+} ELzmaFinishMode;
-+
-+/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
-+
-+   You must use LZMA_FINISH_END, when you know that current output buffer
-+   covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
-+
-+   If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
-+   and output value of destLen will be less than output buffer size limit.
-+   You can check status result also.
-+
-+   You can use multiple checks to test data integrity after full decompression:
-+     1) Check Result and "status" variable.
-+     2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
-+     3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
-+        You must use correct finish mode in that case. */
-+
-+typedef enum
-+{
-+  LZMA_STATUS_NOT_SPECIFIED,               /* use main error code instead */
-+  LZMA_STATUS_FINISHED_WITH_MARK,          /* stream was finished with end mark. */
-+  LZMA_STATUS_NOT_FINISHED,                /* stream was not finished */
-+  LZMA_STATUS_NEEDS_MORE_INPUT,            /* you must provide more input bytes */
-+  LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK  /* there is probability that stream was finished without end mark */
-+} ELzmaStatus;
-+
-+/* ELzmaStatus is used only as output value for function call */
-+
-+
-+/* ---------- Interfaces ---------- */
-+
-+/* There are 3 levels of interfaces:
-+     1) Dictionary Interface
-+     2) Buffer Interface
-+     3) One Call Interface
-+   You can select any of these interfaces, but don't mix functions from different
-+   groups for same object. */
-+
-+
-+/* There are two variants to allocate state for Dictionary Interface:
-+     1) LzmaDec_Allocate / LzmaDec_Free
-+     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
-+   You can use variant 2, if you set dictionary buffer manually.
-+   For Buffer Interface you must always use variant 1.
-+
-+LzmaDec_Allocate* can return:
-+  SZ_OK
-+  SZ_ERROR_MEM         - Memory allocation error
-+  SZ_ERROR_UNSUPPORTED - Unsupported properties
-+*/
-+   
-+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
-+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
-+
-+SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
-+void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
-+
-+/* ---------- Dictionary Interface ---------- */
-+
-+/* You can use it, if you want to eliminate the overhead for data copying from
-+   dictionary to some other external buffer.
-+   You must work with CLzmaDec variables directly in this interface.
-+
-+   STEPS:
-+     LzmaDec_Constr()
-+     LzmaDec_Allocate()
-+     for (each new stream)
-+     {
-+       LzmaDec_Init()
-+       while (it needs more decompression)
-+       {
-+         LzmaDec_DecodeToDic()
-+         use data from CLzmaDec::dic and update CLzmaDec::dicPos
-+       }
-+     }
-+     LzmaDec_Free()
-+*/
-+
-+/* LzmaDec_DecodeToDic
-+   
-+   The decoding to internal dictionary buffer (CLzmaDec::dic).
-+   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
-+
-+finishMode:
-+  It has meaning only if the decoding reaches output limit (dicLimit).
-+  LZMA_FINISH_ANY - Decode just dicLimit bytes.
-+  LZMA_FINISH_END - Stream must be finished after dicLimit.
-+
-+Returns:
-+  SZ_OK
-+    status:
-+      LZMA_STATUS_FINISHED_WITH_MARK
-+      LZMA_STATUS_NOT_FINISHED
-+      LZMA_STATUS_NEEDS_MORE_INPUT
-+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
-+  SZ_ERROR_DATA - Data error
-+*/
-+
-+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
-+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-+
-+
-+/* ---------- Buffer Interface ---------- */
-+
-+/* It's zlib-like interface.
-+   See LzmaDec_DecodeToDic description for information about STEPS and return results,
-+   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
-+   to work with CLzmaDec variables manually.
-+
-+finishMode:
-+  It has meaning only if the decoding reaches output limit (*destLen).
-+  LZMA_FINISH_ANY - Decode just destLen bytes.
-+  LZMA_FINISH_END - Stream must be finished after (*destLen).
-+*/
-+
-+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
-+    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
-+
-+
-+/* ---------- One Call Interface ---------- */
-+
-+/* LzmaDecode
-+
-+finishMode:
-+  It has meaning only if the decoding reaches output limit (*destLen).
-+  LZMA_FINISH_ANY - Decode just destLen bytes.
-+  LZMA_FINISH_END - Stream must be finished after (*destLen).
-+
-+Returns:
-+  SZ_OK
-+    status:
-+      LZMA_STATUS_FINISHED_WITH_MARK
-+      LZMA_STATUS_NOT_FINISHED
-+      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
-+  SZ_ERROR_DATA - Data error
-+  SZ_ERROR_MEM  - Memory allocation error
-+  SZ_ERROR_UNSUPPORTED - Unsupported properties
-+  SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
-+*/
-+
-+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-+    ELzmaStatus *status, ISzAlloc *alloc);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/LzmaEnc.h
-@@ -0,0 +1,80 @@
-+/*  LzmaEnc.h -- LZMA Encoder
-+2009-02-07 : Igor Pavlov : Public domain */
-+
-+#ifndef __LZMA_ENC_H
-+#define __LZMA_ENC_H
-+
-+#include "Types.h"
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define LZMA_PROPS_SIZE 5
-+
-+typedef struct _CLzmaEncProps
-+{
-+  int level;       /*  0 <= level <= 9 */
-+  UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
-+                      (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
-+                       default = (1 << 24) */
-+  int lc;          /* 0 <= lc <= 8, default = 3 */
-+  int lp;          /* 0 <= lp <= 4, default = 0 */
-+  int pb;          /* 0 <= pb <= 4, default = 2 */
-+  int algo;        /* 0 - fast, 1 - normal, default = 1 */
-+  int fb;          /* 5 <= fb <= 273, default = 32 */
-+  int btMode;      /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
-+  int numHashBytes; /* 2, 3 or 4, default = 4 */
-+  UInt32 mc;        /* 1 <= mc <= (1 << 30), default = 32 */
-+  unsigned writeEndMark;  /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
-+  int numThreads;  /* 1 or 2, default = 2 */
-+} CLzmaEncProps;
-+
-+void LzmaEncProps_Init(CLzmaEncProps *p);
-+void LzmaEncProps_Normalize(CLzmaEncProps *p);
-+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
-+
-+
-+/* ---------- CLzmaEncHandle Interface ---------- */
-+
-+/* LzmaEnc_* functions can return the following exit codes:
-+Returns:
-+  SZ_OK           - OK
-+  SZ_ERROR_MEM    - Memory allocation error
-+  SZ_ERROR_PARAM  - Incorrect paramater in props
-+  SZ_ERROR_WRITE  - Write callback error.
-+  SZ_ERROR_PROGRESS - some break from progress callback
-+  SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
-+*/
-+
-+typedef void * CLzmaEncHandle;
-+
-+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
-+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
-+SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
-+SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
-+SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
-+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-+SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-+
-+/* ---------- One Call Interface ---------- */
-+
-+/* LzmaEncode
-+Return code:
-+  SZ_OK               - OK
-+  SZ_ERROR_MEM        - Memory allocation error
-+  SZ_ERROR_PARAM      - Incorrect paramater
-+  SZ_ERROR_OUTPUT_EOF - output buffer overflow
-+  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)
-+*/
-+
-+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif
---- /dev/null
-+++ b/include/linux/lzma/Types.h
-@@ -0,0 +1,226 @@
-+/* Types.h -- Basic types
-+2009-11-23 : Igor Pavlov : Public domain */
-+
-+#ifndef __7Z_TYPES_H
-+#define __7Z_TYPES_H
-+
-+#include <stddef.h>
-+
-+#ifdef _WIN32
-+#include <windows.h>
-+#endif
-+
-+#ifndef EXTERN_C_BEGIN
-+#ifdef __cplusplus
-+#define EXTERN_C_BEGIN extern "C" {
-+#define EXTERN_C_END }
-+#else
-+#define EXTERN_C_BEGIN
-+#define EXTERN_C_END
-+#endif
-+#endif
-+
-+EXTERN_C_BEGIN
-+
-+#define SZ_OK 0
-+
-+#define SZ_ERROR_DATA 1
-+#define SZ_ERROR_MEM 2
-+#define SZ_ERROR_CRC 3
-+#define SZ_ERROR_UNSUPPORTED 4
-+#define SZ_ERROR_PARAM 5
-+#define SZ_ERROR_INPUT_EOF 6
-+#define SZ_ERROR_OUTPUT_EOF 7
-+#define SZ_ERROR_READ 8
-+#define SZ_ERROR_WRITE 9
-+#define SZ_ERROR_PROGRESS 10
-+#define SZ_ERROR_FAIL 11
-+#define SZ_ERROR_THREAD 12
-+
-+#define SZ_ERROR_ARCHIVE 16
-+#define SZ_ERROR_NO_ARCHIVE 17
-+
-+typedef int SRes;
-+
-+#ifdef _WIN32
-+typedef DWORD WRes;
-+#else
-+typedef int WRes;
-+#endif
-+
-+#ifndef RINOK
-+#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
-+#endif
-+
-+typedef unsigned char Byte;
-+typedef short Int16;
-+typedef unsigned short UInt16;
-+
-+#ifdef _LZMA_UINT32_IS_ULONG
-+typedef long Int32;
-+typedef unsigned long UInt32;
-+#else
-+typedef int Int32;
-+typedef unsigned int UInt32;
-+#endif
-+
-+#ifdef _SZ_NO_INT_64
-+
-+/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
-+   NOTES: Some code will work incorrectly in that case! */
-+
-+typedef long Int64;
-+typedef unsigned long UInt64;
-+
-+#else
-+
-+#if defined(_MSC_VER) || defined(__BORLANDC__)
-+typedef __int64 Int64;
-+typedef unsigned __int64 UInt64;
-+#else
-+typedef long long int Int64;
-+typedef unsigned long long int UInt64;
-+#endif
-+
-+#endif
-+
-+#ifdef _LZMA_NO_SYSTEM_SIZE_T
-+typedef UInt32 SizeT;
-+#else
-+typedef size_t SizeT;
-+#endif
-+
-+typedef int Bool;
-+#define True 1
-+#define False 0
-+
-+
-+#ifdef _WIN32
-+#define MY_STD_CALL __stdcall
-+#else
-+#define MY_STD_CALL
-+#endif
-+
-+#ifdef _MSC_VER
-+
-+#if _MSC_VER >= 1300
-+#define MY_NO_INLINE __declspec(noinline)
-+#else
-+#define MY_NO_INLINE
-+#endif
-+
-+#define MY_CDECL __cdecl
-+#define MY_FAST_CALL __fastcall
-+
-+#else
-+
-+#define MY_CDECL
-+#define MY_FAST_CALL
-+
-+#endif
-+
-+
-+/* The following interfaces use first parameter as pointer to structure */
-+
-+typedef struct
-+{
-+  SRes (*Read)(void *p, void *buf, size_t *size);
-+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
-+       (output(*size) < input(*size)) is allowed */
-+} ISeqInStream;
-+
-+/* it can return SZ_ERROR_INPUT_EOF */
-+SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size);
-+SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType);
-+SRes SeqInStream_ReadByte(ISeqInStream *stream, Byte *buf);
-+
-+typedef struct
-+{
-+  size_t (*Write)(void *p, const void *buf, size_t size);
-+    /* Returns: result - the number of actually written bytes.
-+       (result < size) means error */
-+} ISeqOutStream;
-+
-+typedef enum
-+{
-+  SZ_SEEK_SET = 0,
-+  SZ_SEEK_CUR = 1,
-+  SZ_SEEK_END = 2
-+} ESzSeek;
-+
-+typedef struct
-+{
-+  SRes (*Read)(void *p, void *buf, size_t *size);  /* same as ISeqInStream::Read */
-+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-+} ISeekInStream;
-+
-+typedef struct
-+{
-+  SRes (*Look)(void *p, void **buf, size_t *size);
-+    /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
-+       (output(*size) > input(*size)) is not allowed
-+       (output(*size) < input(*size)) is allowed */
-+  SRes (*Skip)(void *p, size_t offset);
-+    /* offset must be <= output(*size) of Look */
-+
-+  SRes (*Read)(void *p, void *buf, size_t *size);
-+    /* reads directly (without buffer). It's same as ISeqInStream::Read */
-+  SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
-+} ILookInStream;
-+
-+SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size);
-+SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
-+
-+/* reads via ILookInStream::Read */
-+SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
-+SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
-+
-+#define LookToRead_BUF_SIZE (1 << 14)
-+
-+typedef struct
-+{
-+  ILookInStream s;
-+  ISeekInStream *realStream;
-+  size_t pos;
-+  size_t size;
-+  Byte buf[LookToRead_BUF_SIZE];
-+} CLookToRead;
-+
-+void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
-+void LookToRead_Init(CLookToRead *p);
-+
-+typedef struct
-+{
-+  ISeqInStream s;
-+  ILookInStream *realStream;
-+} CSecToLook;
-+
-+void SecToLook_CreateVTable(CSecToLook *p);
-+
-+typedef struct
-+{
-+  ISeqInStream s;
-+  ILookInStream *realStream;
-+} CSecToRead;
-+
-+void SecToRead_CreateVTable(CSecToRead *p);
-+
-+typedef struct
-+{
-+  SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
-+    /* Returns: result. (result != SZ_OK) means break.
-+       Value (UInt64)(Int64)-1 for size means unknown value. */
-+} ICompressProgress;
-+
-+typedef struct
-+{
-+  void *(*Alloc)(void *p, size_t size);
-+  void (*Free)(void *p, void *address); /* address can be 0 */
-+} ISzAlloc;
-+
-+#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
-+#define IAlloc_Free(p, a) (p)->Free((p), a)
-+
-+EXTERN_C_END
-+
-+#endif
---- a/lib/Kconfig
-+++ b/lib/Kconfig
-@@ -108,6 +108,12 @@ config LZO_DECOMPRESS
- 
- source "lib/xz/Kconfig"
- 
-+config LZMA_COMPRESS
-+    tristate
-+
-+config LZMA_DECOMPRESS
-+    tristate
-+
- #
- # These all provide a common interface (hence the apparent duplication with
- # ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.)
---- a/lib/Makefile
-+++ b/lib/Makefile
-@@ -2,6 +2,16 @@
- # Makefile for some libs needed in the kernel.
- #
- 
-+ifdef CONFIG_JFFS2_ZLIB
-+	CONFIG_ZLIB_INFLATE:=y
-+	CONFIG_ZLIB_DEFLATE:=y
-+endif
-+
-+ifdef CONFIG_JFFS2_LZMA
-+	CONFIG_LZMA_DECOMPRESS:=y
-+	CONFIG_LZMA_COMPRESS:=y
-+endif
-+
- ifdef CONFIG_FUNCTION_TRACER
- ORIG_CFLAGS := $(KBUILD_CFLAGS)
- KBUILD_CFLAGS = $(subst -pg,,$(ORIG_CFLAGS))
-@@ -73,6 +83,8 @@ obj-$(CONFIG_LZO_COMPRESS) += lzo/
- obj-$(CONFIG_LZO_DECOMPRESS) += lzo/
- obj-$(CONFIG_XZ_DEC) += xz/
- obj-$(CONFIG_RAID6_PQ) += raid6/
-+obj-$(CONFIG_LZMA_COMPRESS) += lzma/
-+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/
- 
- lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
- lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
---- /dev/null
-+++ b/lib/lzma/LzFind.c
-@@ -0,0 +1,761 @@
-+/* LzFind.c -- Match finder for LZ algorithms
-+2009-04-22 : Igor Pavlov : Public domain */
-+
-+#include <string.h>
-+
-+#include "LzFind.h"
-+#include "LzHash.h"
-+
-+#define kEmptyHashValue 0
-+#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
-+#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
-+#define kNormalizeMask (~(kNormalizeStepMin - 1))
-+#define kMaxHistorySize ((UInt32)3 << 30)
-+
-+#define kStartMaxLen 3
-+
-+static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+  if (!p->directInput)
-+  {
-+    alloc->Free(alloc, p->bufferBase);
-+    p->bufferBase = 0;
-+  }
-+}
-+
-+/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
-+
-+static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
-+{
-+  UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
-+  if (p->directInput)
-+  {
-+    p->blockSize = blockSize;
-+    return 1;
-+  }
-+  if (p->bufferBase == 0 || p->blockSize != blockSize)
-+  {
-+    LzInWindow_Free(p, alloc);
-+    p->blockSize = blockSize;
-+    p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
-+  }
-+  return (p->bufferBase != 0);
-+}
-+
-+Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-+Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
-+
-+UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
-+
-+void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
-+{
-+  p->posLimit -= subValue;
-+  p->pos -= subValue;
-+  p->streamPos -= subValue;
-+}
-+
-+static void MatchFinder_ReadBlock(CMatchFinder *p)
-+{
-+  if (p->streamEndWasReached || p->result != SZ_OK)
-+    return;
-+  if (p->directInput)
-+  {
-+    UInt32 curSize = 0xFFFFFFFF - p->streamPos;
-+    if (curSize > p->directInputRem)
-+      curSize = (UInt32)p->directInputRem;
-+    p->directInputRem -= curSize;
-+    p->streamPos += curSize;
-+    if (p->directInputRem == 0)
-+      p->streamEndWasReached = 1;
-+    return;
-+  }
-+  for (;;)
-+  {
-+    Byte *dest = p->buffer + (p->streamPos - p->pos);
-+    size_t size = (p->bufferBase + p->blockSize - dest);
-+    if (size == 0)
-+      return;
-+    p->result = p->stream->Read(p->stream, dest, &size);
-+    if (p->result != SZ_OK)
-+      return;
-+    if (size == 0)
-+    {
-+      p->streamEndWasReached = 1;
-+      return;
-+    }
-+    p->streamPos += (UInt32)size;
-+    if (p->streamPos - p->pos > p->keepSizeAfter)
-+      return;
-+  }
-+}
-+
-+void MatchFinder_MoveBlock(CMatchFinder *p)
-+{
-+  memmove(p->bufferBase,
-+    p->buffer - p->keepSizeBefore,
-+    (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
-+  p->buffer = p->bufferBase + p->keepSizeBefore;
-+}
-+
-+int MatchFinder_NeedMove(CMatchFinder *p)
-+{
-+  if (p->directInput)
-+    return 0;
-+  /* if (p->streamEndWasReached) return 0; */
-+  return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
-+}
-+
-+void MatchFinder_ReadIfRequired(CMatchFinder *p)
-+{
-+  if (p->streamEndWasReached)
-+    return;
-+  if (p->keepSizeAfter >= p->streamPos - p->pos)
-+    MatchFinder_ReadBlock(p);
-+}
-+
-+static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
-+{
-+  if (MatchFinder_NeedMove(p))
-+    MatchFinder_MoveBlock(p);
-+  MatchFinder_ReadBlock(p);
-+}
-+
-+static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
-+{
-+  p->cutValue = 32;
-+  p->btMode = 1;
-+  p->numHashBytes = 4;
-+  p->bigHash = 0;
-+}
-+
-+#define kCrcPoly 0xEDB88320
-+
-+void MatchFinder_Construct(CMatchFinder *p)
-+{
-+  UInt32 i;
-+  p->bufferBase = 0;
-+  p->directInput = 0;
-+  p->hash = 0;
-+  MatchFinder_SetDefaultSettings(p);
-+
-+  for (i = 0; i < 256; i++)
-+  {
-+    UInt32 r = i;
-+    int j;
-+    for (j = 0; j < 8; j++)
-+      r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
-+    p->crc[i] = r;
-+  }
-+}
-+
-+static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+  alloc->Free(alloc, p->hash);
-+  p->hash = 0;
-+}
-+
-+void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
-+{
-+  MatchFinder_FreeThisClassMemory(p, alloc);
-+  LzInWindow_Free(p, alloc);
-+}
-+
-+static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
-+{
-+  size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
-+  if (sizeInBytes / sizeof(CLzRef) != num)
-+    return 0;
-+  return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
-+}
-+
-+int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
-+    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-+    ISzAlloc *alloc)
-+{
-+  UInt32 sizeReserv;
-+  if (historySize > kMaxHistorySize)
-+  {
-+    MatchFinder_Free(p, alloc);
-+    return 0;
-+  }
-+  sizeReserv = historySize >> 1;
-+  if (historySize > ((UInt32)2 << 30))
-+    sizeReserv = historySize >> 2;
-+  sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
-+
-+  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
-+  p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
-+  /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
-+  if (LzInWindow_Create(p, sizeReserv, alloc))
-+  {
-+    UInt32 newCyclicBufferSize = historySize + 1;
-+    UInt32 hs;
-+    p->matchMaxLen = matchMaxLen;
-+    {
-+      p->fixedHashSize = 0;
-+      if (p->numHashBytes == 2)
-+        hs = (1 << 16) - 1;
-+      else
-+      {
-+        hs = historySize - 1;
-+        hs |= (hs >> 1);
-+        hs |= (hs >> 2);
-+        hs |= (hs >> 4);
-+        hs |= (hs >> 8);
-+        hs >>= 1;
-+        hs |= 0xFFFF; /* don't change it! It's required for Deflate */
-+        if (hs > (1 << 24))
-+        {
-+          if (p->numHashBytes == 3)
-+            hs = (1 << 24) - 1;
-+          else
-+            hs >>= 1;
-+        }
-+      }
-+      p->hashMask = hs;
-+      hs++;
-+      if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
-+      if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
-+      if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
-+      hs += p->fixedHashSize;
-+    }
-+
-+    {
-+      UInt32 prevSize = p->hashSizeSum + p->numSons;
-+      UInt32 newSize;
-+      p->historySize = historySize;
-+      p->hashSizeSum = hs;
-+      p->cyclicBufferSize = newCyclicBufferSize;
-+      p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
-+      newSize = p->hashSizeSum + p->numSons;
-+      if (p->hash != 0 && prevSize == newSize)
-+        return 1;
-+      MatchFinder_FreeThisClassMemory(p, alloc);
-+      p->hash = AllocRefs(newSize, alloc);
-+      if (p->hash != 0)
-+      {
-+        p->son = p->hash + p->hashSizeSum;
-+        return 1;
-+      }
-+    }
-+  }
-+  MatchFinder_Free(p, alloc);
-+  return 0;
-+}
-+
-+static void MatchFinder_SetLimits(CMatchFinder *p)
-+{
-+  UInt32 limit = kMaxValForNormalize - p->pos;
-+  UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
-+  if (limit2 < limit)
-+    limit = limit2;
-+  limit2 = p->streamPos - p->pos;
-+  if (limit2 <= p->keepSizeAfter)
-+  {
-+    if (limit2 > 0)
-+      limit2 = 1;
-+  }
-+  else
-+    limit2 -= p->keepSizeAfter;
-+  if (limit2 < limit)
-+    limit = limit2;
-+  {
-+    UInt32 lenLimit = p->streamPos - p->pos;
-+    if (lenLimit > p->matchMaxLen)
-+      lenLimit = p->matchMaxLen;
-+    p->lenLimit = lenLimit;
-+  }
-+  p->posLimit = p->pos + limit;
-+}
-+
-+void MatchFinder_Init(CMatchFinder *p)
-+{
-+  UInt32 i;
-+  for (i = 0; i < p->hashSizeSum; i++)
-+    p->hash[i] = kEmptyHashValue;
-+  p->cyclicBufferPos = 0;
-+  p->buffer = p->bufferBase;
-+  p->pos = p->streamPos = p->cyclicBufferSize;
-+  p->result = SZ_OK;
-+  p->streamEndWasReached = 0;
-+  MatchFinder_ReadBlock(p);
-+  MatchFinder_SetLimits(p);
-+}
-+
-+static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
-+{
-+  return (p->pos - p->historySize - 1) & kNormalizeMask;
-+}
-+
-+void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
-+{
-+  UInt32 i;
-+  for (i = 0; i < numItems; i++)
-+  {
-+    UInt32 value = items[i];
-+    if (value <= subValue)
-+      value = kEmptyHashValue;
-+    else
-+      value -= subValue;
-+    items[i] = value;
-+  }
-+}
-+
-+static void MatchFinder_Normalize(CMatchFinder *p)
-+{
-+  UInt32 subValue = MatchFinder_GetSubValue(p);
-+  MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
-+  MatchFinder_ReduceOffsets(p, subValue);
-+}
-+
-+static void MatchFinder_CheckLimits(CMatchFinder *p)
-+{
-+  if (p->pos == kMaxValForNormalize)
-+    MatchFinder_Normalize(p);
-+  if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
-+    MatchFinder_CheckAndMoveAndRead(p);
-+  if (p->cyclicBufferPos == p->cyclicBufferSize)
-+    p->cyclicBufferPos = 0;
-+  MatchFinder_SetLimits(p);
-+}
-+
-+static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
-+    UInt32 *distances, UInt32 maxLen)
-+{
-+  son[_cyclicBufferPos] = curMatch;
-+  for (;;)
-+  {
-+    UInt32 delta = pos - curMatch;
-+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-+      return distances;
-+    {
-+      const Byte *pb = cur - delta;
-+      curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
-+      if (pb[maxLen] == cur[maxLen] && *pb == *cur)
-+      {
-+        UInt32 len = 0;
-+        while (++len != lenLimit)
-+          if (pb[len] != cur[len])
-+            break;
-+        if (maxLen < len)
-+        {
-+          *distances++ = maxLen = len;
-+          *distances++ = delta - 1;
-+          if (len == lenLimit)
-+            return distances;
-+        }
-+      }
-+    }
-+  }
-+}
-+
-+UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
-+    UInt32 *distances, UInt32 maxLen)
-+{
-+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
-+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
-+  UInt32 len0 = 0, len1 = 0;
-+  for (;;)
-+  {
-+    UInt32 delta = pos - curMatch;
-+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-+    {
-+      *ptr0 = *ptr1 = kEmptyHashValue;
-+      return distances;
-+    }
-+    {
-+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
-+      const Byte *pb = cur - delta;
-+      UInt32 len = (len0 < len1 ? len0 : len1);
-+      if (pb[len] == cur[len])
-+      {
-+        if (++len != lenLimit && pb[len] == cur[len])
-+          while (++len != lenLimit)
-+            if (pb[len] != cur[len])
-+              break;
-+        if (maxLen < len)
-+        {
-+          *distances++ = maxLen = len;
-+          *distances++ = delta - 1;
-+          if (len == lenLimit)
-+          {
-+            *ptr1 = pair[0];
-+            *ptr0 = pair[1];
-+            return distances;
-+          }
-+        }
-+      }
-+      if (pb[len] < cur[len])
-+      {
-+        *ptr1 = curMatch;
-+        ptr1 = pair + 1;
-+        curMatch = *ptr1;
-+        len1 = len;
-+      }
-+      else
-+      {
-+        *ptr0 = curMatch;
-+        ptr0 = pair;
-+        curMatch = *ptr0;
-+        len0 = len;
-+      }
-+    }
-+  }
-+}
-+
-+static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
-+{
-+  CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
-+  CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
-+  UInt32 len0 = 0, len1 = 0;
-+  for (;;)
-+  {
-+    UInt32 delta = pos - curMatch;
-+    if (cutValue-- == 0 || delta >= _cyclicBufferSize)
-+    {
-+      *ptr0 = *ptr1 = kEmptyHashValue;
-+      return;
-+    }
-+    {
-+      CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
-+      const Byte *pb = cur - delta;
-+      UInt32 len = (len0 < len1 ? len0 : len1);
-+      if (pb[len] == cur[len])
-+      {
-+        while (++len != lenLimit)
-+          if (pb[len] != cur[len])
-+            break;
-+        {
-+          if (len == lenLimit)
-+          {
-+            *ptr1 = pair[0];
-+            *ptr0 = pair[1];
-+            return;
-+          }
-+        }
-+      }
-+      if (pb[len] < cur[len])
-+      {
-+        *ptr1 = curMatch;
-+        ptr1 = pair + 1;
-+        curMatch = *ptr1;
-+        len1 = len;
-+      }
-+      else
-+      {
-+        *ptr0 = curMatch;
-+        ptr0 = pair;
-+        curMatch = *ptr0;
-+        len0 = len;
-+      }
-+    }
-+  }
-+}
-+
-+#define MOVE_POS \
-+  ++p->cyclicBufferPos; \
-+  p->buffer++; \
-+  if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
-+
-+#define MOVE_POS_RET MOVE_POS return offset;
-+
-+static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
-+
-+#define GET_MATCHES_HEADER2(minLen, ret_op) \
-+  UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
-+  lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
-+  cur = p->buffer;
-+
-+#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
-+#define SKIP_HEADER(minLen)        GET_MATCHES_HEADER2(minLen, continue)
-+
-+#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
-+
-+#define GET_MATCHES_FOOTER(offset, maxLen) \
-+  offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
-+  distances + offset, maxLen) - distances); MOVE_POS_RET;
-+
-+#define SKIP_FOOTER \
-+  SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
-+
-+static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+  UInt32 offset;
-+  GET_MATCHES_HEADER(2)
-+  HASH2_CALC;
-+  curMatch = p->hash[hashValue];
-+  p->hash[hashValue] = p->pos;
-+  offset = 0;
-+  GET_MATCHES_FOOTER(offset, 1)
-+}
-+
-+UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+  UInt32 offset;
-+  GET_MATCHES_HEADER(3)
-+  HASH_ZIP_CALC;
-+  curMatch = p->hash[hashValue];
-+  p->hash[hashValue] = p->pos;
-+  offset = 0;
-+  GET_MATCHES_FOOTER(offset, 2)
-+}
-+
-+static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+  UInt32 hash2Value, delta2, maxLen, offset;
-+  GET_MATCHES_HEADER(3)
-+
-+  HASH3_CALC;
-+
-+  delta2 = p->pos - p->hash[hash2Value];
-+  curMatch = p->hash[kFix3HashSize + hashValue];
-+  
-+  p->hash[hash2Value] =
-+  p->hash[kFix3HashSize + hashValue] = p->pos;
-+
-+
-+  maxLen = 2;
-+  offset = 0;
-+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-+  {
-+    for (; maxLen != lenLimit; maxLen++)
-+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-+        break;
-+    distances[0] = maxLen;
-+    distances[1] = delta2 - 1;
-+    offset = 2;
-+    if (maxLen == lenLimit)
-+    {
-+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
-+      MOVE_POS_RET;
-+    }
-+  }
-+  GET_MATCHES_FOOTER(offset, maxLen)
-+}
-+
-+static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
-+  GET_MATCHES_HEADER(4)
-+
-+  HASH4_CALC;
-+
-+  delta2 = p->pos - p->hash[                hash2Value];
-+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
-+  curMatch = p->hash[kFix4HashSize + hashValue];
-+  
-+  p->hash[                hash2Value] =
-+  p->hash[kFix3HashSize + hash3Value] =
-+  p->hash[kFix4HashSize + hashValue] = p->pos;
-+
-+  maxLen = 1;
-+  offset = 0;
-+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-+  {
-+    distances[0] = maxLen = 2;
-+    distances[1] = delta2 - 1;
-+    offset = 2;
-+  }
-+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
-+  {
-+    maxLen = 3;
-+    distances[offset + 1] = delta3 - 1;
-+    offset += 2;
-+    delta2 = delta3;
-+  }
-+  if (offset != 0)
-+  {
-+    for (; maxLen != lenLimit; maxLen++)
-+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-+        break;
-+    distances[offset - 2] = maxLen;
-+    if (maxLen == lenLimit)
-+    {
-+      SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
-+      MOVE_POS_RET;
-+    }
-+  }
-+  if (maxLen < 3)
-+    maxLen = 3;
-+  GET_MATCHES_FOOTER(offset, maxLen)
-+}
-+
-+static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+  UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
-+  GET_MATCHES_HEADER(4)
-+
-+  HASH4_CALC;
-+
-+  delta2 = p->pos - p->hash[                hash2Value];
-+  delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
-+  curMatch = p->hash[kFix4HashSize + hashValue];
-+
-+  p->hash[                hash2Value] =
-+  p->hash[kFix3HashSize + hash3Value] =
-+  p->hash[kFix4HashSize + hashValue] = p->pos;
-+
-+  maxLen = 1;
-+  offset = 0;
-+  if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
-+  {
-+    distances[0] = maxLen = 2;
-+    distances[1] = delta2 - 1;
-+    offset = 2;
-+  }
-+  if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
-+  {
-+    maxLen = 3;
-+    distances[offset + 1] = delta3 - 1;
-+    offset += 2;
-+    delta2 = delta3;
-+  }
-+  if (offset != 0)
-+  {
-+    for (; maxLen != lenLimit; maxLen++)
-+      if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
-+        break;
-+    distances[offset - 2] = maxLen;
-+    if (maxLen == lenLimit)
-+    {
-+      p->son[p->cyclicBufferPos] = curMatch;
-+      MOVE_POS_RET;
-+    }
-+  }
-+  if (maxLen < 3)
-+    maxLen = 3;
-+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
-+    distances + offset, maxLen) - (distances));
-+  MOVE_POS_RET
-+}
-+
-+UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+{
-+  UInt32 offset;
-+  GET_MATCHES_HEADER(3)
-+  HASH_ZIP_CALC;
-+  curMatch = p->hash[hashValue];
-+  p->hash[hashValue] = p->pos;
-+  offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
-+    distances, 2) - (distances));
-+  MOVE_POS_RET
-+}
-+
-+static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+  do
-+  {
-+    SKIP_HEADER(2)
-+    HASH2_CALC;
-+    curMatch = p->hash[hashValue];
-+    p->hash[hashValue] = p->pos;
-+    SKIP_FOOTER
-+  }
-+  while (--num != 0);
-+}
-+
-+void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+  do
-+  {
-+    SKIP_HEADER(3)
-+    HASH_ZIP_CALC;
-+    curMatch = p->hash[hashValue];
-+    p->hash[hashValue] = p->pos;
-+    SKIP_FOOTER
-+  }
-+  while (--num != 0);
-+}
-+
-+static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+  do
-+  {
-+    UInt32 hash2Value;
-+    SKIP_HEADER(3)
-+    HASH3_CALC;
-+    curMatch = p->hash[kFix3HashSize + hashValue];
-+    p->hash[hash2Value] =
-+    p->hash[kFix3HashSize + hashValue] = p->pos;
-+    SKIP_FOOTER
-+  }
-+  while (--num != 0);
-+}
-+
-+static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+  do
-+  {
-+    UInt32 hash2Value, hash3Value;
-+    SKIP_HEADER(4)
-+    HASH4_CALC;
-+    curMatch = p->hash[kFix4HashSize + hashValue];
-+    p->hash[                hash2Value] =
-+    p->hash[kFix3HashSize + hash3Value] = p->pos;
-+    p->hash[kFix4HashSize + hashValue] = p->pos;
-+    SKIP_FOOTER
-+  }
-+  while (--num != 0);
-+}
-+
-+static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+  do
-+  {
-+    UInt32 hash2Value, hash3Value;
-+    SKIP_HEADER(4)
-+    HASH4_CALC;
-+    curMatch = p->hash[kFix4HashSize + hashValue];
-+    p->hash[                hash2Value] =
-+    p->hash[kFix3HashSize + hash3Value] =
-+    p->hash[kFix4HashSize + hashValue] = p->pos;
-+    p->son[p->cyclicBufferPos] = curMatch;
-+    MOVE_POS
-+  }
-+  while (--num != 0);
-+}
-+
-+void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+{
-+  do
-+  {
-+    SKIP_HEADER(3)
-+    HASH_ZIP_CALC;
-+    curMatch = p->hash[hashValue];
-+    p->hash[hashValue] = p->pos;
-+    p->son[p->cyclicBufferPos] = curMatch;
-+    MOVE_POS
-+  }
-+  while (--num != 0);
-+}
-+
-+void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
-+{
-+  vTable->Init = (Mf_Init_Func)MatchFinder_Init;
-+  vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
-+  vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
-+  vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
-+  if (!p->btMode)
-+  {
-+    vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
-+    vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
-+  }
-+  else if (p->numHashBytes == 2)
-+  {
-+    vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
-+    vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
-+  }
-+  else if (p->numHashBytes == 3)
-+  {
-+    vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
-+    vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
-+  }
-+  else
-+  {
-+    vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
-+    vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
-+  }
-+}
---- /dev/null
-+++ b/lib/lzma/LzmaDec.c
-@@ -0,0 +1,999 @@
-+/* LzmaDec.c -- LZMA Decoder
-+2009-09-20 : Igor Pavlov : Public domain */
-+
-+#include "LzmaDec.h"
-+
-+#include <string.h>
-+
-+#define kNumTopBits 24
-+#define kTopValue ((UInt32)1 << kNumTopBits)
-+
-+#define kNumBitModelTotalBits 11
-+#define kBitModelTotal (1 << kNumBitModelTotalBits)
-+#define kNumMoveBits 5
-+
-+#define RC_INIT_SIZE 5
-+
-+#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
-+
-+#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-+#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
-+#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
-+#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
-+  { UPDATE_0(p); i = (i + i); A0; } else \
-+  { UPDATE_1(p); i = (i + i) + 1; A1; }
-+#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
-+
-+#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
-+#define TREE_DECODE(probs, limit, i) \
-+  { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
-+
-+/* #define _LZMA_SIZE_OPT */
-+
-+#ifdef _LZMA_SIZE_OPT
-+#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
-+#else
-+#define TREE_6_DECODE(probs, i) \
-+  { i = 1; \
-+  TREE_GET_BIT(probs, i); \
-+  TREE_GET_BIT(probs, i); \
-+  TREE_GET_BIT(probs, i); \
-+  TREE_GET_BIT(probs, i); \
-+  TREE_GET_BIT(probs, i); \
-+  TREE_GET_BIT(probs, i); \
-+  i -= 0x40; }
-+#endif
-+
-+#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
-+
-+#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
-+#define UPDATE_0_CHECK range = bound;
-+#define UPDATE_1_CHECK range -= bound; code -= bound;
-+#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
-+  { UPDATE_0_CHECK; i = (i + i); A0; } else \
-+  { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
-+#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
-+#define TREE_DECODE_CHECK(probs, limit, i) \
-+  { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
-+
-+
-+#define kNumPosBitsMax 4
-+#define kNumPosStatesMax (1 << kNumPosBitsMax)
-+
-+#define kLenNumLowBits 3
-+#define kLenNumLowSymbols (1 << kLenNumLowBits)
-+#define kLenNumMidBits 3
-+#define kLenNumMidSymbols (1 << kLenNumMidBits)
-+#define kLenNumHighBits 8
-+#define kLenNumHighSymbols (1 << kLenNumHighBits)
-+
-+#define LenChoice 0
-+#define LenChoice2 (LenChoice + 1)
-+#define LenLow (LenChoice2 + 1)
-+#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
-+#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
-+#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
-+
-+
-+#define kNumStates 12
-+#define kNumLitStates 7
-+
-+#define kStartPosModelIndex 4
-+#define kEndPosModelIndex 14
-+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-+
-+#define kNumPosSlotBits 6
-+#define kNumLenToPosStates 4
-+
-+#define kNumAlignBits 4
-+#define kAlignTableSize (1 << kNumAlignBits)
-+
-+#define kMatchMinLen 2
-+#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-+
-+#define IsMatch 0
-+#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
-+#define IsRepG0 (IsRep + kNumStates)
-+#define IsRepG1 (IsRepG0 + kNumStates)
-+#define IsRepG2 (IsRepG1 + kNumStates)
-+#define IsRep0Long (IsRepG2 + kNumStates)
-+#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
-+#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
-+#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
-+#define LenCoder (Align + kAlignTableSize)
-+#define RepLenCoder (LenCoder + kNumLenProbs)
-+#define Literal (RepLenCoder + kNumLenProbs)
-+
-+#define LZMA_BASE_SIZE 1846
-+#define LZMA_LIT_SIZE 768
-+
-+#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
-+
-+#if Literal != LZMA_BASE_SIZE
-+StopCompilingDueBUG
-+#endif
-+
-+#define LZMA_DIC_MIN (1 << 12)
-+
-+/* First LZMA-symbol is always decoded.
-+And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
-+Out:
-+  Result:
-+    SZ_OK - OK
-+    SZ_ERROR_DATA - Error
-+  p->remainLen:
-+    < kMatchSpecLenStart : normal remain
-+    = kMatchSpecLenStart : finished
-+    = kMatchSpecLenStart + 1 : Flush marker
-+    = kMatchSpecLenStart + 2 : State Init Marker
-+*/
-+
-+static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-+{
-+  CLzmaProb *probs = p->probs;
-+
-+  unsigned state = p->state;
-+  UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
-+  unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
-+  unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
-+  unsigned lc = p->prop.lc;
-+
-+  Byte *dic = p->dic;
-+  SizeT dicBufSize = p->dicBufSize;
-+  SizeT dicPos = p->dicPos;
-+  
-+  UInt32 processedPos = p->processedPos;
-+  UInt32 checkDicSize = p->checkDicSize;
-+  unsigned len = 0;
-+
-+  const Byte *buf = p->buf;
-+  UInt32 range = p->range;
-+  UInt32 code = p->code;
-+
-+  do
-+  {
-+    CLzmaProb *prob;
-+    UInt32 bound;
-+    unsigned ttt;
-+    unsigned posState = processedPos & pbMask;
-+
-+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
-+    IF_BIT_0(prob)
-+    {
-+      unsigned symbol;
-+      UPDATE_0(prob);
-+      prob = probs + Literal;
-+      if (checkDicSize != 0 || processedPos != 0)
-+        prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
-+        (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
-+
-+      if (state < kNumLitStates)
-+      {
-+        state -= (state < 4) ? state : 3;
-+        symbol = 1;
-+        do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
-+      }
-+      else
-+      {
-+        unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+        unsigned offs = 0x100;
-+        state -= (state < 10) ? 3 : 6;
-+        symbol = 1;
-+        do
-+        {
-+          unsigned bit;
-+          CLzmaProb *probLit;
-+          matchByte <<= 1;
-+          bit = (matchByte & offs);
-+          probLit = prob + offs + bit + symbol;
-+          GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
-+        }
-+        while (symbol < 0x100);
-+      }
-+      dic[dicPos++] = (Byte)symbol;
-+      processedPos++;
-+      continue;
-+    }
-+    else
-+    {
-+      UPDATE_1(prob);
-+      prob = probs + IsRep + state;
-+      IF_BIT_0(prob)
-+      {
-+        UPDATE_0(prob);
-+        state += kNumStates;
-+        prob = probs + LenCoder;
-+      }
-+      else
-+      {
-+        UPDATE_1(prob);
-+        if (checkDicSize == 0 && processedPos == 0)
-+          return SZ_ERROR_DATA;
-+        prob = probs + IsRepG0 + state;
-+        IF_BIT_0(prob)
-+        {
-+          UPDATE_0(prob);
-+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
-+          IF_BIT_0(prob)
-+          {
-+            UPDATE_0(prob);
-+            dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+            dicPos++;
-+            processedPos++;
-+            state = state < kNumLitStates ? 9 : 11;
-+            continue;
-+          }
-+          UPDATE_1(prob);
-+        }
-+        else
-+        {
-+          UInt32 distance;
-+          UPDATE_1(prob);
-+          prob = probs + IsRepG1 + state;
-+          IF_BIT_0(prob)
-+          {
-+            UPDATE_0(prob);
-+            distance = rep1;
-+          }
-+          else
-+          {
-+            UPDATE_1(prob);
-+            prob = probs + IsRepG2 + state;
-+            IF_BIT_0(prob)
-+            {
-+              UPDATE_0(prob);
-+              distance = rep2;
-+            }
-+            else
-+            {
-+              UPDATE_1(prob);
-+              distance = rep3;
-+              rep3 = rep2;
-+            }
-+            rep2 = rep1;
-+          }
-+          rep1 = rep0;
-+          rep0 = distance;
-+        }
-+        state = state < kNumLitStates ? 8 : 11;
-+        prob = probs + RepLenCoder;
-+      }
-+      {
-+        unsigned limit, offset;
-+        CLzmaProb *probLen = prob + LenChoice;
-+        IF_BIT_0(probLen)
-+        {
-+          UPDATE_0(probLen);
-+          probLen = prob + LenLow + (posState << kLenNumLowBits);
-+          offset = 0;
-+          limit = (1 << kLenNumLowBits);
-+        }
-+        else
-+        {
-+          UPDATE_1(probLen);
-+          probLen = prob + LenChoice2;
-+          IF_BIT_0(probLen)
-+          {
-+            UPDATE_0(probLen);
-+            probLen = prob + LenMid + (posState << kLenNumMidBits);
-+            offset = kLenNumLowSymbols;
-+            limit = (1 << kLenNumMidBits);
-+          }
-+          else
-+          {
-+            UPDATE_1(probLen);
-+            probLen = prob + LenHigh;
-+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
-+            limit = (1 << kLenNumHighBits);
-+          }
-+        }
-+        TREE_DECODE(probLen, limit, len);
-+        len += offset;
-+      }
-+
-+      if (state >= kNumStates)
-+      {
-+        UInt32 distance;
-+        prob = probs + PosSlot +
-+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
-+        TREE_6_DECODE(prob, distance);
-+        if (distance >= kStartPosModelIndex)
-+        {
-+          unsigned posSlot = (unsigned)distance;
-+          int numDirectBits = (int)(((distance >> 1) - 1));
-+          distance = (2 | (distance & 1));
-+          if (posSlot < kEndPosModelIndex)
-+          {
-+            distance <<= numDirectBits;
-+            prob = probs + SpecPos + distance - posSlot - 1;
-+            {
-+              UInt32 mask = 1;
-+              unsigned i = 1;
-+              do
-+              {
-+                GET_BIT2(prob + i, i, ; , distance |= mask);
-+                mask <<= 1;
-+              }
-+              while (--numDirectBits != 0);
-+            }
-+          }
-+          else
-+          {
-+            numDirectBits -= kNumAlignBits;
-+            do
-+            {
-+              NORMALIZE
-+              range >>= 1;
-+              
-+              {
-+                UInt32 t;
-+                code -= range;
-+                t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
-+                distance = (distance << 1) + (t + 1);
-+                code += range & t;
-+              }
-+              /*
-+              distance <<= 1;
-+              if (code >= range)
-+              {
-+                code -= range;
-+                distance |= 1;
-+              }
-+              */
-+            }
-+            while (--numDirectBits != 0);
-+            prob = probs + Align;
-+            distance <<= kNumAlignBits;
-+            {
-+              unsigned i = 1;
-+              GET_BIT2(prob + i, i, ; , distance |= 1);
-+              GET_BIT2(prob + i, i, ; , distance |= 2);
-+              GET_BIT2(prob + i, i, ; , distance |= 4);
-+              GET_BIT2(prob + i, i, ; , distance |= 8);
-+            }
-+            if (distance == (UInt32)0xFFFFFFFF)
-+            {
-+              len += kMatchSpecLenStart;
-+              state -= kNumStates;
-+              break;
-+            }
-+          }
-+        }
-+        rep3 = rep2;
-+        rep2 = rep1;
-+        rep1 = rep0;
-+        rep0 = distance + 1;
-+        if (checkDicSize == 0)
-+        {
-+          if (distance >= processedPos)
-+            return SZ_ERROR_DATA;
-+        }
-+        else if (distance >= checkDicSize)
-+          return SZ_ERROR_DATA;
-+        state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
-+      }
-+
-+      len += kMatchMinLen;
-+
-+      if (limit == dicPos)
-+        return SZ_ERROR_DATA;
-+      {
-+        SizeT rem = limit - dicPos;
-+        unsigned curLen = ((rem < len) ? (unsigned)rem : len);
-+        SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
-+
-+        processedPos += curLen;
-+
-+        len -= curLen;
-+        if (pos + curLen <= dicBufSize)
-+        {
-+          Byte *dest = dic + dicPos;
-+          ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
-+          const Byte *lim = dest + curLen;
-+          dicPos += curLen;
-+          do
-+            *(dest) = (Byte)*(dest + src);
-+          while (++dest != lim);
-+        }
-+        else
-+        {
-+          do
-+          {
-+            dic[dicPos++] = dic[pos];
-+            if (++pos == dicBufSize)
-+              pos = 0;
-+          }
-+          while (--curLen != 0);
-+        }
-+      }
-+    }
-+  }
-+  while (dicPos < limit && buf < bufLimit);
-+  NORMALIZE;
-+  p->buf = buf;
-+  p->range = range;
-+  p->code = code;
-+  p->remainLen = len;
-+  p->dicPos = dicPos;
-+  p->processedPos = processedPos;
-+  p->reps[0] = rep0;
-+  p->reps[1] = rep1;
-+  p->reps[2] = rep2;
-+  p->reps[3] = rep3;
-+  p->state = state;
-+
-+  return SZ_OK;
-+}
-+
-+static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
-+{
-+  if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
-+  {
-+    Byte *dic = p->dic;
-+    SizeT dicPos = p->dicPos;
-+    SizeT dicBufSize = p->dicBufSize;
-+    unsigned len = p->remainLen;
-+    UInt32 rep0 = p->reps[0];
-+    if (limit - dicPos < len)
-+      len = (unsigned)(limit - dicPos);
-+
-+    if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
-+      p->checkDicSize = p->prop.dicSize;
-+
-+    p->processedPos += len;
-+    p->remainLen -= len;
-+    while (len-- != 0)
-+    {
-+      dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
-+      dicPos++;
-+    }
-+    p->dicPos = dicPos;
-+  }
-+}
-+
-+static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
-+{
-+  do
-+  {
-+    SizeT limit2 = limit;
-+    if (p->checkDicSize == 0)
-+    {
-+      UInt32 rem = p->prop.dicSize - p->processedPos;
-+      if (limit - p->dicPos > rem)
-+        limit2 = p->dicPos + rem;
-+    }
-+    RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
-+    if (p->processedPos >= p->prop.dicSize)
-+      p->checkDicSize = p->prop.dicSize;
-+    LzmaDec_WriteRem(p, limit);
-+  }
-+  while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
-+
-+  if (p->remainLen > kMatchSpecLenStart)
-+  {
-+    p->remainLen = kMatchSpecLenStart;
-+  }
-+  return 0;
-+}
-+
-+typedef enum
-+{
-+  DUMMY_ERROR, /* unexpected end of input stream */
-+  DUMMY_LIT,
-+  DUMMY_MATCH,
-+  DUMMY_REP
-+} ELzmaDummy;
-+
-+static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
-+{
-+  UInt32 range = p->range;
-+  UInt32 code = p->code;
-+  const Byte *bufLimit = buf + inSize;
-+  CLzmaProb *probs = p->probs;
-+  unsigned state = p->state;
-+  ELzmaDummy res;
-+
-+  {
-+    CLzmaProb *prob;
-+    UInt32 bound;
-+    unsigned ttt;
-+    unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
-+
-+    prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
-+    IF_BIT_0_CHECK(prob)
-+    {
-+      UPDATE_0_CHECK
-+
-+      /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
-+
-+      prob = probs + Literal;
-+      if (p->checkDicSize != 0 || p->processedPos != 0)
-+        prob += (LZMA_LIT_SIZE *
-+          ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
-+          (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
-+
-+      if (state < kNumLitStates)
-+      {
-+        unsigned symbol = 1;
-+        do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
-+      }
-+      else
-+      {
-+        unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
-+            ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
-+        unsigned offs = 0x100;
-+        unsigned symbol = 1;
-+        do
-+        {
-+          unsigned bit;
-+          CLzmaProb *probLit;
-+          matchByte <<= 1;
-+          bit = (matchByte & offs);
-+          probLit = prob + offs + bit + symbol;
-+          GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
-+        }
-+        while (symbol < 0x100);
-+      }
-+      res = DUMMY_LIT;
-+    }
-+    else
-+    {
-+      unsigned len;
-+      UPDATE_1_CHECK;
-+
-+      prob = probs + IsRep + state;
-+      IF_BIT_0_CHECK(prob)
-+      {
-+        UPDATE_0_CHECK;
-+        state = 0;
-+        prob = probs + LenCoder;
-+        res = DUMMY_MATCH;
-+      }
-+      else
-+      {
-+        UPDATE_1_CHECK;
-+        res = DUMMY_REP;
-+        prob = probs + IsRepG0 + state;
-+        IF_BIT_0_CHECK(prob)
-+        {
-+          UPDATE_0_CHECK;
-+          prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
-+          IF_BIT_0_CHECK(prob)
-+          {
-+            UPDATE_0_CHECK;
-+            NORMALIZE_CHECK;
-+            return DUMMY_REP;
-+          }
-+          else
-+          {
-+            UPDATE_1_CHECK;
-+          }
-+        }
-+        else
-+        {
-+          UPDATE_1_CHECK;
-+          prob = probs + IsRepG1 + state;
-+          IF_BIT_0_CHECK(prob)
-+          {
-+            UPDATE_0_CHECK;
-+          }
-+          else
-+          {
-+            UPDATE_1_CHECK;
-+            prob = probs + IsRepG2 + state;
-+            IF_BIT_0_CHECK(prob)
-+            {
-+              UPDATE_0_CHECK;
-+            }
-+            else
-+            {
-+              UPDATE_1_CHECK;
-+            }
-+          }
-+        }
-+        state = kNumStates;
-+        prob = probs + RepLenCoder;
-+      }
-+      {
-+        unsigned limit, offset;
-+        CLzmaProb *probLen = prob + LenChoice;
-+        IF_BIT_0_CHECK(probLen)
-+        {
-+          UPDATE_0_CHECK;
-+          probLen = prob + LenLow + (posState << kLenNumLowBits);
-+          offset = 0;
-+          limit = 1 << kLenNumLowBits;
-+        }
-+        else
-+        {
-+          UPDATE_1_CHECK;
-+          probLen = prob + LenChoice2;
-+          IF_BIT_0_CHECK(probLen)
-+          {
-+            UPDATE_0_CHECK;
-+            probLen = prob + LenMid + (posState << kLenNumMidBits);
-+            offset = kLenNumLowSymbols;
-+            limit = 1 << kLenNumMidBits;
-+          }
-+          else
-+          {
-+            UPDATE_1_CHECK;
-+            probLen = prob + LenHigh;
-+            offset = kLenNumLowSymbols + kLenNumMidSymbols;
-+            limit = 1 << kLenNumHighBits;
-+          }
-+        }
-+        TREE_DECODE_CHECK(probLen, limit, len);
-+        len += offset;
-+      }
-+
-+      if (state < 4)
-+      {
-+        unsigned posSlot;
-+        prob = probs + PosSlot +
-+            ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
-+            kNumPosSlotBits);
-+        TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
-+        if (posSlot >= kStartPosModelIndex)
-+        {
-+          int numDirectBits = ((posSlot >> 1) - 1);
-+
-+          /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
-+
-+          if (posSlot < kEndPosModelIndex)
-+          {
-+            prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
-+          }
-+          else
-+          {
-+            numDirectBits -= kNumAlignBits;
-+            do
-+            {
-+              NORMALIZE_CHECK
-+              range >>= 1;
-+              code -= range & (((code - range) >> 31) - 1);
-+              /* if (code >= range) code -= range; */
-+            }
-+            while (--numDirectBits != 0);
-+            prob = probs + Align;
-+            numDirectBits = kNumAlignBits;
-+          }
-+          {
-+            unsigned i = 1;
-+            do
-+            {
-+              GET_BIT_CHECK(prob + i, i);
-+            }
-+            while (--numDirectBits != 0);
-+          }
-+        }
-+      }
-+    }
-+  }
-+  NORMALIZE_CHECK;
-+  return res;
-+}
-+
-+
-+static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
-+{
-+  p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
-+  p->range = 0xFFFFFFFF;
-+  p->needFlush = 0;
-+}
-+
-+void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
-+{
-+  p->needFlush = 1;
-+  p->remainLen = 0;
-+  p->tempBufSize = 0;
-+
-+  if (initDic)
-+  {
-+    p->processedPos = 0;
-+    p->checkDicSize = 0;
-+    p->needInitState = 1;
-+  }
-+  if (initState)
-+    p->needInitState = 1;
-+}
-+
-+void LzmaDec_Init(CLzmaDec *p)
-+{
-+  p->dicPos = 0;
-+  LzmaDec_InitDicAndState(p, True, True);
-+}
-+
-+static void LzmaDec_InitStateReal(CLzmaDec *p)
-+{
-+  UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
-+  UInt32 i;
-+  CLzmaProb *probs = p->probs;
-+  for (i = 0; i < numProbs; i++)
-+    probs[i] = kBitModelTotal >> 1;
-+  p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
-+  p->state = 0;
-+  p->needInitState = 0;
-+}
-+
-+SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
-+    ELzmaFinishMode finishMode, ELzmaStatus *status)
-+{
-+  SizeT inSize = *srcLen;
-+  (*srcLen) = 0;
-+  LzmaDec_WriteRem(p, dicLimit);
-+  
-+  *status = LZMA_STATUS_NOT_SPECIFIED;
-+
-+  while (p->remainLen != kMatchSpecLenStart)
-+  {
-+      int checkEndMarkNow;
-+
-+      if (p->needFlush != 0)
-+      {
-+        for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
-+          p->tempBuf[p->tempBufSize++] = *src++;
-+        if (p->tempBufSize < RC_INIT_SIZE)
-+        {
-+          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+          return SZ_OK;
-+        }
-+        if (p->tempBuf[0] != 0)
-+          return SZ_ERROR_DATA;
-+
-+        LzmaDec_InitRc(p, p->tempBuf);
-+        p->tempBufSize = 0;
-+      }
-+
-+      checkEndMarkNow = 0;
-+      if (p->dicPos >= dicLimit)
-+      {
-+        if (p->remainLen == 0 && p->code == 0)
-+        {
-+          *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
-+          return SZ_OK;
-+        }
-+        if (finishMode == LZMA_FINISH_ANY)
-+        {
-+          *status = LZMA_STATUS_NOT_FINISHED;
-+          return SZ_OK;
-+        }
-+        if (p->remainLen != 0)
-+        {
-+          *status = LZMA_STATUS_NOT_FINISHED;
-+          return SZ_ERROR_DATA;
-+        }
-+        checkEndMarkNow = 1;
-+      }
-+
-+      if (p->needInitState)
-+        LzmaDec_InitStateReal(p);
-+  
-+      if (p->tempBufSize == 0)
-+      {
-+        SizeT processed;
-+        const Byte *bufLimit;
-+        if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
-+        {
-+          int dummyRes = LzmaDec_TryDummy(p, src, inSize);
-+          if (dummyRes == DUMMY_ERROR)
-+          {
-+            memcpy(p->tempBuf, src, inSize);
-+            p->tempBufSize = (unsigned)inSize;
-+            (*srcLen) += inSize;
-+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+            return SZ_OK;
-+          }
-+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
-+          {
-+            *status = LZMA_STATUS_NOT_FINISHED;
-+            return SZ_ERROR_DATA;
-+          }
-+          bufLimit = src;
-+        }
-+        else
-+          bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
-+        p->buf = src;
-+        if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
-+          return SZ_ERROR_DATA;
-+        processed = (SizeT)(p->buf - src);
-+        (*srcLen) += processed;
-+        src += processed;
-+        inSize -= processed;
-+      }
-+      else
-+      {
-+        unsigned rem = p->tempBufSize, lookAhead = 0;
-+        while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
-+          p->tempBuf[rem++] = src[lookAhead++];
-+        p->tempBufSize = rem;
-+        if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
-+        {
-+          int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
-+          if (dummyRes == DUMMY_ERROR)
-+          {
-+            (*srcLen) += lookAhead;
-+            *status = LZMA_STATUS_NEEDS_MORE_INPUT;
-+            return SZ_OK;
-+          }
-+          if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
-+          {
-+            *status = LZMA_STATUS_NOT_FINISHED;
-+            return SZ_ERROR_DATA;
-+          }
-+        }
-+        p->buf = p->tempBuf;
-+        if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
-+          return SZ_ERROR_DATA;
-+        lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
-+        (*srcLen) += lookAhead;
-+        src += lookAhead;
-+        inSize -= lookAhead;
-+        p->tempBufSize = 0;
-+      }
-+  }
-+  if (p->code == 0)
-+    *status = LZMA_STATUS_FINISHED_WITH_MARK;
-+  return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
-+}
-+
-+SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
-+{
-+  SizeT outSize = *destLen;
-+  SizeT inSize = *srcLen;
-+  *srcLen = *destLen = 0;
-+  for (;;)
-+  {
-+    SizeT inSizeCur = inSize, outSizeCur, dicPos;
-+    ELzmaFinishMode curFinishMode;
-+    SRes res;
-+    if (p->dicPos == p->dicBufSize)
-+      p->dicPos = 0;
-+    dicPos = p->dicPos;
-+    if (outSize > p->dicBufSize - dicPos)
-+    {
-+      outSizeCur = p->dicBufSize;
-+      curFinishMode = LZMA_FINISH_ANY;
-+    }
-+    else
-+    {
-+      outSizeCur = dicPos + outSize;
-+      curFinishMode = finishMode;
-+    }
-+
-+    res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
-+    src += inSizeCur;
-+    inSize -= inSizeCur;
-+    *srcLen += inSizeCur;
-+    outSizeCur = p->dicPos - dicPos;
-+    memcpy(dest, p->dic + dicPos, outSizeCur);
-+    dest += outSizeCur;
-+    outSize -= outSizeCur;
-+    *destLen += outSizeCur;
-+    if (res != 0)
-+      return res;
-+    if (outSizeCur == 0 || outSize == 0)
-+      return SZ_OK;
-+  }
-+}
-+
-+void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
-+{
-+  alloc->Free(alloc, p->probs);
-+  p->probs = 0;
-+}
-+
-+static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
-+{
-+  alloc->Free(alloc, p->dic);
-+  p->dic = 0;
-+}
-+
-+void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
-+{
-+  LzmaDec_FreeProbs(p, alloc);
-+  LzmaDec_FreeDict(p, alloc);
-+}
-+
-+SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
-+{
-+  UInt32 dicSize;
-+  Byte d;
-+  
-+  if (size < LZMA_PROPS_SIZE)
-+    return SZ_ERROR_UNSUPPORTED;
-+  else
-+    dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
-+ 
-+  if (dicSize < LZMA_DIC_MIN)
-+    dicSize = LZMA_DIC_MIN;
-+  p->dicSize = dicSize;
-+
-+  d = data[0];
-+  if (d >= (9 * 5 * 5))
-+    return SZ_ERROR_UNSUPPORTED;
-+
-+  p->lc = d % 9;
-+  d /= 9;
-+  p->pb = d / 5;
-+  p->lp = d % 5;
-+
-+  return SZ_OK;
-+}
-+
-+static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
-+{
-+  UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
-+  if (p->probs == 0 || numProbs != p->numProbs)
-+  {
-+    LzmaDec_FreeProbs(p, alloc);
-+    p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
-+    p->numProbs = numProbs;
-+    if (p->probs == 0)
-+      return SZ_ERROR_MEM;
-+  }
-+  return SZ_OK;
-+}
-+
-+SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-+{
-+  CLzmaProps propNew;
-+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-+  p->prop = propNew;
-+  return SZ_OK;
-+}
-+
-+SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-+{
-+  CLzmaProps propNew;
-+  SizeT dicBufSize;
-+  RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-+  RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
-+  dicBufSize = propNew.dicSize;
-+  if (p->dic == 0 || dicBufSize != p->dicBufSize)
-+  {
-+    LzmaDec_FreeDict(p, alloc);
-+    p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
-+    if (p->dic == 0)
-+    {
-+      LzmaDec_FreeProbs(p, alloc);
-+      return SZ_ERROR_MEM;
-+    }
-+  }
-+  p->dicBufSize = dicBufSize;
-+  p->prop = propNew;
-+  return SZ_OK;
-+}
-+
-+SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
-+    const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
-+    ELzmaStatus *status, ISzAlloc *alloc)
-+{
-+  CLzmaDec p;
-+  SRes res;
-+  SizeT inSize = *srcLen;
-+  SizeT outSize = *destLen;
-+  *srcLen = *destLen = 0;
-+  if (inSize < RC_INIT_SIZE)
-+    return SZ_ERROR_INPUT_EOF;
-+
-+  LzmaDec_Construct(&p);
-+  res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
-+  if (res != 0)
-+    return res;
-+  p.dic = dest;
-+  p.dicBufSize = outSize;
-+
-+  LzmaDec_Init(&p);
-+  
-+  *srcLen = inSize;
-+  res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
-+
-+  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
-+    res = SZ_ERROR_INPUT_EOF;
-+
-+  (*destLen) = p.dicPos;
-+  LzmaDec_FreeProbs(&p, alloc);
-+  return res;
-+}
---- /dev/null
-+++ b/lib/lzma/LzmaEnc.c
-@@ -0,0 +1,2271 @@
-+/* LzmaEnc.c -- LZMA Encoder
-+2009-11-24 : Igor Pavlov : Public domain */
-+
-+#include <string.h>
-+
-+/* #define SHOW_STAT */
-+/* #define SHOW_STAT2 */
-+
-+#if defined(SHOW_STAT) || defined(SHOW_STAT2)
-+#include <stdio.h>
-+#endif
-+
-+#include "LzmaEnc.h"
-+
-+/* disable MT */
-+#define _7ZIP_ST
-+
-+#include "LzFind.h"
-+#ifndef _7ZIP_ST
-+#include "LzFindMt.h"
-+#endif
-+
-+#ifdef SHOW_STAT
-+static int ttt = 0;
-+#endif
-+
-+#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
-+
-+#define kBlockSize (9 << 10)
-+#define kUnpackBlockSize (1 << 18)
-+#define kMatchArraySize (1 << 21)
-+#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
-+
-+#define kNumMaxDirectBits (31)
-+
-+#define kNumTopBits 24
-+#define kTopValue ((UInt32)1 << kNumTopBits)
-+
-+#define kNumBitModelTotalBits 11
-+#define kBitModelTotal (1 << kNumBitModelTotalBits)
-+#define kNumMoveBits 5
-+#define kProbInitValue (kBitModelTotal >> 1)
-+
-+#define kNumMoveReducingBits 4
-+#define kNumBitPriceShiftBits 4
-+#define kBitPrice (1 << kNumBitPriceShiftBits)
-+
-+void LzmaEncProps_Init(CLzmaEncProps *p)
-+{
-+  p->level = 5;
-+  p->dictSize = p->mc = 0;
-+  p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
-+  p->writeEndMark = 0;
-+}
-+
-+void LzmaEncProps_Normalize(CLzmaEncProps *p)
-+{
-+  int level = p->level;
-+  if (level < 0) level = 5;
-+  p->level = level;
-+  if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
-+  if (p->lc < 0) p->lc = 3;
-+  if (p->lp < 0) p->lp = 0;
-+  if (p->pb < 0) p->pb = 2;
-+  if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
-+  if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
-+  if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
-+  if (p->numHashBytes < 0) p->numHashBytes = 4;
-+  if (p->mc == 0)  p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
-+  if (p->numThreads < 0)
-+    p->numThreads =
-+      #ifndef _7ZIP_ST
-+      ((p->btMode && p->algo) ? 2 : 1);
-+      #else
-+      1;
-+      #endif
-+}
-+
-+UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
-+{
-+  CLzmaEncProps props = *props2;
-+  LzmaEncProps_Normalize(&props);
-+  return props.dictSize;
-+}
-+
-+/* #define LZMA_LOG_BSR */
-+/* Define it for Intel's CPU */
-+
-+
-+#ifdef LZMA_LOG_BSR
-+
-+#define kDicLogSizeMaxCompress 30
-+
-+#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
-+
-+UInt32 GetPosSlot1(UInt32 pos)
-+{
-+  UInt32 res;
-+  BSR2_RET(pos, res);
-+  return res;
-+}
-+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-+#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
-+
-+#else
-+
-+#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
-+#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
-+
-+void LzmaEnc_FastPosInit(Byte *g_FastPos)
-+{
-+  int c = 2, slotFast;
-+  g_FastPos[0] = 0;
-+  g_FastPos[1] = 1;
-+  
-+  for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
-+  {
-+    UInt32 k = (1 << ((slotFast >> 1) - 1));
-+    UInt32 j;
-+    for (j = 0; j < k; j++, c++)
-+      g_FastPos[c] = (Byte)slotFast;
-+  }
-+}
-+
-+#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
-+  (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
-+  res = p->g_FastPos[pos >> i] + (i * 2); }
-+/*
-+#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
-+  p->g_FastPos[pos >> 6] + 12 : \
-+  p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
-+*/
-+
-+#define GetPosSlot1(pos) p->g_FastPos[pos]
-+#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
-+#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
-+
-+#endif
-+
-+
-+#define LZMA_NUM_REPS 4
-+
-+typedef unsigned CState;
-+
-+typedef struct
-+{
-+  UInt32 price;
-+
-+  CState state;
-+  int prev1IsChar;
-+  int prev2;
-+
-+  UInt32 posPrev2;
-+  UInt32 backPrev2;
-+
-+  UInt32 posPrev;
-+  UInt32 backPrev;
-+  UInt32 backs[LZMA_NUM_REPS];
-+} COptimal;
-+
-+#define kNumOpts (1 << 12)
-+
-+#define kNumLenToPosStates 4
-+#define kNumPosSlotBits 6
-+#define kDicLogSizeMin 0
-+#define kDicLogSizeMax 32
-+#define kDistTableSizeMax (kDicLogSizeMax * 2)
-+
-+
-+#define kNumAlignBits 4
-+#define kAlignTableSize (1 << kNumAlignBits)
-+#define kAlignMask (kAlignTableSize - 1)
-+
-+#define kStartPosModelIndex 4
-+#define kEndPosModelIndex 14
-+#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
-+
-+#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
-+
-+#ifdef _LZMA_PROB32
-+#define CLzmaProb UInt32
-+#else
-+#define CLzmaProb UInt16
-+#endif
-+
-+#define LZMA_PB_MAX 4
-+#define LZMA_LC_MAX 8
-+#define LZMA_LP_MAX 4
-+
-+#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
-+
-+
-+#define kLenNumLowBits 3
-+#define kLenNumLowSymbols (1 << kLenNumLowBits)
-+#define kLenNumMidBits 3
-+#define kLenNumMidSymbols (1 << kLenNumMidBits)
-+#define kLenNumHighBits 8
-+#define kLenNumHighSymbols (1 << kLenNumHighBits)
-+
-+#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
-+
-+#define LZMA_MATCH_LEN_MIN 2
-+#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
-+
-+#define kNumStates 12
-+
-+typedef struct
-+{
-+  CLzmaProb choice;
-+  CLzmaProb choice2;
-+  CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
-+  CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
-+  CLzmaProb high[kLenNumHighSymbols];
-+} CLenEnc;
-+
-+typedef struct
-+{
-+  CLenEnc p;
-+  UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
-+  UInt32 tableSize;
-+  UInt32 counters[LZMA_NUM_PB_STATES_MAX];
-+} CLenPriceEnc;
-+
-+typedef struct
-+{
-+  UInt32 range;
-+  Byte cache;
-+  UInt64 low;
-+  UInt64 cacheSize;
-+  Byte *buf;
-+  Byte *bufLim;
-+  Byte *bufBase;
-+  ISeqOutStream *outStream;
-+  UInt64 processed;
-+  SRes res;
-+} CRangeEnc;
-+
-+typedef struct
-+{
-+  CLzmaProb *litProbs;
-+
-+  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+  CLzmaProb isRep[kNumStates];
-+  CLzmaProb isRepG0[kNumStates];
-+  CLzmaProb isRepG1[kNumStates];
-+  CLzmaProb isRepG2[kNumStates];
-+  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+
-+  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
-+  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
-+  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-+  
-+  CLenPriceEnc lenEnc;
-+  CLenPriceEnc repLenEnc;
-+
-+  UInt32 reps[LZMA_NUM_REPS];
-+  UInt32 state;
-+} CSaveState;
-+
-+typedef struct
-+{
-+  IMatchFinder matchFinder;
-+  void *matchFinderObj;
-+
-+  #ifndef _7ZIP_ST
-+  Bool mtMode;
-+  CMatchFinderMt matchFinderMt;
-+  #endif
-+
-+  CMatchFinder matchFinderBase;
-+
-+  #ifndef _7ZIP_ST
-+  Byte pad[128];
-+  #endif
-+  
-+  UInt32 optimumEndIndex;
-+  UInt32 optimumCurrentIndex;
-+
-+  UInt32 longestMatchLength;
-+  UInt32 numPairs;
-+  UInt32 numAvail;
-+  COptimal opt[kNumOpts];
-+  
-+  #ifndef LZMA_LOG_BSR
-+  Byte g_FastPos[1 << kNumLogBits];
-+  #endif
-+
-+  UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
-+  UInt32 matches[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
-+  UInt32 numFastBytes;
-+  UInt32 additionalOffset;
-+  UInt32 reps[LZMA_NUM_REPS];
-+  UInt32 state;
-+
-+  UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
-+  UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
-+  UInt32 alignPrices[kAlignTableSize];
-+  UInt32 alignPriceCount;
-+
-+  UInt32 distTableSize;
-+
-+  unsigned lc, lp, pb;
-+  unsigned lpMask, pbMask;
-+
-+  CLzmaProb *litProbs;
-+
-+  CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+  CLzmaProb isRep[kNumStates];
-+  CLzmaProb isRepG0[kNumStates];
-+  CLzmaProb isRepG1[kNumStates];
-+  CLzmaProb isRepG2[kNumStates];
-+  CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
-+
-+  CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
-+  CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
-+  CLzmaProb posAlignEncoder[1 << kNumAlignBits];
-+  
-+  CLenPriceEnc lenEnc;
-+  CLenPriceEnc repLenEnc;
-+
-+  unsigned lclp;
-+
-+  Bool fastMode;
-+  
-+  CRangeEnc rc;
-+
-+  Bool writeEndMark;
-+  UInt64 nowPos64;
-+  UInt32 matchPriceCount;
-+  Bool finished;
-+  Bool multiThread;
-+
-+  SRes result;
-+  UInt32 dictSize;
-+  UInt32 matchFinderCycles;
-+
-+  int needInit;
-+
-+  CSaveState saveState;
-+} CLzmaEnc;
-+
-+void LzmaEnc_SaveState(CLzmaEncHandle pp)
-+{
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+  CSaveState *dest = &p->saveState;
-+  int i;
-+  dest->lenEnc = p->lenEnc;
-+  dest->repLenEnc = p->repLenEnc;
-+  dest->state = p->state;
-+
-+  for (i = 0; i < kNumStates; i++)
-+  {
-+    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
-+    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
-+  }
-+  for (i = 0; i < kNumLenToPosStates; i++)
-+    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
-+  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
-+  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
-+  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
-+  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
-+  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
-+  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
-+  memcpy(dest->reps, p->reps, sizeof(p->reps));
-+  memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
-+}
-+
-+void LzmaEnc_RestoreState(CLzmaEncHandle pp)
-+{
-+  CLzmaEnc *dest = (CLzmaEnc *)pp;
-+  const CSaveState *p = &dest->saveState;
-+  int i;
-+  dest->lenEnc = p->lenEnc;
-+  dest->repLenEnc = p->repLenEnc;
-+  dest->state = p->state;
-+
-+  for (i = 0; i < kNumStates; i++)
-+  {
-+    memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
-+    memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
-+  }
-+  for (i = 0; i < kNumLenToPosStates; i++)
-+    memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
-+  memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
-+  memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
-+  memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
-+  memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
-+  memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
-+  memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
-+  memcpy(dest->reps, p->reps, sizeof(p->reps));
-+  memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
-+}
-+
-+SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
-+{
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+  CLzmaEncProps props = *props2;
-+  LzmaEncProps_Normalize(&props);
-+
-+  if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
-+      props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
-+    return SZ_ERROR_PARAM;
-+  p->dictSize = props.dictSize;
-+  p->matchFinderCycles = props.mc;
-+  {
-+    unsigned fb = props.fb;
-+    if (fb < 5)
-+      fb = 5;
-+    if (fb > LZMA_MATCH_LEN_MAX)
-+      fb = LZMA_MATCH_LEN_MAX;
-+    p->numFastBytes = fb;
-+  }
-+  p->lc = props.lc;
-+  p->lp = props.lp;
-+  p->pb = props.pb;
-+  p->fastMode = (props.algo == 0);
-+  p->matchFinderBase.btMode = props.btMode;
-+  {
-+    UInt32 numHashBytes = 4;
-+    if (props.btMode)
-+    {
-+      if (props.numHashBytes < 2)
-+        numHashBytes = 2;
-+      else if (props.numHashBytes < 4)
-+        numHashBytes = props.numHashBytes;
-+    }
-+    p->matchFinderBase.numHashBytes = numHashBytes;
-+  }
-+
-+  p->matchFinderBase.cutValue = props.mc;
-+
-+  p->writeEndMark = props.writeEndMark;
-+
-+  #ifndef _7ZIP_ST
-+  /*
-+  if (newMultiThread != _multiThread)
-+  {
-+    ReleaseMatchFinder();
-+    _multiThread = newMultiThread;
-+  }
-+  */
-+  p->multiThread = (props.numThreads > 1);
-+  #endif
-+
-+  return SZ_OK;
-+}
-+
-+static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4,  5,  6,   4, 5};
-+static const int kMatchNextStates[kNumStates]   = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
-+static const int kRepNextStates[kNumStates]     = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
-+static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
-+
-+#define IsCharState(s) ((s) < 7)
-+
-+#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
-+
-+#define kInfinityPrice (1 << 30)
-+
-+static void RangeEnc_Construct(CRangeEnc *p)
-+{
-+  p->outStream = 0;
-+  p->bufBase = 0;
-+}
-+
-+#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
-+
-+#define RC_BUF_SIZE (1 << 16)
-+static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
-+{
-+  if (p->bufBase == 0)
-+  {
-+    p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
-+    if (p->bufBase == 0)
-+      return 0;
-+    p->bufLim = p->bufBase + RC_BUF_SIZE;
-+  }
-+  return 1;
-+}
-+
-+static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
-+{
-+  alloc->Free(alloc, p->bufBase);
-+  p->bufBase = 0;
-+}
-+
-+static void RangeEnc_Init(CRangeEnc *p)
-+{
-+  /* Stream.Init(); */
-+  p->low = 0;
-+  p->range = 0xFFFFFFFF;
-+  p->cacheSize = 1;
-+  p->cache = 0;
-+
-+  p->buf = p->bufBase;
-+
-+  p->processed = 0;
-+  p->res = SZ_OK;
-+}
-+
-+static void RangeEnc_FlushStream(CRangeEnc *p)
-+{
-+  size_t num;
-+  if (p->res != SZ_OK)
-+    return;
-+  num = p->buf - p->bufBase;
-+  if (num != p->outStream->Write(p->outStream, p->bufBase, num))
-+    p->res = SZ_ERROR_WRITE;
-+  p->processed += num;
-+  p->buf = p->bufBase;
-+}
-+
-+static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
-+{
-+  if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
-+  {
-+    Byte temp = p->cache;
-+    do
-+    {
-+      Byte *buf = p->buf;
-+      *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
-+      p->buf = buf;
-+      if (buf == p->bufLim)
-+        RangeEnc_FlushStream(p);
-+      temp = 0xFF;
-+    }
-+    while (--p->cacheSize != 0);
-+    p->cache = (Byte)((UInt32)p->low >> 24);
-+  }
-+  p->cacheSize++;
-+  p->low = (UInt32)p->low << 8;
-+}
-+
-+static void RangeEnc_FlushData(CRangeEnc *p)
-+{
-+  int i;
-+  for (i = 0; i < 5; i++)
-+    RangeEnc_ShiftLow(p);
-+}
-+
-+static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
-+{
-+  do
-+  {
-+    p->range >>= 1;
-+    p->low += p->range & (0 - ((value >> --numBits) & 1));
-+    if (p->range < kTopValue)
-+    {
-+      p->range <<= 8;
-+      RangeEnc_ShiftLow(p);
-+    }
-+  }
-+  while (numBits != 0);
-+}
-+
-+static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
-+{
-+  UInt32 ttt = *prob;
-+  UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
-+  if (symbol == 0)
-+  {
-+    p->range = newBound;
-+    ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
-+  }
-+  else
-+  {
-+    p->low += newBound;
-+    p->range -= newBound;
-+    ttt -= ttt >> kNumMoveBits;
-+  }
-+  *prob = (CLzmaProb)ttt;
-+  if (p->range < kTopValue)
-+  {
-+    p->range <<= 8;
-+    RangeEnc_ShiftLow(p);
-+  }
-+}
-+
-+static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
-+{
-+  symbol |= 0x100;
-+  do
-+  {
-+    RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
-+    symbol <<= 1;
-+  }
-+  while (symbol < 0x10000);
-+}
-+
-+static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
-+{
-+  UInt32 offs = 0x100;
-+  symbol |= 0x100;
-+  do
-+  {
-+    matchByte <<= 1;
-+    RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
-+    symbol <<= 1;
-+    offs &= ~(matchByte ^ symbol);
-+  }
-+  while (symbol < 0x10000);
-+}
-+
-+void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
-+{
-+  UInt32 i;
-+  for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
-+  {
-+    const int kCyclesBits = kNumBitPriceShiftBits;
-+    UInt32 w = i;
-+    UInt32 bitCount = 0;
-+    int j;
-+    for (j = 0; j < kCyclesBits; j++)
-+    {
-+      w = w * w;
-+      bitCount <<= 1;
-+      while (w >= ((UInt32)1 << 16))
-+      {
-+        w >>= 1;
-+        bitCount++;
-+      }
-+    }
-+    ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
-+  }
-+}
-+
-+
-+#define GET_PRICE(prob, symbol) \
-+  p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-+
-+#define GET_PRICEa(prob, symbol) \
-+  ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
-+
-+#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
-+#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-+
-+#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
-+#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
-+
-+static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+  UInt32 price = 0;
-+  symbol |= 0x100;
-+  do
-+  {
-+    price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
-+    symbol <<= 1;
-+  }
-+  while (symbol < 0x10000);
-+  return price;
-+}
-+
-+static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
-+{
-+  UInt32 price = 0;
-+  UInt32 offs = 0x100;
-+  symbol |= 0x100;
-+  do
-+  {
-+    matchByte <<= 1;
-+    price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
-+    symbol <<= 1;
-+    offs &= ~(matchByte ^ symbol);
-+  }
-+  while (symbol < 0x10000);
-+  return price;
-+}
-+
-+
-+static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-+{
-+  UInt32 m = 1;
-+  int i;
-+  for (i = numBitLevels; i != 0;)
-+  {
-+    UInt32 bit;
-+    i--;
-+    bit = (symbol >> i) & 1;
-+    RangeEnc_EncodeBit(rc, probs + m, bit);
-+    m = (m << 1) | bit;
-+  }
-+}
-+
-+static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
-+{
-+  UInt32 m = 1;
-+  int i;
-+  for (i = 0; i < numBitLevels; i++)
-+  {
-+    UInt32 bit = symbol & 1;
-+    RangeEnc_EncodeBit(rc, probs + m, bit);
-+    m = (m << 1) | bit;
-+    symbol >>= 1;
-+  }
-+}
-+
-+static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+  UInt32 price = 0;
-+  symbol |= (1 << numBitLevels);
-+  while (symbol != 1)
-+  {
-+    price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
-+    symbol >>= 1;
-+  }
-+  return price;
-+}
-+
-+static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
-+{
-+  UInt32 price = 0;
-+  UInt32 m = 1;
-+  int i;
-+  for (i = numBitLevels; i != 0; i--)
-+  {
-+    UInt32 bit = symbol & 1;
-+    symbol >>= 1;
-+    price += GET_PRICEa(probs[m], bit);
-+    m = (m << 1) | bit;
-+  }
-+  return price;
-+}
-+
-+
-+static void LenEnc_Init(CLenEnc *p)
-+{
-+  unsigned i;
-+  p->choice = p->choice2 = kProbInitValue;
-+  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
-+    p->low[i] = kProbInitValue;
-+  for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
-+    p->mid[i] = kProbInitValue;
-+  for (i = 0; i < kLenNumHighSymbols; i++)
-+    p->high[i] = kProbInitValue;
-+}
-+
-+static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
-+{
-+  if (symbol < kLenNumLowSymbols)
-+  {
-+    RangeEnc_EncodeBit(rc, &p->choice, 0);
-+    RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
-+  }
-+  else
-+  {
-+    RangeEnc_EncodeBit(rc, &p->choice, 1);
-+    if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
-+    {
-+      RangeEnc_EncodeBit(rc, &p->choice2, 0);
-+      RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
-+    }
-+    else
-+    {
-+      RangeEnc_EncodeBit(rc, &p->choice2, 1);
-+      RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
-+    }
-+  }
-+}
-+
-+static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
-+{
-+  UInt32 a0 = GET_PRICE_0a(p->choice);
-+  UInt32 a1 = GET_PRICE_1a(p->choice);
-+  UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
-+  UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
-+  UInt32 i = 0;
-+  for (i = 0; i < kLenNumLowSymbols; i++)
-+  {
-+    if (i >= numSymbols)
-+      return;
-+    prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
-+  }
-+  for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
-+  {
-+    if (i >= numSymbols)
-+      return;
-+    prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
-+  }
-+  for (; i < numSymbols; i++)
-+    prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
-+}
-+
-+static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
-+{
-+  LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
-+  p->counters[posState] = p->tableSize;
-+}
-+
-+static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
-+{
-+  UInt32 posState;
-+  for (posState = 0; posState < numPosStates; posState++)
-+    LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-+}
-+
-+static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
-+{
-+  LenEnc_Encode(&p->p, rc, symbol, posState);
-+  if (updatePrice)
-+    if (--p->counters[posState] == 0)
-+      LenPriceEnc_UpdateTable(p, posState, ProbPrices);
-+}
-+
-+
-+
-+
-+static void MovePos(CLzmaEnc *p, UInt32 num)
-+{
-+  #ifdef SHOW_STAT
-+  ttt += num;
-+  printf("\n MovePos %d", num);
-+  #endif
-+  if (num != 0)
-+  {
-+    p->additionalOffset += num;
-+    p->matchFinder.Skip(p->matchFinderObj, num);
-+  }
-+}
-+
-+static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
-+{
-+  UInt32 lenRes = 0, numPairs;
-+  p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-+  numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
-+  #ifdef SHOW_STAT
-+  printf("\n i = %d numPairs = %d    ", ttt, numPairs / 2);
-+  ttt++;
-+  {
-+    UInt32 i;
-+    for (i = 0; i < numPairs; i += 2)
-+      printf("%2d %6d   | ", p->matches[i], p->matches[i + 1]);
-+  }
-+  #endif
-+  if (numPairs > 0)
-+  {
-+    lenRes = p->matches[numPairs - 2];
-+    if (lenRes == p->numFastBytes)
-+    {
-+      const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+      UInt32 distance = p->matches[numPairs - 1] + 1;
-+      UInt32 numAvail = p->numAvail;
-+      if (numAvail > LZMA_MATCH_LEN_MAX)
-+        numAvail = LZMA_MATCH_LEN_MAX;
-+      {
-+        const Byte *pby2 = pby - distance;
-+        for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
-+      }
-+    }
-+  }
-+  p->additionalOffset++;
-+  *numDistancePairsRes = numPairs;
-+  return lenRes;
-+}
-+
-+
-+#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
-+#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
-+#define IsShortRep(p) ((p)->backPrev == 0)
-+
-+static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
-+{
-+  return
-+    GET_PRICE_0(p->isRepG0[state]) +
-+    GET_PRICE_0(p->isRep0Long[state][posState]);
-+}
-+
-+static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
-+{
-+  UInt32 price;
-+  if (repIndex == 0)
-+  {
-+    price = GET_PRICE_0(p->isRepG0[state]);
-+    price += GET_PRICE_1(p->isRep0Long[state][posState]);
-+  }
-+  else
-+  {
-+    price = GET_PRICE_1(p->isRepG0[state]);
-+    if (repIndex == 1)
-+      price += GET_PRICE_0(p->isRepG1[state]);
-+    else
-+    {
-+      price += GET_PRICE_1(p->isRepG1[state]);
-+      price += GET_PRICE(p->isRepG2[state], repIndex - 2);
-+    }
-+  }
-+  return price;
-+}
-+
-+static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
-+{
-+  return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
-+    GetPureRepPrice(p, repIndex, state, posState);
-+}
-+
-+static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
-+{
-+  UInt32 posMem = p->opt[cur].posPrev;
-+  UInt32 backMem = p->opt[cur].backPrev;
-+  p->optimumEndIndex = cur;
-+  do
-+  {
-+    if (p->opt[cur].prev1IsChar)
-+    {
-+      MakeAsChar(&p->opt[posMem])
-+      p->opt[posMem].posPrev = posMem - 1;
-+      if (p->opt[cur].prev2)
-+      {
-+        p->opt[posMem - 1].prev1IsChar = False;
-+        p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
-+        p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
-+      }
-+    }
-+    {
-+      UInt32 posPrev = posMem;
-+      UInt32 backCur = backMem;
-+      
-+      backMem = p->opt[posPrev].backPrev;
-+      posMem = p->opt[posPrev].posPrev;
-+      
-+      p->opt[posPrev].backPrev = backCur;
-+      p->opt[posPrev].posPrev = cur;
-+      cur = posPrev;
-+    }
-+  }
-+  while (cur != 0);
-+  *backRes = p->opt[0].backPrev;
-+  p->optimumCurrentIndex  = p->opt[0].posPrev;
-+  return p->optimumCurrentIndex;
-+}
-+
-+#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
-+
-+static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
-+{
-+  UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
-+  UInt32 matchPrice, repMatchPrice, normalMatchPrice;
-+  UInt32 reps[LZMA_NUM_REPS], repLens[LZMA_NUM_REPS];
-+  UInt32 *matches;
-+  const Byte *data;
-+  Byte curByte, matchByte;
-+  if (p->optimumEndIndex != p->optimumCurrentIndex)
-+  {
-+    const COptimal *opt = &p->opt[p->optimumCurrentIndex];
-+    UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
-+    *backRes = opt->backPrev;
-+    p->optimumCurrentIndex = opt->posPrev;
-+    return lenRes;
-+  }
-+  p->optimumCurrentIndex = p->optimumEndIndex = 0;
-+  
-+  if (p->additionalOffset == 0)
-+    mainLen = ReadMatchDistances(p, &numPairs);
-+  else
-+  {
-+    mainLen = p->longestMatchLength;
-+    numPairs = p->numPairs;
-+  }
-+
-+  numAvail = p->numAvail;
-+  if (numAvail < 2)
-+  {
-+    *backRes = (UInt32)(-1);
-+    return 1;
-+  }
-+  if (numAvail > LZMA_MATCH_LEN_MAX)
-+    numAvail = LZMA_MATCH_LEN_MAX;
-+
-+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+  repMaxIndex = 0;
-+  for (i = 0; i < LZMA_NUM_REPS; i++)
-+  {
-+    UInt32 lenTest;
-+    const Byte *data2;
-+    reps[i] = p->reps[i];
-+    data2 = data - (reps[i] + 1);
-+    if (data[0] != data2[0] || data[1] != data2[1])
-+    {
-+      repLens[i] = 0;
-+      continue;
-+    }
-+    for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
-+    repLens[i] = lenTest;
-+    if (lenTest > repLens[repMaxIndex])
-+      repMaxIndex = i;
-+  }
-+  if (repLens[repMaxIndex] >= p->numFastBytes)
-+  {
-+    UInt32 lenRes;
-+    *backRes = repMaxIndex;
-+    lenRes = repLens[repMaxIndex];
-+    MovePos(p, lenRes - 1);
-+    return lenRes;
-+  }
-+
-+  matches = p->matches;
-+  if (mainLen >= p->numFastBytes)
-+  {
-+    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
-+    MovePos(p, mainLen - 1);
-+    return mainLen;
-+  }
-+  curByte = *data;
-+  matchByte = *(data - (reps[0] + 1));
-+
-+  if (mainLen < 2 && curByte != matchByte && repLens[repMaxIndex] < 2)
-+  {
-+    *backRes = (UInt32)-1;
-+    return 1;
-+  }
-+
-+  p->opt[0].state = (CState)p->state;
-+
-+  posState = (position & p->pbMask);
-+
-+  {
-+    const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
-+    p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
-+        (!IsCharState(p->state) ?
-+          LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
-+          LitEnc_GetPrice(probs, curByte, p->ProbPrices));
-+  }
-+
-+  MakeAsChar(&p->opt[1]);
-+
-+  matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
-+  repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
-+
-+  if (matchByte == curByte)
-+  {
-+    UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
-+    if (shortRepPrice < p->opt[1].price)
-+    {
-+      p->opt[1].price = shortRepPrice;
-+      MakeAsShortRep(&p->opt[1]);
-+    }
-+  }
-+  lenEnd = ((mainLen >= repLens[repMaxIndex]) ? mainLen : repLens[repMaxIndex]);
-+
-+  if (lenEnd < 2)
-+  {
-+    *backRes = p->opt[1].backPrev;
-+    return 1;
-+  }
-+
-+  p->opt[1].posPrev = 0;
-+  for (i = 0; i < LZMA_NUM_REPS; i++)
-+    p->opt[0].backs[i] = reps[i];
-+
-+  len = lenEnd;
-+  do
-+    p->opt[len--].price = kInfinityPrice;
-+  while (len >= 2);
-+
-+  for (i = 0; i < LZMA_NUM_REPS; i++)
-+  {
-+    UInt32 repLen = repLens[i];
-+    UInt32 price;
-+    if (repLen < 2)
-+      continue;
-+    price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
-+    do
-+    {
-+      UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
-+      COptimal *opt = &p->opt[repLen];
-+      if (curAndLenPrice < opt->price)
-+      {
-+        opt->price = curAndLenPrice;
-+        opt->posPrev = 0;
-+        opt->backPrev = i;
-+        opt->prev1IsChar = False;
-+      }
-+    }
-+    while (--repLen >= 2);
-+  }
-+
-+  normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
-+
-+  len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
-+  if (len <= mainLen)
-+  {
-+    UInt32 offs = 0;
-+    while (len > matches[offs])
-+      offs += 2;
-+    for (; ; len++)
-+    {
-+      COptimal *opt;
-+      UInt32 distance = matches[offs + 1];
-+
-+      UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
-+      UInt32 lenToPosState = GetLenToPosState(len);
-+      if (distance < kNumFullDistances)
-+        curAndLenPrice += p->distancesPrices[lenToPosState][distance];
-+      else
-+      {
-+        UInt32 slot;
-+        GetPosSlot2(distance, slot);
-+        curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
-+      }
-+      opt = &p->opt[len];
-+      if (curAndLenPrice < opt->price)
-+      {
-+        opt->price = curAndLenPrice;
-+        opt->posPrev = 0;
-+        opt->backPrev = distance + LZMA_NUM_REPS;
-+        opt->prev1IsChar = False;
-+      }
-+      if (len == matches[offs])
-+      {
-+        offs += 2;
-+        if (offs == numPairs)
-+          break;
-+      }
-+    }
-+  }
-+
-+  cur = 0;
-+
-+    #ifdef SHOW_STAT2
-+    if (position >= 0)
-+    {
-+      unsigned i;
-+      printf("\n pos = %4X", position);
-+      for (i = cur; i <= lenEnd; i++)
-+      printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
-+    }
-+    #endif
-+
-+  for (;;)
-+  {
-+    UInt32 numAvailFull, newLen, numPairs, posPrev, state, posState, startLen;
-+    UInt32 curPrice, curAnd1Price, matchPrice, repMatchPrice;
-+    Bool nextIsChar;
-+    Byte curByte, matchByte;
-+    const Byte *data;
-+    COptimal *curOpt;
-+    COptimal *nextOpt;
-+
-+    cur++;
-+    if (cur == lenEnd)
-+      return Backward(p, backRes, cur);
-+
-+    newLen = ReadMatchDistances(p, &numPairs);
-+    if (newLen >= p->numFastBytes)
-+    {
-+      p->numPairs = numPairs;
-+      p->longestMatchLength = newLen;
-+      return Backward(p, backRes, cur);
-+    }
-+    position++;
-+    curOpt = &p->opt[cur];
-+    posPrev = curOpt->posPrev;
-+    if (curOpt->prev1IsChar)
-+    {
-+      posPrev--;
-+      if (curOpt->prev2)
-+      {
-+        state = p->opt[curOpt->posPrev2].state;
-+        if (curOpt->backPrev2 < LZMA_NUM_REPS)
-+          state = kRepNextStates[state];
-+        else
-+          state = kMatchNextStates[state];
-+      }
-+      else
-+        state = p->opt[posPrev].state;
-+      state = kLiteralNextStates[state];
-+    }
-+    else
-+      state = p->opt[posPrev].state;
-+    if (posPrev == cur - 1)
-+    {
-+      if (IsShortRep(curOpt))
-+        state = kShortRepNextStates[state];
-+      else
-+        state = kLiteralNextStates[state];
-+    }
-+    else
-+    {
-+      UInt32 pos;
-+      const COptimal *prevOpt;
-+      if (curOpt->prev1IsChar && curOpt->prev2)
-+      {
-+        posPrev = curOpt->posPrev2;
-+        pos = curOpt->backPrev2;
-+        state = kRepNextStates[state];
-+      }
-+      else
-+      {
-+        pos = curOpt->backPrev;
-+        if (pos < LZMA_NUM_REPS)
-+          state = kRepNextStates[state];
-+        else
-+          state = kMatchNextStates[state];
-+      }
-+      prevOpt = &p->opt[posPrev];
-+      if (pos < LZMA_NUM_REPS)
-+      {
-+        UInt32 i;
-+        reps[0] = prevOpt->backs[pos];
-+        for (i = 1; i <= pos; i++)
-+          reps[i] = prevOpt->backs[i - 1];
-+        for (; i < LZMA_NUM_REPS; i++)
-+          reps[i] = prevOpt->backs[i];
-+      }
-+      else
-+      {
-+        UInt32 i;
-+        reps[0] = (pos - LZMA_NUM_REPS);
-+        for (i = 1; i < LZMA_NUM_REPS; i++)
-+          reps[i] = prevOpt->backs[i - 1];
-+      }
-+    }
-+    curOpt->state = (CState)state;
-+
-+    curOpt->backs[0] = reps[0];
-+    curOpt->backs[1] = reps[1];
-+    curOpt->backs[2] = reps[2];
-+    curOpt->backs[3] = reps[3];
-+
-+    curPrice = curOpt->price;
-+    nextIsChar = False;
-+    data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+    curByte = *data;
-+    matchByte = *(data - (reps[0] + 1));
-+
-+    posState = (position & p->pbMask);
-+
-+    curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
-+    {
-+      const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
-+      curAnd1Price +=
-+        (!IsCharState(state) ?
-+          LitEnc_GetPriceMatched(probs, curByte, matchByte, p->ProbPrices) :
-+          LitEnc_GetPrice(probs, curByte, p->ProbPrices));
-+    }
-+
-+    nextOpt = &p->opt[cur + 1];
-+
-+    if (curAnd1Price < nextOpt->price)
-+    {
-+      nextOpt->price = curAnd1Price;
-+      nextOpt->posPrev = cur;
-+      MakeAsChar(nextOpt);
-+      nextIsChar = True;
-+    }
-+
-+    matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
-+    repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
-+    
-+    if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
-+    {
-+      UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
-+      if (shortRepPrice <= nextOpt->price)
-+      {
-+        nextOpt->price = shortRepPrice;
-+        nextOpt->posPrev = cur;
-+        MakeAsShortRep(nextOpt);
-+        nextIsChar = True;
-+      }
-+    }
-+    numAvailFull = p->numAvail;
-+    {
-+      UInt32 temp = kNumOpts - 1 - cur;
-+      if (temp < numAvailFull)
-+        numAvailFull = temp;
-+    }
-+
-+    if (numAvailFull < 2)
-+      continue;
-+    numAvail = (numAvailFull <= p->numFastBytes ? numAvailFull : p->numFastBytes);
-+
-+    if (!nextIsChar && matchByte != curByte) /* speed optimization */
-+    {
-+      /* try Literal + rep0 */
-+      UInt32 temp;
-+      UInt32 lenTest2;
-+      const Byte *data2 = data - (reps[0] + 1);
-+      UInt32 limit = p->numFastBytes + 1;
-+      if (limit > numAvailFull)
-+        limit = numAvailFull;
-+
-+      for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
-+      lenTest2 = temp - 1;
-+      if (lenTest2 >= 2)
-+      {
-+        UInt32 state2 = kLiteralNextStates[state];
-+        UInt32 posStateNext = (position + 1) & p->pbMask;
-+        UInt32 nextRepMatchPrice = curAnd1Price +
-+            GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+            GET_PRICE_1(p->isRep[state2]);
-+        /* for (; lenTest2 >= 2; lenTest2--) */
-+        {
-+          UInt32 curAndLenPrice;
-+          COptimal *opt;
-+          UInt32 offset = cur + 1 + lenTest2;
-+          while (lenEnd < offset)
-+            p->opt[++lenEnd].price = kInfinityPrice;
-+          curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+          opt = &p->opt[offset];
-+          if (curAndLenPrice < opt->price)
-+          {
-+            opt->price = curAndLenPrice;
-+            opt->posPrev = cur + 1;
-+            opt->backPrev = 0;
-+            opt->prev1IsChar = True;
-+            opt->prev2 = False;
-+          }
-+        }
-+      }
-+    }
-+    
-+    startLen = 2; /* speed optimization */
-+    {
-+    UInt32 repIndex;
-+    for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
-+    {
-+      UInt32 lenTest;
-+      UInt32 lenTestTemp;
-+      UInt32 price;
-+      const Byte *data2 = data - (reps[repIndex] + 1);
-+      if (data[0] != data2[0] || data[1] != data2[1])
-+        continue;
-+      for (lenTest = 2; lenTest < numAvail && data[lenTest] == data2[lenTest]; lenTest++);
-+      while (lenEnd < cur + lenTest)
-+        p->opt[++lenEnd].price = kInfinityPrice;
-+      lenTestTemp = lenTest;
-+      price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
-+      do
-+      {
-+        UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
-+        COptimal *opt = &p->opt[cur + lenTest];
-+        if (curAndLenPrice < opt->price)
-+        {
-+          opt->price = curAndLenPrice;
-+          opt->posPrev = cur;
-+          opt->backPrev = repIndex;
-+          opt->prev1IsChar = False;
-+        }
-+      }
-+      while (--lenTest >= 2);
-+      lenTest = lenTestTemp;
-+      
-+      if (repIndex == 0)
-+        startLen = lenTest + 1;
-+        
-+      /* if (_maxMode) */
-+        {
-+          UInt32 lenTest2 = lenTest + 1;
-+          UInt32 limit = lenTest2 + p->numFastBytes;
-+          UInt32 nextRepMatchPrice;
-+          if (limit > numAvailFull)
-+            limit = numAvailFull;
-+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-+          lenTest2 -= lenTest + 1;
-+          if (lenTest2 >= 2)
-+          {
-+            UInt32 state2 = kRepNextStates[state];
-+            UInt32 posStateNext = (position + lenTest) & p->pbMask;
-+            UInt32 curAndLenCharPrice =
-+                price + p->repLenEnc.prices[posState][lenTest - 2] +
-+                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-+                    data[lenTest], data2[lenTest], p->ProbPrices);
-+            state2 = kLiteralNextStates[state2];
-+            posStateNext = (position + lenTest + 1) & p->pbMask;
-+            nextRepMatchPrice = curAndLenCharPrice +
-+                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+                GET_PRICE_1(p->isRep[state2]);
-+            
-+            /* for (; lenTest2 >= 2; lenTest2--) */
-+            {
-+              UInt32 curAndLenPrice;
-+              COptimal *opt;
-+              UInt32 offset = cur + lenTest + 1 + lenTest2;
-+              while (lenEnd < offset)
-+                p->opt[++lenEnd].price = kInfinityPrice;
-+              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+              opt = &p->opt[offset];
-+              if (curAndLenPrice < opt->price)
-+              {
-+                opt->price = curAndLenPrice;
-+                opt->posPrev = cur + lenTest + 1;
-+                opt->backPrev = 0;
-+                opt->prev1IsChar = True;
-+                opt->prev2 = True;
-+                opt->posPrev2 = cur;
-+                opt->backPrev2 = repIndex;
-+              }
-+            }
-+          }
-+        }
-+    }
-+    }
-+    /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
-+    if (newLen > numAvail)
-+    {
-+      newLen = numAvail;
-+      for (numPairs = 0; newLen > matches[numPairs]; numPairs += 2);
-+      matches[numPairs] = newLen;
-+      numPairs += 2;
-+    }
-+    if (newLen >= startLen)
-+    {
-+      UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
-+      UInt32 offs, curBack, posSlot;
-+      UInt32 lenTest;
-+      while (lenEnd < cur + newLen)
-+        p->opt[++lenEnd].price = kInfinityPrice;
-+
-+      offs = 0;
-+      while (startLen > matches[offs])
-+        offs += 2;
-+      curBack = matches[offs + 1];
-+      GetPosSlot2(curBack, posSlot);
-+      for (lenTest = /*2*/ startLen; ; lenTest++)
-+      {
-+        UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
-+        UInt32 lenToPosState = GetLenToPosState(lenTest);
-+        COptimal *opt;
-+        if (curBack < kNumFullDistances)
-+          curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
-+        else
-+          curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
-+        
-+        opt = &p->opt[cur + lenTest];
-+        if (curAndLenPrice < opt->price)
-+        {
-+          opt->price = curAndLenPrice;
-+          opt->posPrev = cur;
-+          opt->backPrev = curBack + LZMA_NUM_REPS;
-+          opt->prev1IsChar = False;
-+        }
-+
-+        if (/*_maxMode && */lenTest == matches[offs])
-+        {
-+          /* Try Match + Literal + Rep0 */
-+          const Byte *data2 = data - (curBack + 1);
-+          UInt32 lenTest2 = lenTest + 1;
-+          UInt32 limit = lenTest2 + p->numFastBytes;
-+          UInt32 nextRepMatchPrice;
-+          if (limit > numAvailFull)
-+            limit = numAvailFull;
-+          for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
-+          lenTest2 -= lenTest + 1;
-+          if (lenTest2 >= 2)
-+          {
-+            UInt32 state2 = kMatchNextStates[state];
-+            UInt32 posStateNext = (position + lenTest) & p->pbMask;
-+            UInt32 curAndLenCharPrice = curAndLenPrice +
-+                GET_PRICE_0(p->isMatch[state2][posStateNext]) +
-+                LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
-+                    data[lenTest], data2[lenTest], p->ProbPrices);
-+            state2 = kLiteralNextStates[state2];
-+            posStateNext = (posStateNext + 1) & p->pbMask;
-+            nextRepMatchPrice = curAndLenCharPrice +
-+                GET_PRICE_1(p->isMatch[state2][posStateNext]) +
-+                GET_PRICE_1(p->isRep[state2]);
-+            
-+            /* for (; lenTest2 >= 2; lenTest2--) */
-+            {
-+              UInt32 offset = cur + lenTest + 1 + lenTest2;
-+              UInt32 curAndLenPrice;
-+              COptimal *opt;
-+              while (lenEnd < offset)
-+                p->opt[++lenEnd].price = kInfinityPrice;
-+              curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
-+              opt = &p->opt[offset];
-+              if (curAndLenPrice < opt->price)
-+              {
-+                opt->price = curAndLenPrice;
-+                opt->posPrev = cur + lenTest + 1;
-+                opt->backPrev = 0;
-+                opt->prev1IsChar = True;
-+                opt->prev2 = True;
-+                opt->posPrev2 = cur;
-+                opt->backPrev2 = curBack + LZMA_NUM_REPS;
-+              }
-+            }
-+          }
-+          offs += 2;
-+          if (offs == numPairs)
-+            break;
-+          curBack = matches[offs + 1];
-+          if (curBack >= kNumFullDistances)
-+            GetPosSlot2(curBack, posSlot);
-+        }
-+      }
-+    }
-+  }
-+}
-+
-+#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
-+
-+static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
-+{
-+  UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
-+  const Byte *data;
-+  const UInt32 *matches;
-+
-+  if (p->additionalOffset == 0)
-+    mainLen = ReadMatchDistances(p, &numPairs);
-+  else
-+  {
-+    mainLen = p->longestMatchLength;
-+    numPairs = p->numPairs;
-+  }
-+
-+  numAvail = p->numAvail;
-+  *backRes = (UInt32)-1;
-+  if (numAvail < 2)
-+    return 1;
-+  if (numAvail > LZMA_MATCH_LEN_MAX)
-+    numAvail = LZMA_MATCH_LEN_MAX;
-+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+
-+  repLen = repIndex = 0;
-+  for (i = 0; i < LZMA_NUM_REPS; i++)
-+  {
-+    UInt32 len;
-+    const Byte *data2 = data - (p->reps[i] + 1);
-+    if (data[0] != data2[0] || data[1] != data2[1])
-+      continue;
-+    for (len = 2; len < numAvail && data[len] == data2[len]; len++);
-+    if (len >= p->numFastBytes)
-+    {
-+      *backRes = i;
-+      MovePos(p, len - 1);
-+      return len;
-+    }
-+    if (len > repLen)
-+    {
-+      repIndex = i;
-+      repLen = len;
-+    }
-+  }
-+
-+  matches = p->matches;
-+  if (mainLen >= p->numFastBytes)
-+  {
-+    *backRes = matches[numPairs - 1] + LZMA_NUM_REPS;
-+    MovePos(p, mainLen - 1);
-+    return mainLen;
-+  }
-+
-+  mainDist = 0; /* for GCC */
-+  if (mainLen >= 2)
-+  {
-+    mainDist = matches[numPairs - 1];
-+    while (numPairs > 2 && mainLen == matches[numPairs - 4] + 1)
-+    {
-+      if (!ChangePair(matches[numPairs - 3], mainDist))
-+        break;
-+      numPairs -= 2;
-+      mainLen = matches[numPairs - 2];
-+      mainDist = matches[numPairs - 1];
-+    }
-+    if (mainLen == 2 && mainDist >= 0x80)
-+      mainLen = 1;
-+  }
-+
-+  if (repLen >= 2 && (
-+        (repLen + 1 >= mainLen) ||
-+        (repLen + 2 >= mainLen && mainDist >= (1 << 9)) ||
-+        (repLen + 3 >= mainLen && mainDist >= (1 << 15))))
-+  {
-+    *backRes = repIndex;
-+    MovePos(p, repLen - 1);
-+    return repLen;
-+  }
-+  
-+  if (mainLen < 2 || numAvail <= 2)
-+    return 1;
-+
-+  p->longestMatchLength = ReadMatchDistances(p, &p->numPairs);
-+  if (p->longestMatchLength >= 2)
-+  {
-+    UInt32 newDistance = matches[p->numPairs - 1];
-+    if ((p->longestMatchLength >= mainLen && newDistance < mainDist) ||
-+        (p->longestMatchLength == mainLen + 1 && !ChangePair(mainDist, newDistance)) ||
-+        (p->longestMatchLength > mainLen + 1) ||
-+        (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist)))
-+      return 1;
-+  }
-+  
-+  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
-+  for (i = 0; i < LZMA_NUM_REPS; i++)
-+  {
-+    UInt32 len, limit;
-+    const Byte *data2 = data - (p->reps[i] + 1);
-+    if (data[0] != data2[0] || data[1] != data2[1])
-+      continue;
-+    limit = mainLen - 1;
-+    for (len = 2; len < limit && data[len] == data2[len]; len++);
-+    if (len >= limit)
-+      return 1;
-+  }
-+  *backRes = mainDist + LZMA_NUM_REPS;
-+  MovePos(p, mainLen - 2);
-+  return mainLen;
-+}
-+
-+static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
-+{
-+  UInt32 len;
-+  RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
-+  RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
-+  p->state = kMatchNextStates[p->state];
-+  len = LZMA_MATCH_LEN_MIN;
-+  LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+  RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
-+  RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
-+  RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
-+}
-+
-+static SRes CheckErrors(CLzmaEnc *p)
-+{
-+  if (p->result != SZ_OK)
-+    return p->result;
-+  if (p->rc.res != SZ_OK)
-+    p->result = SZ_ERROR_WRITE;
-+  if (p->matchFinderBase.result != SZ_OK)
-+    p->result = SZ_ERROR_READ;
-+  if (p->result != SZ_OK)
-+    p->finished = True;
-+  return p->result;
-+}
-+
-+static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
-+{
-+  /* ReleaseMFStream(); */
-+  p->finished = True;
-+  if (p->writeEndMark)
-+    WriteEndMarker(p, nowPos & p->pbMask);
-+  RangeEnc_FlushData(&p->rc);
-+  RangeEnc_FlushStream(&p->rc);
-+  return CheckErrors(p);
-+}
-+
-+static void FillAlignPrices(CLzmaEnc *p)
-+{
-+  UInt32 i;
-+  for (i = 0; i < kAlignTableSize; i++)
-+    p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
-+  p->alignPriceCount = 0;
-+}
-+
-+static void FillDistancesPrices(CLzmaEnc *p)
-+{
-+  UInt32 tempPrices[kNumFullDistances];
-+  UInt32 i, lenToPosState;
-+  for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
-+  {
-+    UInt32 posSlot = GetPosSlot1(i);
-+    UInt32 footerBits = ((posSlot >> 1) - 1);
-+    UInt32 base = ((2 | (posSlot & 1)) << footerBits);
-+    tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
-+  }
-+
-+  for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
-+  {
-+    UInt32 posSlot;
-+    const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
-+    UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
-+    for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
-+      posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
-+    for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
-+      posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
-+
-+    {
-+      UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
-+      UInt32 i;
-+      for (i = 0; i < kStartPosModelIndex; i++)
-+        distancesPrices[i] = posSlotPrices[i];
-+      for (; i < kNumFullDistances; i++)
-+        distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
-+    }
-+  }
-+  p->matchPriceCount = 0;
-+}
-+
-+void LzmaEnc_Construct(CLzmaEnc *p)
-+{
-+  RangeEnc_Construct(&p->rc);
-+  MatchFinder_Construct(&p->matchFinderBase);
-+  #ifndef _7ZIP_ST
-+  MatchFinderMt_Construct(&p->matchFinderMt);
-+  p->matchFinderMt.MatchFinder = &p->matchFinderBase;
-+  #endif
-+
-+  {
-+    CLzmaEncProps props;
-+    LzmaEncProps_Init(&props);
-+    LzmaEnc_SetProps(p, &props);
-+  }
-+
-+  #ifndef LZMA_LOG_BSR
-+  LzmaEnc_FastPosInit(p->g_FastPos);
-+  #endif
-+
-+  LzmaEnc_InitPriceTables(p->ProbPrices);
-+  p->litProbs = 0;
-+  p->saveState.litProbs = 0;
-+}
-+
-+CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
-+{
-+  void *p;
-+  p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
-+  if (p != 0)
-+    LzmaEnc_Construct((CLzmaEnc *)p);
-+  return p;
-+}
-+
-+void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
-+{
-+  alloc->Free(alloc, p->litProbs);
-+  alloc->Free(alloc, p->saveState.litProbs);
-+  p->litProbs = 0;
-+  p->saveState.litProbs = 0;
-+}
-+
-+void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  #ifndef _7ZIP_ST
-+  MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
-+  #endif
-+  MatchFinder_Free(&p->matchFinderBase, allocBig);
-+  LzmaEnc_FreeLits(p, alloc);
-+  RangeEnc_Free(&p->rc, alloc);
-+}
-+
-+void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
-+  alloc->Free(alloc, p);
-+}
-+
-+static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
-+{
-+  UInt32 nowPos32, startPos32;
-+  if (p->needInit)
-+  {
-+    p->matchFinder.Init(p->matchFinderObj);
-+    p->needInit = 0;
-+  }
-+
-+  if (p->finished)
-+    return p->result;
-+  RINOK(CheckErrors(p));
-+
-+  nowPos32 = (UInt32)p->nowPos64;
-+  startPos32 = nowPos32;
-+
-+  if (p->nowPos64 == 0)
-+  {
-+    UInt32 numPairs;
-+    Byte curByte;
-+    if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
-+      return Flush(p, nowPos32);
-+    ReadMatchDistances(p, &numPairs);
-+    RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
-+    p->state = kLiteralNextStates[p->state];
-+    curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
-+    LitEnc_Encode(&p->rc, p->litProbs, curByte);
-+    p->additionalOffset--;
-+    nowPos32++;
-+  }
-+
-+  if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
-+  for (;;)
-+  {
-+    UInt32 pos, len, posState;
-+
-+    if (p->fastMode)
-+      len = GetOptimumFast(p, &pos);
-+    else
-+      len = GetOptimum(p, nowPos32, &pos);
-+
-+    #ifdef SHOW_STAT2
-+    printf("\n pos = %4X,   len = %d   pos = %d", nowPos32, len, pos);
-+    #endif
-+
-+    posState = nowPos32 & p->pbMask;
-+    if (len == 1 && pos == (UInt32)-1)
-+    {
-+      Byte curByte;
-+      CLzmaProb *probs;
-+      const Byte *data;
-+
-+      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
-+      data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-+      curByte = *data;
-+      probs = LIT_PROBS(nowPos32, *(data - 1));
-+      if (IsCharState(p->state))
-+        LitEnc_Encode(&p->rc, probs, curByte);
-+      else
-+        LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
-+      p->state = kLiteralNextStates[p->state];
-+    }
-+    else
-+    {
-+      RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
-+      if (pos < LZMA_NUM_REPS)
-+      {
-+        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
-+        if (pos == 0)
-+        {
-+          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
-+          RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
-+        }
-+        else
-+        {
-+          UInt32 distance = p->reps[pos];
-+          RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
-+          if (pos == 1)
-+            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
-+          else
-+          {
-+            RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
-+            RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
-+            if (pos == 3)
-+              p->reps[3] = p->reps[2];
-+            p->reps[2] = p->reps[1];
-+          }
-+          p->reps[1] = p->reps[0];
-+          p->reps[0] = distance;
-+        }
-+        if (len == 1)
-+          p->state = kShortRepNextStates[p->state];
-+        else
-+        {
-+          LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+          p->state = kRepNextStates[p->state];
-+        }
-+      }
-+      else
-+      {
-+        UInt32 posSlot;
-+        RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
-+        p->state = kMatchNextStates[p->state];
-+        LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
-+        pos -= LZMA_NUM_REPS;
-+        GetPosSlot(pos, posSlot);
-+        RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
-+        
-+        if (posSlot >= kStartPosModelIndex)
-+        {
-+          UInt32 footerBits = ((posSlot >> 1) - 1);
-+          UInt32 base = ((2 | (posSlot & 1)) << footerBits);
-+          UInt32 posReduced = pos - base;
-+
-+          if (posSlot < kEndPosModelIndex)
-+            RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
-+          else
-+          {
-+            RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
-+            RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
-+            p->alignPriceCount++;
-+          }
-+        }
-+        p->reps[3] = p->reps[2];
-+        p->reps[2] = p->reps[1];
-+        p->reps[1] = p->reps[0];
-+        p->reps[0] = pos;
-+        p->matchPriceCount++;
-+      }
-+    }
-+    p->additionalOffset -= len;
-+    nowPos32 += len;
-+    if (p->additionalOffset == 0)
-+    {
-+      UInt32 processed;
-+      if (!p->fastMode)
-+      {
-+        if (p->matchPriceCount >= (1 << 7))
-+          FillDistancesPrices(p);
-+        if (p->alignPriceCount >= kAlignTableSize)
-+          FillAlignPrices(p);
-+      }
-+      if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
-+        break;
-+      processed = nowPos32 - startPos32;
-+      if (useLimits)
-+      {
-+        if (processed + kNumOpts + 300 >= maxUnpackSize ||
-+            RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
-+          break;
-+      }
-+      else if (processed >= (1 << 15))
-+      {
-+        p->nowPos64 += nowPos32 - startPos32;
-+        return CheckErrors(p);
-+      }
-+    }
-+  }
-+  p->nowPos64 += nowPos32 - startPos32;
-+  return Flush(p, nowPos32);
-+}
-+
-+#define kBigHashDicLimit ((UInt32)1 << 24)
-+
-+static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  UInt32 beforeSize = kNumOpts;
-+  Bool btMode;
-+  if (!RangeEnc_Alloc(&p->rc, alloc))
-+    return SZ_ERROR_MEM;
-+  btMode = (p->matchFinderBase.btMode != 0);
-+  #ifndef _7ZIP_ST
-+  p->mtMode = (p->multiThread && !p->fastMode && btMode);
-+  #endif
-+
-+  {
-+    unsigned lclp = p->lc + p->lp;
-+    if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
-+    {
-+      LzmaEnc_FreeLits(p, alloc);
-+      p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
-+      p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
-+      if (p->litProbs == 0 || p->saveState.litProbs == 0)
-+      {
-+        LzmaEnc_FreeLits(p, alloc);
-+        return SZ_ERROR_MEM;
-+      }
-+      p->lclp = lclp;
-+    }
-+  }
-+
-+  p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
-+
-+  if (beforeSize + p->dictSize < keepWindowSize)
-+    beforeSize = keepWindowSize - p->dictSize;
-+
-+  #ifndef _7ZIP_ST
-+  if (p->mtMode)
-+  {
-+    RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
-+    p->matchFinderObj = &p->matchFinderMt;
-+    MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
-+  }
-+  else
-+  #endif
-+  {
-+    if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
-+      return SZ_ERROR_MEM;
-+    p->matchFinderObj = &p->matchFinderBase;
-+    MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
-+  }
-+  return SZ_OK;
-+}
-+
-+void LzmaEnc_Init(CLzmaEnc *p)
-+{
-+  UInt32 i;
-+  p->state = 0;
-+  for (i = 0 ; i < LZMA_NUM_REPS; i++)
-+    p->reps[i] = 0;
-+
-+  RangeEnc_Init(&p->rc);
-+
-+
-+  for (i = 0; i < kNumStates; i++)
-+  {
-+    UInt32 j;
-+    for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
-+    {
-+      p->isMatch[i][j] = kProbInitValue;
-+      p->isRep0Long[i][j] = kProbInitValue;
-+    }
-+    p->isRep[i] = kProbInitValue;
-+    p->isRepG0[i] = kProbInitValue;
-+    p->isRepG1[i] = kProbInitValue;
-+    p->isRepG2[i] = kProbInitValue;
-+  }
-+
-+  {
-+    UInt32 num = 0x300 << (p->lp + p->lc);
-+    for (i = 0; i < num; i++)
-+      p->litProbs[i] = kProbInitValue;
-+  }
-+
-+  {
-+    for (i = 0; i < kNumLenToPosStates; i++)
-+    {
-+      CLzmaProb *probs = p->posSlotEncoder[i];
-+      UInt32 j;
-+      for (j = 0; j < (1 << kNumPosSlotBits); j++)
-+        probs[j] = kProbInitValue;
-+    }
-+  }
-+  {
-+    for (i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
-+      p->posEncoders[i] = kProbInitValue;
-+  }
-+
-+  LenEnc_Init(&p->lenEnc.p);
-+  LenEnc_Init(&p->repLenEnc.p);
-+
-+  for (i = 0; i < (1 << kNumAlignBits); i++)
-+    p->posAlignEncoder[i] = kProbInitValue;
-+
-+  p->optimumEndIndex = 0;
-+  p->optimumCurrentIndex = 0;
-+  p->additionalOffset = 0;
-+
-+  p->pbMask = (1 << p->pb) - 1;
-+  p->lpMask = (1 << p->lp) - 1;
-+}
-+
-+void LzmaEnc_InitPrices(CLzmaEnc *p)
-+{
-+  if (!p->fastMode)
-+  {
-+    FillDistancesPrices(p);
-+    FillAlignPrices(p);
-+  }
-+
-+  p->lenEnc.tableSize =
-+  p->repLenEnc.tableSize =
-+      p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
-+  LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
-+  LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
-+}
-+
-+static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  UInt32 i;
-+  for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
-+    if (p->dictSize <= ((UInt32)1 << i))
-+      break;
-+  p->distTableSize = i * 2;
-+
-+  p->finished = False;
-+  p->result = SZ_OK;
-+  RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
-+  LzmaEnc_Init(p);
-+  LzmaEnc_InitPrices(p);
-+  p->nowPos64 = 0;
-+  return SZ_OK;
-+}
-+
-+static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream,
-+    ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+  p->matchFinderBase.stream = inStream;
-+  p->needInit = 1;
-+  p->rc.outStream = outStream;
-+  return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
-+}
-+
-+SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
-+    ISeqInStream *inStream, UInt32 keepWindowSize,
-+    ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+  p->matchFinderBase.stream = inStream;
-+  p->needInit = 1;
-+  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-+}
-+
-+static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
-+{
-+  p->matchFinderBase.directInput = 1;
-+  p->matchFinderBase.bufferBase = (Byte *)src;
-+  p->matchFinderBase.directInputRem = srcLen;
-+}
-+
-+SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
-+    UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+  LzmaEnc_SetInputBuf(p, src, srcLen);
-+  p->needInit = 1;
-+
-+  return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
-+}
-+
-+void LzmaEnc_Finish(CLzmaEncHandle pp)
-+{
-+  #ifndef _7ZIP_ST
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+  if (p->mtMode)
-+    MatchFinderMt_ReleaseStream(&p->matchFinderMt);
-+  #else
-+  pp = pp;
-+  #endif
-+}
-+
-+typedef struct
-+{
-+  ISeqOutStream funcTable;
-+  Byte *data;
-+  SizeT rem;
-+  Bool overflow;
-+} CSeqOutStreamBuf;
-+
-+static size_t MyWrite(void *pp, const void *data, size_t size)
-+{
-+  CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
-+  if (p->rem < size)
-+  {
-+    size = p->rem;
-+    p->overflow = True;
-+  }
-+  memcpy(p->data, data, size);
-+  p->rem -= size;
-+  p->data += size;
-+  return size;
-+}
-+
-+
-+UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
-+{
-+  const CLzmaEnc *p = (CLzmaEnc *)pp;
-+  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-+}
-+
-+const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
-+{
-+  const CLzmaEnc *p = (CLzmaEnc *)pp;
-+  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-+}
-+
-+SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
-+    Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
-+{
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+  UInt64 nowPos64;
-+  SRes res;
-+  CSeqOutStreamBuf outStream;
-+
-+  outStream.funcTable.Write = MyWrite;
-+  outStream.data = dest;
-+  outStream.rem = *destLen;
-+  outStream.overflow = False;
-+
-+  p->writeEndMark = False;
-+  p->finished = False;
-+  p->result = SZ_OK;
-+
-+  if (reInit)
-+    LzmaEnc_Init(p);
-+  LzmaEnc_InitPrices(p);
-+  nowPos64 = p->nowPos64;
-+  RangeEnc_Init(&p->rc);
-+  p->rc.outStream = &outStream.funcTable;
-+
-+  res = LzmaEnc_CodeOneBlock(p, True, desiredPackSize, *unpackSize);
-+  
-+  *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
-+  *destLen -= outStream.rem;
-+  if (outStream.overflow)
-+    return SZ_ERROR_OUTPUT_EOF;
-+
-+  return res;
-+}
-+
-+static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress)
-+{
-+  SRes res = SZ_OK;
-+
-+  #ifndef _7ZIP_ST
-+  Byte allocaDummy[0x300];
-+  int i = 0;
-+  for (i = 0; i < 16; i++)
-+    allocaDummy[i] = (Byte)i;
-+  #endif
-+
-+  for (;;)
-+  {
-+    res = LzmaEnc_CodeOneBlock(p, False, 0, 0);
-+    if (res != SZ_OK || p->finished != 0)
-+      break;
-+    if (progress != 0)
-+    {
-+      res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
-+      if (res != SZ_OK)
-+      {
-+        res = SZ_ERROR_PROGRESS;
-+        break;
-+      }
-+    }
-+  }
-+  LzmaEnc_Finish(p);
-+  return res;
-+}
-+
-+SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
-+    ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  RINOK(LzmaEnc_Prepare(pp, outStream, inStream, alloc, allocBig));
-+  return LzmaEnc_Encode2((CLzmaEnc *)pp, progress);
-+}
-+
-+SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
-+{
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+  int i;
-+  UInt32 dictSize = p->dictSize;
-+  if (*size < LZMA_PROPS_SIZE)
-+    return SZ_ERROR_PARAM;
-+  *size = LZMA_PROPS_SIZE;
-+  props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
-+
-+  for (i = 11; i <= 30; i++)
-+  {
-+    if (dictSize <= ((UInt32)2 << i))
-+    {
-+      dictSize = (2 << i);
-+      break;
-+    }
-+    if (dictSize <= ((UInt32)3 << i))
-+    {
-+      dictSize = (3 << i);
-+      break;
-+    }
-+  }
-+
-+  for (i = 0; i < 4; i++)
-+    props[1 + i] = (Byte)(dictSize >> (8 * i));
-+  return SZ_OK;
-+}
-+
-+SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+    int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  SRes res;
-+  CLzmaEnc *p = (CLzmaEnc *)pp;
-+
-+  CSeqOutStreamBuf outStream;
-+
-+  LzmaEnc_SetInputBuf(p, src, srcLen);
-+
-+  outStream.funcTable.Write = MyWrite;
-+  outStream.data = dest;
-+  outStream.rem = *destLen;
-+  outStream.overflow = False;
-+
-+  p->writeEndMark = writeEndMark;
-+
-+  p->rc.outStream = &outStream.funcTable;
-+  res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig);
-+  if (res == SZ_OK)
-+    res = LzmaEnc_Encode2(p, progress);
-+
-+  *destLen -= outStream.rem;
-+  if (outStream.overflow)
-+    return SZ_ERROR_OUTPUT_EOF;
-+  return res;
-+}
-+
-+SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-+    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
-+{
-+  CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
-+  SRes res;
-+  if (p == 0)
-+    return SZ_ERROR_MEM;
-+
-+  res = LzmaEnc_SetProps(p, props);
-+  if (res == SZ_OK)
-+  {
-+    res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
-+    if (res == SZ_OK)
-+      res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
-+          writeEndMark, progress, alloc, allocBig);
-+  }
-+
-+  LzmaEnc_Destroy(p, alloc, allocBig);
-+  return res;
-+}
---- /dev/null
-+++ b/lib/lzma/Makefile
-@@ -0,0 +1,7 @@
-+lzma_compress-objs := LzFind.o LzmaEnc.o
-+lzma_decompress-objs := LzmaDec.o
-+
-+obj-$(CONFIG_LZMA_COMPRESS) += lzma_compress.o
-+obj-$(CONFIG_LZMA_DECOMPRESS) += lzma_decompress.o
-+
-+EXTRA_CFLAGS += -Iinclude/linux -Iinclude/linux/lzma -include types.h
diff --git a/target/linux/generic/patches-2.6.38/511-debloat_lzma.patch b/target/linux/generic/patches-2.6.38/511-debloat_lzma.patch
deleted file mode 100644
index 1e41661ebb..0000000000
--- a/target/linux/generic/patches-2.6.38/511-debloat_lzma.patch
+++ /dev/null
@@ -1,485 +0,0 @@
---- a/include/linux/lzma/LzmaDec.h
-+++ b/include/linux/lzma/LzmaDec.h
-@@ -31,14 +31,6 @@ typedef struct _CLzmaProps
-   UInt32 dicSize;
- } CLzmaProps;
- 
--/* LzmaProps_Decode - decodes properties
--Returns:
--  SZ_OK
--  SZ_ERROR_UNSUPPORTED - Unsupported properties
--*/
--
--SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
--
- 
- /* ---------- LZMA Decoder state ---------- */
- 
-@@ -70,8 +62,6 @@ typedef struct
- 
- #define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
- 
--void LzmaDec_Init(CLzmaDec *p);
--
- /* There are two types of LZMA streams:
-      0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
-      1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
-@@ -108,97 +98,6 @@ typedef enum
- 
- /* ELzmaStatus is used only as output value for function call */
- 
--
--/* ---------- Interfaces ---------- */
--
--/* There are 3 levels of interfaces:
--     1) Dictionary Interface
--     2) Buffer Interface
--     3) One Call Interface
--   You can select any of these interfaces, but don't mix functions from different
--   groups for same object. */
--
--
--/* There are two variants to allocate state for Dictionary Interface:
--     1) LzmaDec_Allocate / LzmaDec_Free
--     2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
--   You can use variant 2, if you set dictionary buffer manually.
--   For Buffer Interface you must always use variant 1.
--
--LzmaDec_Allocate* can return:
--  SZ_OK
--  SZ_ERROR_MEM         - Memory allocation error
--  SZ_ERROR_UNSUPPORTED - Unsupported properties
--*/
--   
--SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
--void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
--
--SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
--void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
--
--/* ---------- Dictionary Interface ---------- */
--
--/* You can use it, if you want to eliminate the overhead for data copying from
--   dictionary to some other external buffer.
--   You must work with CLzmaDec variables directly in this interface.
--
--   STEPS:
--     LzmaDec_Constr()
--     LzmaDec_Allocate()
--     for (each new stream)
--     {
--       LzmaDec_Init()
--       while (it needs more decompression)
--       {
--         LzmaDec_DecodeToDic()
--         use data from CLzmaDec::dic and update CLzmaDec::dicPos
--       }
--     }
--     LzmaDec_Free()
--*/
--
--/* LzmaDec_DecodeToDic
--   
--   The decoding to internal dictionary buffer (CLzmaDec::dic).
--   You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
--
--finishMode:
--  It has meaning only if the decoding reaches output limit (dicLimit).
--  LZMA_FINISH_ANY - Decode just dicLimit bytes.
--  LZMA_FINISH_END - Stream must be finished after dicLimit.
--
--Returns:
--  SZ_OK
--    status:
--      LZMA_STATUS_FINISHED_WITH_MARK
--      LZMA_STATUS_NOT_FINISHED
--      LZMA_STATUS_NEEDS_MORE_INPUT
--      LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
--  SZ_ERROR_DATA - Data error
--*/
--
--SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
--    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
--
--
--/* ---------- Buffer Interface ---------- */
--
--/* It's zlib-like interface.
--   See LzmaDec_DecodeToDic description for information about STEPS and return results,
--   but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
--   to work with CLzmaDec variables manually.
--
--finishMode:
--  It has meaning only if the decoding reaches output limit (*destLen).
--  LZMA_FINISH_ANY - Decode just destLen bytes.
--  LZMA_FINISH_END - Stream must be finished after (*destLen).
--*/
--
--SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
--    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
--
--
- /* ---------- One Call Interface ---------- */
- 
- /* LzmaDecode
---- a/lib/lzma/LzmaDec.c
-+++ b/lib/lzma/LzmaDec.c
-@@ -682,7 +682,7 @@ static void LzmaDec_InitRc(CLzmaDec *p,
-   p->needFlush = 0;
- }
- 
--void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
-+static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
- {
-   p->needFlush = 1;
-   p->remainLen = 0;
-@@ -698,7 +698,7 @@ void LzmaDec_InitDicAndState(CLzmaDec *p
-     p->needInitState = 1;
- }
- 
--void LzmaDec_Init(CLzmaDec *p)
-+static void LzmaDec_Init(CLzmaDec *p)
- {
-   p->dicPos = 0;
-   LzmaDec_InitDicAndState(p, True, True);
-@@ -716,7 +716,7 @@ static void LzmaDec_InitStateReal(CLzmaD
-   p->needInitState = 0;
- }
- 
--SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
-+static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
-     ELzmaFinishMode finishMode, ELzmaStatus *status)
- {
-   SizeT inSize = *srcLen;
-@@ -837,7 +837,7 @@ SRes LzmaDec_DecodeToDic(CLzmaDec *p, Si
-   return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
- }
- 
--SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
-+static __maybe_unused SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
- {
-   SizeT outSize = *destLen;
-   SizeT inSize = *srcLen;
-@@ -877,7 +877,7 @@ SRes LzmaDec_DecodeToBuf(CLzmaDec *p, By
-   }
- }
- 
--void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
-+static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
- {
-   alloc->Free(alloc, p->probs);
-   p->probs = 0;
-@@ -889,13 +889,13 @@ static void LzmaDec_FreeDict(CLzmaDec *p
-   p->dic = 0;
- }
- 
--void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
-+static void __maybe_unused LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
- {
-   LzmaDec_FreeProbs(p, alloc);
-   LzmaDec_FreeDict(p, alloc);
- }
- 
--SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
-+static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
- {
-   UInt32 dicSize;
-   Byte d;
-@@ -935,7 +935,7 @@ static SRes LzmaDec_AllocateProbs2(CLzma
-   return SZ_OK;
- }
- 
--SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-+static SRes __maybe_unused LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
- {
-   CLzmaProps propNew;
-   RINOK(LzmaProps_Decode(&propNew, props, propsSize));
-@@ -944,7 +944,7 @@ SRes LzmaDec_AllocateProbs(CLzmaDec *p,
-   return SZ_OK;
- }
- 
--SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
-+static SRes __maybe_unused LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
- {
-   CLzmaProps propNew;
-   SizeT dicBufSize;
---- a/include/linux/lzma/LzmaEnc.h
-+++ b/include/linux/lzma/LzmaEnc.h
-@@ -31,9 +31,6 @@ typedef struct _CLzmaEncProps
- } CLzmaEncProps;
- 
- void LzmaEncProps_Init(CLzmaEncProps *p);
--void LzmaEncProps_Normalize(CLzmaEncProps *p);
--UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
--
- 
- /* ---------- CLzmaEncHandle Interface ---------- */
- 
-@@ -53,26 +50,9 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *
- void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
- SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
- SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
--SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
--    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
- SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-     int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
- 
--/* ---------- One Call Interface ---------- */
--
--/* LzmaEncode
--Return code:
--  SZ_OK               - OK
--  SZ_ERROR_MEM        - Memory allocation error
--  SZ_ERROR_PARAM      - Incorrect paramater
--  SZ_ERROR_OUTPUT_EOF - output buffer overflow
--  SZ_ERROR_THREAD     - errors in multithreading functions (only for Mt version)
--*/
--
--SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
--    const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
--    ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
--
- #ifdef __cplusplus
- }
- #endif
---- a/lib/lzma/LzmaEnc.c
-+++ b/lib/lzma/LzmaEnc.c
-@@ -53,7 +53,7 @@ void LzmaEncProps_Init(CLzmaEncProps *p)
-   p->writeEndMark = 0;
- }
- 
--void LzmaEncProps_Normalize(CLzmaEncProps *p)
-+static void LzmaEncProps_Normalize(CLzmaEncProps *p)
- {
-   int level = p->level;
-   if (level < 0) level = 5;
-@@ -76,7 +76,7 @@ void LzmaEncProps_Normalize(CLzmaEncProp
-       #endif
- }
- 
--UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
-+static UInt32 __maybe_unused LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
- {
-   CLzmaEncProps props = *props2;
-   LzmaEncProps_Normalize(&props);
-@@ -93,7 +93,7 @@ UInt32 LzmaEncProps_GetDictSize(const CL
- 
- #define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
- 
--UInt32 GetPosSlot1(UInt32 pos)
-+static UInt32 GetPosSlot1(UInt32 pos)
- {
-   UInt32 res;
-   BSR2_RET(pos, res);
-@@ -107,7 +107,7 @@ UInt32 GetPosSlot1(UInt32 pos)
- #define kNumLogBits (9 + (int)sizeof(size_t) / 2)
- #define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
- 
--void LzmaEnc_FastPosInit(Byte *g_FastPos)
-+static void LzmaEnc_FastPosInit(Byte *g_FastPos)
- {
-   int c = 2, slotFast;
-   g_FastPos[0] = 0;
-@@ -339,7 +339,7 @@ typedef struct
-   CSaveState saveState;
- } CLzmaEnc;
- 
--void LzmaEnc_SaveState(CLzmaEncHandle pp)
-+static void __maybe_unused LzmaEnc_SaveState(CLzmaEncHandle pp)
- {
-   CLzmaEnc *p = (CLzmaEnc *)pp;
-   CSaveState *dest = &p->saveState;
-@@ -365,7 +365,7 @@ void LzmaEnc_SaveState(CLzmaEncHandle pp
-   memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
- }
- 
--void LzmaEnc_RestoreState(CLzmaEncHandle pp)
-+static void __maybe_unused LzmaEnc_RestoreState(CLzmaEncHandle pp)
- {
-   CLzmaEnc *dest = (CLzmaEnc *)pp;
-   const CSaveState *p = &dest->saveState;
-@@ -600,7 +600,7 @@ static void LitEnc_EncodeMatched(CRangeE
-   while (symbol < 0x10000);
- }
- 
--void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
-+static void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
- {
-   UInt32 i;
-   for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
-@@ -1676,7 +1676,7 @@ static void FillDistancesPrices(CLzmaEnc
-   p->matchPriceCount = 0;
- }
- 
--void LzmaEnc_Construct(CLzmaEnc *p)
-+static void LzmaEnc_Construct(CLzmaEnc *p)
- {
-   RangeEnc_Construct(&p->rc);
-   MatchFinder_Construct(&p->matchFinderBase);
-@@ -1709,7 +1709,7 @@ CLzmaEncHandle LzmaEnc_Create(ISzAlloc *
-   return p;
- }
- 
--void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
-+static void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
- {
-   alloc->Free(alloc, p->litProbs);
-   alloc->Free(alloc, p->saveState.litProbs);
-@@ -2074,7 +2074,7 @@ SRes LzmaEnc_MemPrepare(CLzmaEncHandle p
-   return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
- }
- 
--void LzmaEnc_Finish(CLzmaEncHandle pp)
-+static void LzmaEnc_Finish(CLzmaEncHandle pp)
- {
-   #ifndef _7ZIP_ST
-   CLzmaEnc *p = (CLzmaEnc *)pp;
-@@ -2108,7 +2108,7 @@ static size_t MyWrite(void *pp, const vo
- }
- 
- 
--UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
-+static UInt32 __maybe_unused LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
- {
-   const CLzmaEnc *p = (CLzmaEnc *)pp;
-   return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-@@ -2120,7 +2120,7 @@ const Byte *LzmaEnc_GetCurBuf(CLzmaEncHa
-   return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
- }
- 
--SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
-+static SRes __maybe_unused LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
-     Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
- {
-   CLzmaEnc *p = (CLzmaEnc *)pp;
-@@ -2248,7 +2248,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp
-   return res;
- }
- 
--SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-+static __maybe_unused SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
-     const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
-     ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
- {
---- a/include/linux/lzma/LzFind.h
-+++ b/include/linux/lzma/LzFind.h
-@@ -55,11 +55,6 @@ typedef struct _CMatchFinder
- 
- #define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
- 
--int MatchFinder_NeedMove(CMatchFinder *p);
--Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
--void MatchFinder_MoveBlock(CMatchFinder *p);
--void MatchFinder_ReadIfRequired(CMatchFinder *p);
--
- void MatchFinder_Construct(CMatchFinder *p);
- 
- /* Conditions:
-@@ -70,12 +65,6 @@ int MatchFinder_Create(CMatchFinder *p,
-     UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
-     ISzAlloc *alloc);
- void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
--void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
--void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
--
--UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
--    UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
--    UInt32 *distances, UInt32 maxLen);
- 
- /*
- Conditions:
-@@ -102,12 +91,6 @@ typedef struct _IMatchFinder
- 
- void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
- 
--void MatchFinder_Init(CMatchFinder *p);
--UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
--UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
--void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
--void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
--
- #ifdef __cplusplus
- }
- #endif
---- a/lib/lzma/LzFind.c
-+++ b/lib/lzma/LzFind.c
-@@ -42,12 +42,12 @@ static int LzInWindow_Create(CMatchFinde
-   return (p->bufferBase != 0);
- }
- 
--Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
--Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
-+static Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
-+static Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
- 
--UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
-+static UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
- 
--void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
-+static void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
- {
-   p->posLimit -= subValue;
-   p->pos -= subValue;
-@@ -268,7 +268,7 @@ static void MatchFinder_SetLimits(CMatch
-   p->posLimit = p->pos + limit;
- }
- 
--void MatchFinder_Init(CMatchFinder *p)
-+static void MatchFinder_Init(CMatchFinder *p)
- {
-   UInt32 i;
-   for (i = 0; i < p->hashSizeSum; i++)
-@@ -287,7 +287,7 @@ static UInt32 MatchFinder_GetSubValue(CM
-   return (p->pos - p->historySize - 1) & kNormalizeMask;
- }
- 
--void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
-+static void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
- {
-   UInt32 i;
-   for (i = 0; i < numItems; i++)
-@@ -350,7 +350,7 @@ static UInt32 * Hc_GetMatchesSpec(UInt32
-   }
- }
- 
--UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-+static UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
-     UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
-     UInt32 *distances, UInt32 maxLen)
- {
-@@ -492,7 +492,7 @@ static UInt32 Bt2_MatchFinder_GetMatches
-   GET_MATCHES_FOOTER(offset, 1)
- }
- 
--UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+static __maybe_unused UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
- {
-   UInt32 offset;
-   GET_MATCHES_HEADER(3)
-@@ -632,7 +632,7 @@ static UInt32 Hc4_MatchFinder_GetMatches
-   MOVE_POS_RET
- }
- 
--UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
-+static __maybe_unused UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
- {
-   UInt32 offset;
-   GET_MATCHES_HEADER(3)
-@@ -657,7 +657,7 @@ static void Bt2_MatchFinder_Skip(CMatchF
-   while (--num != 0);
- }
- 
--void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+static __maybe_unused void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
- {
-   do
-   {
-@@ -718,7 +718,7 @@ static void Hc4_MatchFinder_Skip(CMatchF
-   while (--num != 0);
- }
- 
--void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
-+static __maybe_unused void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
- {
-   do
-   {
diff --git a/target/linux/generic/patches-2.6.38/512-jffs2_eofdetect.patch b/target/linux/generic/patches-2.6.38/512-jffs2_eofdetect.patch
deleted file mode 100644
index eaf9489d35..0000000000
--- a/target/linux/generic/patches-2.6.38/512-jffs2_eofdetect.patch
+++ /dev/null
@@ -1,132 +0,0 @@
---- a/fs/jffs2/build.c
-+++ b/fs/jffs2/build.c
-@@ -112,6 +112,17 @@ static int jffs2_build_filesystem(struct
- 	dbg_fsbuild("scanned flash completely\n");
- 	jffs2_dbg_dump_block_lists_nolock(c);
- 
-+	if (c->flags & (1 << 7)) {
-+		printk("%s(): unlocking the mtd device... ", __func__);
-+		if (c->mtd->unlock)
-+			c->mtd->unlock(c->mtd, 0, c->mtd->size);
-+		printk("done.\n");
-+
-+		printk("%s(): erasing all blocks after the end marker... ", __func__);
-+		jffs2_erase_pending_blocks(c, -1);
-+		printk("done.\n");
-+	}
-+
- 	dbg_fsbuild("pass 1 starting\n");
- 	c->flags |= JFFS2_SB_FLAG_BUILDING;
- 	/* Now scan the directory tree, increasing nlink according to every dirent found. */
---- a/fs/jffs2/scan.c
-+++ b/fs/jffs2/scan.c
-@@ -72,7 +72,7 @@ static int file_dirty(struct jffs2_sb_in
- 		return ret;
- 	if ((ret = jffs2_scan_dirty_space(c, jeb, jeb->free_size)))
- 		return ret;
--	/* Turned wasted size into dirty, since we apparently 
-+	/* Turned wasted size into dirty, since we apparently
- 	   think it's recoverable now. */
- 	jeb->dirty_size += jeb->wasted_size;
- 	c->dirty_size += jeb->wasted_size;
-@@ -144,8 +144,11 @@ int jffs2_scan_medium(struct jffs2_sb_in
- 		/* reset summary info for next eraseblock scan */
- 		jffs2_sum_reset_collected(s);
- 
--		ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
--						buf_size, s);
-+		if (c->flags & (1 << 7))
-+			ret = BLK_STATE_ALLFF;
-+		else
-+			ret = jffs2_scan_eraseblock(c, jeb, buf_size?flashbuf:(flashbuf+jeb->offset),
-+							buf_size, s);
- 
- 		if (ret < 0)
- 			goto out;
-@@ -402,7 +405,7 @@ static int jffs2_scan_xref_node(struct j
- 	if (!ref)
- 		return -ENOMEM;
- 
--	/* BEFORE jffs2_build_xattr_subsystem() called, 
-+	/* BEFORE jffs2_build_xattr_subsystem() called,
- 	 * and AFTER xattr_ref is marked as a dead xref,
- 	 * ref->xid is used to store 32bit xid, xd is not used
- 	 * ref->ino is used to store 32bit inode-number, ic is not used
-@@ -475,7 +478,7 @@ static int jffs2_scan_eraseblock (struct
- 		struct jffs2_sum_marker *sm;
- 		void *sumptr = NULL;
- 		uint32_t sumlen;
--	      
-+
- 		if (!buf_size) {
- 			/* XIP case. Just look, point at the summary if it's there */
- 			sm = (void *)buf + c->sector_size - sizeof(*sm);
-@@ -491,9 +494,9 @@ static int jffs2_scan_eraseblock (struct
- 				buf_len = sizeof(*sm);
- 
- 			/* Read as much as we want into the _end_ of the preallocated buffer */
--			err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len, 
-+			err = jffs2_fill_scan_buf(c, buf + buf_size - buf_len,
- 						  jeb->offset + c->sector_size - buf_len,
--						  buf_len);				
-+						  buf_len);
- 			if (err)
- 				return err;
- 
-@@ -512,9 +515,9 @@ static int jffs2_scan_eraseblock (struct
- 				}
- 				if (buf_len < sumlen) {
- 					/* Need to read more so that the entire summary node is present */
--					err = jffs2_fill_scan_buf(c, sumptr, 
-+					err = jffs2_fill_scan_buf(c, sumptr,
- 								  jeb->offset + c->sector_size - sumlen,
--								  sumlen - buf_len);				
-+								  sumlen - buf_len);
- 					if (err)
- 						return err;
- 				}
-@@ -527,7 +530,7 @@ static int jffs2_scan_eraseblock (struct
- 
- 			if (buf_size && sumlen > buf_size)
- 				kfree(sumptr);
--			/* If it returns with a real error, bail. 
-+			/* If it returns with a real error, bail.
- 			   If it returns positive, that's a block classification
- 			   (i.e. BLK_STATE_xxx) so return that too.
- 			   If it returns zero, fall through to full scan. */
-@@ -548,6 +551,17 @@ static int jffs2_scan_eraseblock (struct
- 			return err;
- 	}
- 
-+	if ((buf[0] == 0xde) &&
-+		(buf[1] == 0xad) &&
-+		(buf[2] == 0xc0) &&
-+		(buf[3] == 0xde)) {
-+		/* end of filesystem. erase everything after this point */
-+		printk("%s(): End of filesystem marker found at 0x%x\n", __func__, jeb->offset);
-+		c->flags |= (1 << 7);
-+
-+		return BLK_STATE_ALLFF;
-+	}
-+
- 	/* We temporarily use 'ofs' as a pointer into the buffer/jeb */
- 	ofs = 0;
- 	max_ofs = EMPTY_SCAN_SIZE(c->sector_size);
-@@ -673,7 +687,7 @@ scan_more:
- 				scan_end = buf_len;
- 				goto more_empty;
- 			}
--			
-+
- 			/* See how much more there is to read in this eraseblock... */
- 			buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs);
- 			if (!buf_len) {
-@@ -909,7 +923,7 @@ scan_more:
- 
- 	D1(printk(KERN_DEBUG "Block at 0x%08x: free 0x%08x, dirty 0x%08x, unchecked 0x%08x, used 0x%08x, wasted 0x%08x\n",
- 		  jeb->offset,jeb->free_size, jeb->dirty_size, jeb->unchecked_size, jeb->used_size, jeb->wasted_size));
--	
-+
- 	/* mark_node_obsolete can add to wasted !! */
- 	if (jeb->wasted_size) {
- 		jeb->dirty_size += jeb->wasted_size;
diff --git a/target/linux/generic/patches-2.6.38/600-netfilter_layer7_2.22.patch b/target/linux/generic/patches-2.6.38/600-netfilter_layer7_2.22.patch
deleted file mode 100644
index a32169d49f..0000000000
--- a/target/linux/generic/patches-2.6.38/600-netfilter_layer7_2.22.patch
+++ /dev/null
@@ -1,2142 +0,0 @@
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -946,6 +946,27 @@ config NETFILTER_XT_MATCH_STATE
- 
- 	  To compile it as a module, choose M here.  If unsure, say N.
- 
-+config NETFILTER_XT_MATCH_LAYER7
-+	tristate '"layer7" match support'
-+	depends on NETFILTER_XTABLES
-+	depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK)
-+       depends on NETFILTER_ADVANCED
-+	help
-+	  Say Y if you want to be able to classify connections (and their
-+	  packets) based on regular expression matching of their application
-+	  layer data.   This is one way to classify applications such as
-+	  peer-to-peer filesharing systems that do not always use the same
-+	  port.
-+
-+	  To compile it as a module, choose M here.  If unsure, say N.
-+
-+config NETFILTER_XT_MATCH_LAYER7_DEBUG
-+        bool 'Layer 7 debugging output'
-+        depends on NETFILTER_XT_MATCH_LAYER7
-+        help
-+          Say Y to get lots of debugging output.
-+
-+
- config NETFILTER_XT_MATCH_STATISTIC
- 	tristate '"statistic" match support'
- 	depends on NETFILTER_ADVANCED
---- a/net/netfilter/Makefile
-+++ b/net/netfilter/Makefile
-@@ -95,6 +95,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT)
- obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
-+obj-$(CONFIG_NETFILTER_XT_MATCH_LAYER7) += xt_layer7.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
- obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
---- /dev/null
-+++ b/net/netfilter/xt_layer7.c
-@@ -0,0 +1,666 @@
-+/*
-+  Kernel module to match application layer (OSI layer 7) data in connections.
-+
-+  http://l7-filter.sf.net
-+
-+  (C) 2003-2009 Matthew Strait and Ethan Sommer.
-+
-+  This program is free software; you can redistribute it and/or
-+  modify it under the terms of the GNU General Public License
-+  as published by the Free Software Foundation; either version
-+  2 of the License, or (at your option) any later version.
-+  http://www.gnu.org/licenses/gpl.txt
-+
-+  Based on ipt_string.c (C) 2000 Emmanuel Roger <winfield@freegates.be>,
-+  xt_helper.c (C) 2002 Harald Welte and cls_layer7.c (C) 2003 Matthew Strait,
-+  Ethan Sommer, Justin Levandoski.
-+*/
-+
-+#include <linux/spinlock.h>
-+#include <linux/version.h>
-+#include <net/ip.h>
-+#include <net/tcp.h>
-+#include <linux/module.h>
-+#include <linux/skbuff.h>
-+#include <linux/netfilter.h>
-+#include <net/netfilter/nf_conntrack.h>
-+#include <net/netfilter/nf_conntrack_core.h>
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
-+#include <net/netfilter/nf_conntrack_extend.h>
-+#include <net/netfilter/nf_conntrack_acct.h>
-+#endif
-+#include <linux/netfilter/x_tables.h>
-+#include <linux/netfilter/xt_layer7.h>
-+#include <linux/ctype.h>
-+#include <linux/proc_fs.h>
-+
-+#include "regexp/regexp.c"
-+
-+MODULE_LICENSE("GPL");
-+MODULE_AUTHOR("Matthew Strait <quadong@users.sf.net>, Ethan Sommer <sommere@users.sf.net>");
-+MODULE_DESCRIPTION("iptables application layer match module");
-+MODULE_ALIAS("ipt_layer7");
-+MODULE_VERSION("2.21");
-+
-+static int maxdatalen = 2048; // this is the default
-+module_param(maxdatalen, int, 0444);
-+MODULE_PARM_DESC(maxdatalen, "maximum bytes of data looked at by l7-filter");
-+#ifdef CONFIG_NETFILTER_XT_MATCH_LAYER7_DEBUG
-+	#define DPRINTK(format,args...) printk(format,##args)
-+#else
-+	#define DPRINTK(format,args...)
-+#endif
-+
-+/* Number of packets whose data we look at.
-+This can be modified through /proc/net/layer7_numpackets */
-+static int num_packets = 10;
-+
-+static struct pattern_cache {
-+	char * regex_string;
-+	regexp * pattern;
-+	struct pattern_cache * next;
-+} * first_pattern_cache = NULL;
-+
-+DEFINE_SPINLOCK(l7_lock);
-+
-+static int total_acct_packets(struct nf_conn *ct)
-+{
-+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 26)
-+	BUG_ON(ct == NULL);
-+	return (ct->counters[IP_CT_DIR_ORIGINAL].packets + ct->counters[IP_CT_DIR_REPLY].packets);
-+#else
-+	struct nf_conn_counter *acct;
-+
-+	BUG_ON(ct == NULL);
-+	acct = nf_conn_acct_find(ct);
-+	if (!acct)
-+		return 0;
-+	return (acct[IP_CT_DIR_ORIGINAL].packets + acct[IP_CT_DIR_REPLY].packets);
-+#endif
-+}
-+
-+#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
-+/* Converts an unfriendly string into a friendly one by
-+replacing unprintables with periods and all whitespace with " ". */
-+static char * friendly_print(unsigned char * s)
-+{
-+	char * f = kmalloc(strlen(s) + 1, GFP_ATOMIC);
-+	int i;
-+
-+	if(!f) {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory in "
-+					"friendly_print, bailing.\n");
-+		return NULL;
-+	}
-+
-+	for(i = 0; i < strlen(s); i++){
-+		if(isprint(s[i]) && s[i] < 128)	f[i] = s[i];
-+		else if(isspace(s[i]))		f[i] = ' ';
-+		else 				f[i] = '.';
-+	}
-+	f[i] = '\0';
-+	return f;
-+}
-+
-+static char dec2hex(int i)
-+{
-+	switch (i) {
-+		case 0 ... 9:
-+			return (i + '0');
-+			break;
-+		case 10 ... 15:
-+			return (i - 10 + 'a');
-+			break;
-+		default:
-+			if (net_ratelimit())
-+				printk("layer7: Problem in dec2hex\n");
-+			return '\0';
-+	}
-+}
-+
-+static char * hex_print(unsigned char * s)
-+{
-+	char * g = kmalloc(strlen(s)*3 + 1, GFP_ATOMIC);
-+	int i;
-+
-+	if(!g) {
-+	       if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory in hex_print, "
-+					"bailing.\n");
-+	       return NULL;
-+	}
-+
-+	for(i = 0; i < strlen(s); i++) {
-+		g[i*3    ] = dec2hex(s[i]/16);
-+		g[i*3 + 1] = dec2hex(s[i]%16);
-+		g[i*3 + 2] = ' ';
-+	}
-+	g[i*3] = '\0';
-+
-+	return g;
-+}
-+#endif // DEBUG
-+
-+/* Use instead of regcomp.  As we expect to be seeing the same regexps over and
-+over again, it make sense to cache the results. */
-+static regexp * compile_and_cache(const char * regex_string, 
-+                                  const char * protocol)
-+{
-+	struct pattern_cache * node               = first_pattern_cache;
-+	struct pattern_cache * last_pattern_cache = first_pattern_cache;
-+	struct pattern_cache * tmp;
-+	unsigned int len;
-+
-+	while (node != NULL) {
-+		if (!strcmp(node->regex_string, regex_string))
-+		return node->pattern;
-+
-+		last_pattern_cache = node;/* points at the last non-NULL node */
-+		node = node->next;
-+	}
-+
-+	/* If we reach the end of the list, then we have not yet cached
-+	   the pattern for this regex. Let's do that now.
-+	   Be paranoid about running out of memory to avoid list corruption. */
-+	tmp = kmalloc(sizeof(struct pattern_cache), GFP_ATOMIC);
-+
-+	if(!tmp) {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory in "
-+					"compile_and_cache, bailing.\n");
-+		return NULL;
-+	}
-+
-+	tmp->regex_string  = kmalloc(strlen(regex_string) + 1, GFP_ATOMIC);
-+	tmp->pattern       = kmalloc(sizeof(struct regexp),    GFP_ATOMIC);
-+	tmp->next = NULL;
-+
-+	if(!tmp->regex_string || !tmp->pattern) {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory in "
-+					"compile_and_cache, bailing.\n");
-+		kfree(tmp->regex_string);
-+		kfree(tmp->pattern);
-+		kfree(tmp);
-+		return NULL;
-+	}
-+
-+	/* Ok.  The new node is all ready now. */
-+	node = tmp;
-+
-+	if(first_pattern_cache == NULL) /* list is empty */
-+		first_pattern_cache = node; /* make node the beginning */
-+	else
-+		last_pattern_cache->next = node; /* attach node to the end */
-+
-+	/* copy the string and compile the regex */
-+	len = strlen(regex_string);
-+	DPRINTK("About to compile this: \"%s\"\n", regex_string);
-+	node->pattern = regcomp((char *)regex_string, &len);
-+	if ( !node->pattern ) {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: Error compiling regexp "
-+					"\"%s\" (%s)\n", 
-+					regex_string, protocol);
-+		/* pattern is now cached as NULL, so we won't try again. */
-+	}
-+
-+	strcpy(node->regex_string, regex_string);
-+	return node->pattern;
-+}
-+
-+static int can_handle(const struct sk_buff *skb)
-+{
-+	if(!ip_hdr(skb)) /* not IP */
-+		return 0;
-+	if(ip_hdr(skb)->protocol != IPPROTO_TCP &&
-+	   ip_hdr(skb)->protocol != IPPROTO_UDP &&
-+	   ip_hdr(skb)->protocol != IPPROTO_ICMP)
-+		return 0;
-+	return 1;
-+}
-+
-+/* Returns offset the into the skb->data that the application data starts */
-+static int app_data_offset(const struct sk_buff *skb)
-+{
-+	/* In case we are ported somewhere (ebtables?) where ip_hdr(skb)
-+	isn't set, this can be gotten from 4*(skb->data[0] & 0x0f) as well. */
-+	int ip_hl = 4*ip_hdr(skb)->ihl;
-+
-+	if( ip_hdr(skb)->protocol == IPPROTO_TCP ) {
-+		/* 12 == offset into TCP header for the header length field.
-+		Can't get this with skb->h.th->doff because the tcphdr
-+		struct doesn't get set when routing (this is confirmed to be
-+		true in Netfilter as well as QoS.) */
-+		int tcp_hl = 4*(skb->data[ip_hl + 12] >> 4);
-+
-+		return ip_hl + tcp_hl;
-+	} else if( ip_hdr(skb)->protocol == IPPROTO_UDP  ) {
-+		return ip_hl + 8; /* UDP header is always 8 bytes */
-+	} else if( ip_hdr(skb)->protocol == IPPROTO_ICMP ) {
-+		return ip_hl + 8; /* ICMP header is 8 bytes */
-+	} else {
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: tried to handle unknown "
-+					"protocol!\n");
-+		return ip_hl + 8; /* something reasonable */
-+	}
-+}
-+
-+/* handles whether there's a match when we aren't appending data anymore */
-+static int match_no_append(struct nf_conn * conntrack, 
-+                           struct nf_conn * master_conntrack, 
-+                           enum ip_conntrack_info ctinfo,
-+                           enum ip_conntrack_info master_ctinfo,
-+                           const struct xt_layer7_info * info)
-+{
-+	/* If we're in here, throw the app data away */
-+	if(master_conntrack->layer7.app_data != NULL) {
-+
-+	#ifdef CONFIG_IP_NF_MATCH_LAYER7_DEBUG
-+		if(!master_conntrack->layer7.app_proto) {
-+			char * f = 
-+			  friendly_print(master_conntrack->layer7.app_data);
-+			char * g = 
-+			  hex_print(master_conntrack->layer7.app_data);
-+			DPRINTK("\nl7-filter gave up after %d bytes "
-+				"(%d packets):\n%s\n",
-+				strlen(f), total_acct_packets(master_conntrack), f);
-+			kfree(f);
-+			DPRINTK("In hex: %s\n", g);
-+			kfree(g);
-+		}
-+	#endif
-+
-+		kfree(master_conntrack->layer7.app_data);
-+		master_conntrack->layer7.app_data = NULL; /* don't free again */
-+	}
-+
-+	if(master_conntrack->layer7.app_proto){
-+		/* Here child connections set their .app_proto (for /proc) */
-+		if(!conntrack->layer7.app_proto) {
-+			conntrack->layer7.app_proto = 
-+			  kmalloc(strlen(master_conntrack->layer7.app_proto)+1, 
-+			    GFP_ATOMIC);
-+			if(!conntrack->layer7.app_proto){
-+				if (net_ratelimit())
-+					printk(KERN_ERR "layer7: out of memory "
-+							"in match_no_append, "
-+							"bailing.\n");
-+				return 1;
-+			}
-+			strcpy(conntrack->layer7.app_proto, 
-+				master_conntrack->layer7.app_proto);
-+		}
-+
-+		return (!strcmp(master_conntrack->layer7.app_proto, 
-+				info->protocol));
-+	}
-+	else {
-+		/* If not classified, set to "unknown" to distinguish from
-+		connections that are still being tested. */
-+		master_conntrack->layer7.app_proto = 
-+			kmalloc(strlen("unknown")+1, GFP_ATOMIC);
-+		if(!master_conntrack->layer7.app_proto){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: out of memory in "
-+						"match_no_append, bailing.\n");
-+			return 1;
-+		}
-+		strcpy(master_conntrack->layer7.app_proto, "unknown");
-+		return 0;
-+	}
-+}
-+
-+/* add the new app data to the conntrack.  Return number of bytes added. */
-+static int add_data(struct nf_conn * master_conntrack,
-+                    char * app_data, int appdatalen)
-+{
-+	int length = 0, i;
-+	int oldlength = master_conntrack->layer7.app_data_len;
-+
-+	/* This is a fix for a race condition by Deti Fliegl. However, I'm not 
-+	   clear on whether the race condition exists or whether this really 
-+	   fixes it.  I might just be being dense... Anyway, if it's not really 
-+	   a fix, all it does is waste a very small amount of time. */
-+	if(!master_conntrack->layer7.app_data) return 0;
-+
-+	/* Strip nulls. Make everything lower case (our regex lib doesn't
-+	do case insensitivity).  Add it to the end of the current data. */
-+	for(i = 0; i < maxdatalen-oldlength-1 &&
-+		   i < appdatalen; i++) {
-+		if(app_data[i] != '\0') {
-+			/* the kernel version of tolower mungs 'upper ascii' */
-+			master_conntrack->layer7.app_data[length+oldlength] =
-+				isascii(app_data[i])? 
-+					tolower(app_data[i]) : app_data[i];
-+			length++;
-+		}
-+	}
-+
-+	master_conntrack->layer7.app_data[length+oldlength] = '\0';
-+	master_conntrack->layer7.app_data_len = length + oldlength;
-+
-+	return length;
-+}
-+
-+/* taken from drivers/video/modedb.c */
-+static int my_atoi(const char *s)
-+{
-+	int val = 0;
-+
-+	for (;; s++) {
-+		switch (*s) {
-+			case '0'...'9':
-+			val = 10*val+(*s-'0');
-+			break;
-+		default:
-+			return val;
-+		}
-+	}
-+}
-+
-+/* write out num_packets to userland. */
-+static int layer7_read_proc(char* page, char ** start, off_t off, int count,
-+                            int* eof, void * data)
-+{
-+	if(num_packets > 99 && net_ratelimit())
-+		printk(KERN_ERR "layer7: NOT REACHED. num_packets too big\n");
-+
-+	page[0] = num_packets/10 + '0';
-+	page[1] = num_packets%10 + '0';
-+	page[2] = '\n';
-+	page[3] = '\0';
-+
-+	*eof=1;
-+
-+	return 3;
-+}
-+
-+/* Read in num_packets from userland */
-+static int layer7_write_proc(struct file* file, const char* buffer,
-+                             unsigned long count, void *data)
-+{
-+	char * foo = kmalloc(count, GFP_ATOMIC);
-+
-+	if(!foo){
-+		if (net_ratelimit())
-+			printk(KERN_ERR "layer7: out of memory, bailing. "
-+					"num_packets unchanged.\n");
-+		return count;
-+	}
-+
-+	if(copy_from_user(foo, buffer, count)) {
-+		return -EFAULT;
-+	}
-+
-+
-+	num_packets = my_atoi(foo);
-+	kfree (foo);
-+
-+	/* This has an arbitrary limit to make the math easier. I'm lazy.
-+	But anyway, 99 is a LOT! If you want more, you're doing it wrong! */
-+	if(num_packets > 99) {
-+		printk(KERN_WARNING "layer7: num_packets can't be > 99.\n");
-+		num_packets = 99;
-+	} else if(num_packets < 1) {
-+		printk(KERN_WARNING "layer7: num_packets can't be < 1.\n");
-+		num_packets = 1;
-+	}
-+
-+	return count;
-+}
-+
-+static bool
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+match(const struct sk_buff *skbin, const struct xt_match_param *par)
-+#else
-+match(const struct sk_buff *skbin,
-+      const struct net_device *in,
-+      const struct net_device *out,
-+      const struct xt_match *match,
-+      const void *matchinfo,
-+      int offset,
-+      unsigned int protoff,
-+      bool *hotdrop)
-+#endif
-+{
-+	/* sidestep const without getting a compiler warning... */
-+	struct sk_buff * skb = (struct sk_buff *)skbin; 
-+
-+	const struct xt_layer7_info * info = 
-+	#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+		par->matchinfo;
-+	#else
-+		matchinfo;
-+	#endif
-+
-+	enum ip_conntrack_info master_ctinfo, ctinfo;
-+	struct nf_conn *master_conntrack, *conntrack;
-+	unsigned char * app_data;
-+	unsigned int pattern_result, appdatalen;
-+	regexp * comppattern;
-+
-+	/* Be paranoid/incompetent - lock the entire match function. */
-+	spin_lock_bh(&l7_lock);
-+
-+	if(!can_handle(skb)){
-+		DPRINTK("layer7: This is some protocol I can't handle.\n");
-+		spin_unlock_bh(&l7_lock);
-+		return info->invert;
-+	}
-+
-+	/* Treat parent & all its children together as one connection, except
-+	for the purpose of setting conntrack->layer7.app_proto in the actual
-+	connection. This makes /proc/net/ip_conntrack more satisfying. */
-+	if(!(conntrack = nf_ct_get(skb, &ctinfo)) ||
-+	   !(master_conntrack=nf_ct_get(skb,&master_ctinfo))){
-+		DPRINTK("layer7: couldn't get conntrack.\n");
-+		spin_unlock_bh(&l7_lock);
-+		return info->invert;
-+	}
-+
-+	/* Try to get a master conntrack (and its master etc) for FTP, etc. */
-+	while (master_ct(master_conntrack) != NULL)
-+		master_conntrack = master_ct(master_conntrack);
-+
-+	/* if we've classified it or seen too many packets */
-+	if(total_acct_packets(master_conntrack) > num_packets ||
-+	   master_conntrack->layer7.app_proto) {
-+
-+		pattern_result = match_no_append(conntrack, master_conntrack, 
-+						 ctinfo, master_ctinfo, info);
-+
-+		/* skb->cb[0] == seen. Don't do things twice if there are 
-+		multiple l7 rules. I'm not sure that using cb for this purpose 
-+		is correct, even though it says "put your private variables 
-+		there". But it doesn't look like it is being used for anything
-+		else in the skbs that make it here. */
-+		skb->cb[0] = 1; /* marking it seen here's probably irrelevant */
-+
-+		spin_unlock_bh(&l7_lock);
-+		return (pattern_result ^ info->invert);
-+	}
-+
-+	if(skb_is_nonlinear(skb)){
-+		if(skb_linearize(skb) != 0){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: failed to linearize "
-+						"packet, bailing.\n");
-+			spin_unlock_bh(&l7_lock);
-+			return info->invert;
-+		}
-+	}
-+
-+	/* now that the skb is linearized, it's safe to set these. */
-+	app_data = skb->data + app_data_offset(skb);
-+	appdatalen = skb_tail_pointer(skb) - app_data;
-+
-+	/* the return value gets checked later, when we're ready to use it */
-+	comppattern = compile_and_cache(info->pattern, info->protocol);
-+
-+	/* On the first packet of a connection, allocate space for app data */
-+	if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] && 
-+	   !master_conntrack->layer7.app_data){
-+		master_conntrack->layer7.app_data = 
-+			kmalloc(maxdatalen, GFP_ATOMIC);
-+		if(!master_conntrack->layer7.app_data){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: out of memory in "
-+						"match, bailing.\n");
-+			spin_unlock_bh(&l7_lock);
-+			return info->invert;
-+		}
-+
-+		master_conntrack->layer7.app_data[0] = '\0';
-+	}
-+
-+	/* Can be here, but unallocated, if numpackets is increased near
-+	the beginning of a connection */
-+	if(master_conntrack->layer7.app_data == NULL){
-+		spin_unlock_bh(&l7_lock);
-+		return info->invert; /* unmatched */
-+	}
-+
-+	if(!skb->cb[0]){
-+		int newbytes;
-+		newbytes = add_data(master_conntrack, app_data, appdatalen);
-+
-+		if(newbytes == 0) { /* didn't add any data */
-+			skb->cb[0] = 1;
-+			/* Didn't match before, not going to match now */
-+			spin_unlock_bh(&l7_lock);
-+			return info->invert;
-+		}
-+	}
-+
-+	/* If looking for "unknown", then never match.  "Unknown" means that
-+	we've given up; we're still trying with these packets. */
-+	if(!strcmp(info->protocol, "unknown")) {
-+		pattern_result = 0;
-+	/* If looking for "unset", then always match. "Unset" means that we
-+	haven't yet classified the connection. */
-+	} else if(!strcmp(info->protocol, "unset")) {
-+		pattern_result = 2;
-+		DPRINTK("layer7: matched unset: not yet classified "
-+			"(%d/%d packets)\n",
-+                        total_acct_packets(master_conntrack), num_packets);
-+	/* If the regexp failed to compile, don't bother running it */
-+	} else if(comppattern && 
-+		  regexec(comppattern, master_conntrack->layer7.app_data)){
-+		DPRINTK("layer7: matched %s\n", info->protocol);
-+		pattern_result = 1;
-+	} else pattern_result = 0;
-+
-+	if(pattern_result == 1) {
-+		master_conntrack->layer7.app_proto = 
-+			kmalloc(strlen(info->protocol)+1, GFP_ATOMIC);
-+		if(!master_conntrack->layer7.app_proto){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: out of memory in "
-+						"match, bailing.\n");
-+			spin_unlock_bh(&l7_lock);
-+			return (pattern_result ^ info->invert);
-+		}
-+		strcpy(master_conntrack->layer7.app_proto, info->protocol);
-+	} else if(pattern_result > 1) { /* cleanup from "unset" */
-+		pattern_result = 1;
-+	}
-+
-+	/* mark the packet seen */
-+	skb->cb[0] = 1;
-+
-+	spin_unlock_bh(&l7_lock);
-+	return (pattern_result ^ info->invert);
-+}
-+
-+// load nf_conntrack_ipv4
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+static bool check(const struct xt_mtchk_param *par)
-+{
-+        if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
-+                printk(KERN_WARNING "can't load conntrack support for "
-+                                    "proto=%d\n", par->match->family);
-+#else
-+static bool check(const char *tablename, const void *inf,
-+		 const struct xt_match *match, void *matchinfo,
-+		 unsigned int hook_mask)
-+{
-+        if (nf_ct_l3proto_try_module_get(match->family) < 0) {
-+                printk(KERN_WARNING "can't load conntrack support for "
-+                                    "proto=%d\n", match->family);
-+#endif
-+                return 0;
-+        }
-+	return 1;
-+}
-+
-+
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+	static void destroy(const struct xt_mtdtor_param *par)
-+	{
-+		nf_ct_l3proto_module_put(par->match->family);
-+	}
-+#else
-+	static void destroy(const struct xt_match *match, void *matchinfo)
-+	{
-+		nf_ct_l3proto_module_put(match->family);
-+	}
-+#endif
-+
-+static struct xt_match xt_layer7_match[] __read_mostly = {
-+{
-+	.name		= "layer7",
-+	.family		= AF_INET,
-+	.checkentry	= check,
-+	.match		= match,
-+	.destroy	= destroy,
-+	.matchsize	= sizeof(struct xt_layer7_info),
-+	.me		= THIS_MODULE
-+}
-+};
-+
-+static void layer7_cleanup_proc(void)
-+{
-+	remove_proc_entry("layer7_numpackets", init_net.proc_net);
-+}
-+
-+/* register the proc file */
-+static void layer7_init_proc(void)
-+{
-+	struct proc_dir_entry* entry;
-+	entry = create_proc_entry("layer7_numpackets", 0644, init_net.proc_net);
-+	entry->read_proc = layer7_read_proc;
-+	entry->write_proc = layer7_write_proc;
-+}
-+
-+static int __init xt_layer7_init(void)
-+{
-+	need_conntrack();
-+
-+	layer7_init_proc();
-+	if(maxdatalen < 1) {
-+		printk(KERN_WARNING "layer7: maxdatalen can't be < 1, "
-+			"using 1\n");
-+		maxdatalen = 1;
-+	}
-+	/* This is not a hard limit.  It's just here to prevent people from
-+	bringing their slow machines to a grinding halt. */
-+	else if(maxdatalen > 65536) {
-+		printk(KERN_WARNING "layer7: maxdatalen can't be > 65536, "
-+			"using 65536\n");
-+		maxdatalen = 65536;
-+	}
-+	return xt_register_matches(xt_layer7_match,
-+				   ARRAY_SIZE(xt_layer7_match));
-+}
-+
-+static void __exit xt_layer7_fini(void)
-+{
-+	layer7_cleanup_proc();
-+	xt_unregister_matches(xt_layer7_match, ARRAY_SIZE(xt_layer7_match));
-+}
-+
-+module_init(xt_layer7_init);
-+module_exit(xt_layer7_fini);
---- /dev/null
-+++ b/net/netfilter/regexp/regexp.c
-@@ -0,0 +1,1197 @@
-+/*
-+ * regcomp and regexec -- regsub and regerror are elsewhere
-+ * @(#)regexp.c	1.3 of 18 April 87
-+ *
-+ *	Copyright (c) 1986 by University of Toronto.
-+ *	Written by Henry Spencer.  Not derived from licensed software.
-+ *
-+ *	Permission is granted to anyone to use this software for any
-+ *	purpose on any computer system, and to redistribute it freely,
-+ *	subject to the following restrictions:
-+ *
-+ *	1. The author is not responsible for the consequences of use of
-+ *		this software, no matter how awful, even if they arise
-+ *		from defects in it.
-+ *
-+ *	2. The origin of this software must not be misrepresented, either
-+ *		by explicit claim or by omission.
-+ *
-+ *	3. Altered versions must be plainly marked as such, and must not
-+ *		be misrepresented as being the original software.
-+ *
-+ * Beware that some of this code is subtly aware of the way operator
-+ * precedence is structured in regular expressions.  Serious changes in
-+ * regular-expression syntax might require a total rethink.
-+ *
-+ * This code was modified by Ethan Sommer to work within the kernel
-+ * (it now uses kmalloc etc..)
-+ *
-+ * Modified slightly by Matthew Strait to use more modern C.
-+ */
-+
-+#include "regexp.h"
-+#include "regmagic.h"
-+
-+/* added by ethan and matt.  Lets it work in both kernel and user space.
-+(So iptables can use it, for instance.)  Yea, it goes both ways... */
-+#if __KERNEL__
-+  #define malloc(foo) kmalloc(foo,GFP_ATOMIC)
-+#else
-+  #define printk(format,args...) printf(format,##args)
-+#endif
-+
-+void regerror(char * s)
-+{
-+        printk("<3>Regexp: %s\n", s);
-+        /* NOTREACHED */
-+}
-+
-+/*
-+ * The "internal use only" fields in regexp.h are present to pass info from
-+ * compile to execute that permits the execute phase to run lots faster on
-+ * simple cases.  They are:
-+ *
-+ * regstart	char that must begin a match; '\0' if none obvious
-+ * reganch	is the match anchored (at beginning-of-line only)?
-+ * regmust	string (pointer into program) that match must include, or NULL
-+ * regmlen	length of regmust string
-+ *
-+ * Regstart and reganch permit very fast decisions on suitable starting points
-+ * for a match, cutting down the work a lot.  Regmust permits fast rejection
-+ * of lines that cannot possibly match.  The regmust tests are costly enough
-+ * that regcomp() supplies a regmust only if the r.e. contains something
-+ * potentially expensive (at present, the only such thing detected is * or +
-+ * at the start of the r.e., which can involve a lot of backup).  Regmlen is
-+ * supplied because the test in regexec() needs it and regcomp() is computing
-+ * it anyway.
-+ */
-+
-+/*
-+ * Structure for regexp "program".  This is essentially a linear encoding
-+ * of a nondeterministic finite-state machine (aka syntax charts or
-+ * "railroad normal form" in parsing technology).  Each node is an opcode
-+ * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
-+ * all nodes except BRANCH implement concatenation; a "next" pointer with
-+ * a BRANCH on both ends of it is connecting two alternatives.  (Here we
-+ * have one of the subtle syntax dependencies:  an individual BRANCH (as
-+ * opposed to a collection of them) is never concatenated with anything
-+ * because of operator precedence.)  The operand of some types of node is
-+ * a literal string; for others, it is a node leading into a sub-FSM.  In
-+ * particular, the operand of a BRANCH node is the first node of the branch.
-+ * (NB this is *not* a tree structure:  the tail of the branch connects
-+ * to the thing following the set of BRANCHes.)  The opcodes are:
-+ */
-+
-+/* definition	number	opnd?	meaning */
-+#define	END	0	/* no	End of program. */
-+#define	BOL	1	/* no	Match "" at beginning of line. */
-+#define	EOL	2	/* no	Match "" at end of line. */
-+#define	ANY	3	/* no	Match any one character. */
-+#define	ANYOF	4	/* str	Match any character in this string. */
-+#define	ANYBUT	5	/* str	Match any character not in this string. */
-+#define	BRANCH	6	/* node	Match this alternative, or the next... */
-+#define	BACK	7	/* no	Match "", "next" ptr points backward. */
-+#define	EXACTLY	8	/* str	Match this string. */
-+#define	NOTHING	9	/* no	Match empty string. */
-+#define	STAR	10	/* node	Match this (simple) thing 0 or more times. */
-+#define	PLUS	11	/* node	Match this (simple) thing 1 or more times. */
-+#define	OPEN	20	/* no	Mark this point in input as start of #n. */
-+			/*	OPEN+1 is number 1, etc. */
-+#define	CLOSE	30	/* no	Analogous to OPEN. */
-+
-+/*
-+ * Opcode notes:
-+ *
-+ * BRANCH	The set of branches constituting a single choice are hooked
-+ *		together with their "next" pointers, since precedence prevents
-+ *		anything being concatenated to any individual branch.  The
-+ *		"next" pointer of the last BRANCH in a choice points to the
-+ *		thing following the whole choice.  This is also where the
-+ *		final "next" pointer of each individual branch points; each
-+ *		branch starts with the operand node of a BRANCH node.
-+ *
-+ * BACK		Normal "next" pointers all implicitly point forward; BACK
-+ *		exists to make loop structures possible.
-+ *
-+ * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
-+ *		BRANCH structures using BACK.  Simple cases (one character
-+ *		per match) are implemented with STAR and PLUS for speed
-+ *		and to minimize recursive plunges.
-+ *
-+ * OPEN,CLOSE	...are numbered at compile time.
-+ */
-+
-+/*
-+ * A node is one char of opcode followed by two chars of "next" pointer.
-+ * "Next" pointers are stored as two 8-bit pieces, high order first.  The
-+ * value is a positive offset from the opcode of the node containing it.
-+ * An operand, if any, simply follows the node.  (Note that much of the
-+ * code generation knows about this implicit relationship.)
-+ *
-+ * Using two bytes for the "next" pointer is vast overkill for most things,
-+ * but allows patterns to get big without disasters.
-+ */
-+#define	OP(p)	(*(p))
-+#define	NEXT(p)	(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
-+#define	OPERAND(p)	((p) + 3)
-+
-+/*
-+ * See regmagic.h for one further detail of program structure.
-+ */
-+
-+
-+/*
-+ * Utility definitions.
-+ */
-+#ifndef CHARBITS
-+#define	UCHARAT(p)	((int)*(unsigned char *)(p))
-+#else
-+#define	UCHARAT(p)	((int)*(p)&CHARBITS)
-+#endif
-+
-+#define	FAIL(m)	{ regerror(m); return(NULL); }
-+#define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
-+#define	META	"^$.[()|?+*\\"
-+
-+/*
-+ * Flags to be passed up and down.
-+ */
-+#define	HASWIDTH	01	/* Known never to match null string. */
-+#define	SIMPLE		02	/* Simple enough to be STAR/PLUS operand. */
-+#define	SPSTART		04	/* Starts with * or +. */
-+#define	WORST		0	/* Worst case. */
-+
-+/*
-+ * Global work variables for regcomp().
-+ */
-+struct match_globals {
-+char *reginput;		/* String-input pointer. */
-+char *regbol;		/* Beginning of input, for ^ check. */
-+char **regstartp;	/* Pointer to startp array. */
-+char **regendp;		/* Ditto for endp. */
-+char *regparse;		/* Input-scan pointer. */
-+int regnpar;		/* () count. */
-+char regdummy;
-+char *regcode;		/* Code-emit pointer; &regdummy = don't. */
-+long regsize;		/* Code size. */
-+};
-+
-+/*
-+ * Forward declarations for regcomp()'s friends.
-+ */
-+#ifndef STATIC
-+#define	STATIC	static
-+#endif
-+STATIC char *reg(struct match_globals *g, int paren,int *flagp);
-+STATIC char *regbranch(struct match_globals *g, int *flagp);
-+STATIC char *regpiece(struct match_globals *g, int *flagp);
-+STATIC char *regatom(struct match_globals *g, int *flagp);
-+STATIC char *regnode(struct match_globals *g, char op);
-+STATIC char *regnext(struct match_globals *g, char *p);
-+STATIC void regc(struct match_globals *g, char b);
-+STATIC void reginsert(struct match_globals *g, char op, char *opnd);
-+STATIC void regtail(struct match_globals *g, char *p, char *val);
-+STATIC void regoptail(struct match_globals *g, char *p, char *val);
-+
-+
-+__kernel_size_t my_strcspn(const char *s1,const char *s2)
-+{
-+        char *scan1;
-+        char *scan2;
-+        int count;
-+
-+        count = 0;
-+        for (scan1 = (char *)s1; *scan1 != '\0'; scan1++) {
-+                for (scan2 = (char *)s2; *scan2 != '\0';)       /* ++ moved down. */
-+                        if (*scan1 == *scan2++)
-+                                return(count);
-+                count++;
-+        }
-+        return(count);
-+}
-+
-+/*
-+ - regcomp - compile a regular expression into internal code
-+ *
-+ * We can't allocate space until we know how big the compiled form will be,
-+ * but we can't compile it (and thus know how big it is) until we've got a
-+ * place to put the code.  So we cheat:  we compile it twice, once with code
-+ * generation turned off and size counting turned on, and once "for real".
-+ * This also means that we don't allocate space until we are sure that the
-+ * thing really will compile successfully, and we never have to move the
-+ * code and thus invalidate pointers into it.  (Note that it has to be in
-+ * one piece because free() must be able to free it all.)
-+ *
-+ * Beware that the optimization-preparation code in here knows about some
-+ * of the structure of the compiled regexp.
-+ */
-+regexp *
-+regcomp(char *exp,int *patternsize)
-+{
-+	register regexp *r;
-+	register char *scan;
-+	register char *longest;
-+	register int len;
-+	int flags;
-+	struct match_globals g;
-+	
-+	/* commented out by ethan
-+	   extern char *malloc();
-+	*/
-+
-+	if (exp == NULL)
-+		FAIL("NULL argument");
-+
-+	/* First pass: determine size, legality. */
-+	g.regparse = exp;
-+	g.regnpar = 1;
-+	g.regsize = 0L;
-+	g.regcode = &g.regdummy;
-+	regc(&g, MAGIC);
-+	if (reg(&g, 0, &flags) == NULL)
-+		return(NULL);
-+
-+	/* Small enough for pointer-storage convention? */
-+	if (g.regsize >= 32767L)		/* Probably could be 65535L. */
-+		FAIL("regexp too big");
-+
-+	/* Allocate space. */
-+	*patternsize=sizeof(regexp) + (unsigned)g.regsize;
-+	r = (regexp *)malloc(sizeof(regexp) + (unsigned)g.regsize);
-+	if (r == NULL)
-+		FAIL("out of space");
-+
-+	/* Second pass: emit code. */
-+	g.regparse = exp;
-+	g.regnpar = 1;
-+	g.regcode = r->program;
-+	regc(&g, MAGIC);
-+	if (reg(&g, 0, &flags) == NULL)
-+		return(NULL);
-+
-+	/* Dig out information for optimizations. */
-+	r->regstart = '\0';	/* Worst-case defaults. */
-+	r->reganch = 0;
-+	r->regmust = NULL;
-+	r->regmlen = 0;
-+	scan = r->program+1;			/* First BRANCH. */
-+	if (OP(regnext(&g, scan)) == END) {		/* Only one top-level choice. */
-+		scan = OPERAND(scan);
-+
-+		/* Starting-point info. */
-+		if (OP(scan) == EXACTLY)
-+			r->regstart = *OPERAND(scan);
-+		else if (OP(scan) == BOL)
-+			r->reganch++;
-+
-+		/*
-+		 * If there's something expensive in the r.e., find the
-+		 * longest literal string that must appear and make it the
-+		 * regmust.  Resolve ties in favor of later strings, since
-+		 * the regstart check works with the beginning of the r.e.
-+		 * and avoiding duplication strengthens checking.  Not a
-+		 * strong reason, but sufficient in the absence of others.
-+		 */
-+		if (flags&SPSTART) {
-+			longest = NULL;
-+			len = 0;
-+			for (; scan != NULL; scan = regnext(&g, scan))
-+				if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
-+					longest = OPERAND(scan);
-+					len = strlen(OPERAND(scan));
-+				}
-+			r->regmust = longest;
-+			r->regmlen = len;
-+		}
-+	}
-+
-+	return(r);
-+}
-+
-+/*
-+ - reg - regular expression, i.e. main body or parenthesized thing
-+ *
-+ * Caller must absorb opening parenthesis.
-+ *
-+ * Combining parenthesis handling with the base level of regular expression
-+ * is a trifle forced, but the need to tie the tails of the branches to what
-+ * follows makes it hard to avoid.
-+ */
-+static char *
-+reg(struct match_globals *g, int paren, int *flagp /* Parenthesized? */ )
-+{
-+	register char *ret;
-+	register char *br;
-+	register char *ender;
-+	register int parno = 0; /* 0 makes gcc happy */
-+	int flags;
-+
-+	*flagp = HASWIDTH;	/* Tentatively. */
-+
-+	/* Make an OPEN node, if parenthesized. */
-+	if (paren) {
-+		if (g->regnpar >= NSUBEXP)
-+			FAIL("too many ()");
-+		parno = g->regnpar;
-+		g->regnpar++;
-+		ret = regnode(g, OPEN+parno);
-+	} else
-+		ret = NULL;
-+
-+	/* Pick up the branches, linking them together. */
-+	br = regbranch(g, &flags);
-+	if (br == NULL)
-+		return(NULL);
-+	if (ret != NULL)
-+		regtail(g, ret, br);	/* OPEN -> first. */
-+	else
-+		ret = br;
-+	if (!(flags&HASWIDTH))
-+		*flagp &= ~HASWIDTH;
-+	*flagp |= flags&SPSTART;
-+	while (*g->regparse == '|') {
-+		g->regparse++;
-+		br = regbranch(g, &flags);
-+		if (br == NULL)
-+			return(NULL);
-+		regtail(g, ret, br);	/* BRANCH -> BRANCH. */
-+		if (!(flags&HASWIDTH))
-+			*flagp &= ~HASWIDTH;
-+		*flagp |= flags&SPSTART;
-+	}
-+
-+	/* Make a closing node, and hook it on the end. */
-+	ender = regnode(g, (paren) ? CLOSE+parno : END);	
-+	regtail(g, ret, ender);
-+
-+	/* Hook the tails of the branches to the closing node. */
-+	for (br = ret; br != NULL; br = regnext(g, br))
-+		regoptail(g, br, ender);
-+
-+	/* Check for proper termination. */
-+	if (paren && *g->regparse++ != ')') {
-+		FAIL("unmatched ()");
-+	} else if (!paren && *g->regparse != '\0') {
-+		if (*g->regparse == ')') {
-+			FAIL("unmatched ()");
-+		} else
-+			FAIL("junk on end");	/* "Can't happen". */
-+		/* NOTREACHED */
-+	}
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regbranch - one alternative of an | operator
-+ *
-+ * Implements the concatenation operator.
-+ */
-+static char *
-+regbranch(struct match_globals *g, int *flagp)
-+{
-+	register char *ret;
-+	register char *chain;
-+	register char *latest;
-+	int flags;
-+
-+	*flagp = WORST;		/* Tentatively. */
-+
-+	ret = regnode(g, BRANCH);
-+	chain = NULL;
-+	while (*g->regparse != '\0' && *g->regparse != '|' && *g->regparse != ')') {
-+		latest = regpiece(g, &flags);
-+		if (latest == NULL)
-+			return(NULL);
-+		*flagp |= flags&HASWIDTH;
-+		if (chain == NULL)	/* First piece. */
-+			*flagp |= flags&SPSTART;
-+		else
-+			regtail(g, chain, latest);
-+		chain = latest;
-+	}
-+	if (chain == NULL)	/* Loop ran zero times. */
-+		(void) regnode(g, NOTHING);
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regpiece - something followed by possible [*+?]
-+ *
-+ * Note that the branching code sequences used for ? and the general cases
-+ * of * and + are somewhat optimized:  they use the same NOTHING node as
-+ * both the endmarker for their branch list and the body of the last branch.
-+ * It might seem that this node could be dispensed with entirely, but the
-+ * endmarker role is not redundant.
-+ */
-+static char *
-+regpiece(struct match_globals *g, int *flagp)
-+{
-+	register char *ret;
-+	register char op;
-+	register char *next;
-+	int flags;
-+
-+	ret = regatom(g, &flags);
-+	if (ret == NULL)
-+		return(NULL);
-+
-+	op = *g->regparse;
-+	if (!ISMULT(op)) {
-+		*flagp = flags;
-+		return(ret);
-+	}
-+
-+	if (!(flags&HASWIDTH) && op != '?')
-+		FAIL("*+ operand could be empty");
-+	*flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
-+
-+	if (op == '*' && (flags&SIMPLE))
-+		reginsert(g, STAR, ret);
-+	else if (op == '*') {
-+		/* Emit x* as (x&|), where & means "self". */
-+		reginsert(g, BRANCH, ret);			/* Either x */
-+		regoptail(g, ret, regnode(g, BACK));		/* and loop */
-+		regoptail(g, ret, ret);			/* back */
-+		regtail(g, ret, regnode(g, BRANCH));		/* or */
-+		regtail(g, ret, regnode(g, NOTHING));		/* null. */
-+	} else if (op == '+' && (flags&SIMPLE))
-+		reginsert(g, PLUS, ret);
-+	else if (op == '+') {
-+		/* Emit x+ as x(&|), where & means "self". */
-+		next = regnode(g, BRANCH);			/* Either */
-+		regtail(g, ret, next);
-+		regtail(g, regnode(g, BACK), ret);		/* loop back */
-+		regtail(g, next, regnode(g, BRANCH));		/* or */
-+		regtail(g, ret, regnode(g, NOTHING));		/* null. */
-+	} else if (op == '?') {
-+		/* Emit x? as (x|) */
-+		reginsert(g, BRANCH, ret);			/* Either x */
-+		regtail(g, ret, regnode(g, BRANCH));		/* or */
-+		next = regnode(g, NOTHING);		/* null. */
-+		regtail(g, ret, next);
-+		regoptail(g, ret, next);
-+	}
-+	g->regparse++;
-+	if (ISMULT(*g->regparse))
-+		FAIL("nested *?+");
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regatom - the lowest level
-+ *
-+ * Optimization:  gobbles an entire sequence of ordinary characters so that
-+ * it can turn them into a single node, which is smaller to store and
-+ * faster to run.  Backslashed characters are exceptions, each becoming a
-+ * separate node; the code is simpler that way and it's not worth fixing.
-+ */
-+static char *
-+regatom(struct match_globals *g, int *flagp)
-+{
-+	register char *ret;
-+	int flags;
-+
-+	*flagp = WORST;		/* Tentatively. */
-+
-+	switch (*g->regparse++) {
-+	case '^':
-+		ret = regnode(g, BOL);
-+		break;
-+	case '$':
-+		ret = regnode(g, EOL);
-+		break;
-+	case '.':
-+		ret = regnode(g, ANY);
-+		*flagp |= HASWIDTH|SIMPLE;
-+		break;
-+	case '[': {
-+			register int class;
-+			register int classend;
-+
-+			if (*g->regparse == '^') {	/* Complement of range. */
-+				ret = regnode(g, ANYBUT);
-+				g->regparse++;
-+			} else
-+				ret = regnode(g, ANYOF);
-+			if (*g->regparse == ']' || *g->regparse == '-')
-+				regc(g, *g->regparse++);
-+			while (*g->regparse != '\0' && *g->regparse != ']') {
-+				if (*g->regparse == '-') {
-+					g->regparse++;
-+					if (*g->regparse == ']' || *g->regparse == '\0')
-+						regc(g, '-');
-+					else {
-+						class = UCHARAT(g->regparse-2)+1;
-+						classend = UCHARAT(g->regparse);
-+						if (class > classend+1)
-+							FAIL("invalid [] range");
-+						for (; class <= classend; class++)
-+							regc(g, class);
-+						g->regparse++;
-+					}
-+				} else
-+					regc(g, *g->regparse++);
-+			}
-+			regc(g, '\0');
-+			if (*g->regparse != ']')
-+				FAIL("unmatched []");
-+			g->regparse++;
-+			*flagp |= HASWIDTH|SIMPLE;
-+		}
-+		break;
-+	case '(':
-+		ret = reg(g, 1, &flags);
-+		if (ret == NULL)
-+			return(NULL);
-+		*flagp |= flags&(HASWIDTH|SPSTART);
-+		break;
-+	case '\0':
-+	case '|':
-+	case ')':
-+		FAIL("internal urp");	/* Supposed to be caught earlier. */
-+		break;
-+	case '?':
-+	case '+':
-+	case '*':
-+		FAIL("?+* follows nothing");
-+		break;
-+	case '\\':
-+		if (*g->regparse == '\0')
-+			FAIL("trailing \\");
-+		ret = regnode(g, EXACTLY);
-+		regc(g, *g->regparse++);
-+		regc(g, '\0');
-+		*flagp |= HASWIDTH|SIMPLE;
-+		break;
-+	default: {
-+			register int len;
-+			register char ender;
-+
-+			g->regparse--;
-+			len = my_strcspn((const char *)g->regparse, (const char *)META);
-+			if (len <= 0)
-+				FAIL("internal disaster");
-+			ender = *(g->regparse+len);
-+			if (len > 1 && ISMULT(ender))
-+				len--;		/* Back off clear of ?+* operand. */
-+			*flagp |= HASWIDTH;
-+			if (len == 1)
-+				*flagp |= SIMPLE;
-+			ret = regnode(g, EXACTLY);
-+			while (len > 0) {
-+				regc(g, *g->regparse++);
-+				len--;
-+			}
-+			regc(g, '\0');
-+		}
-+		break;
-+	}
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regnode - emit a node
-+ */
-+static char *			/* Location. */
-+regnode(struct match_globals *g, char op)
-+{
-+	register char *ret;
-+	register char *ptr;
-+
-+	ret = g->regcode;
-+	if (ret == &g->regdummy) {
-+		g->regsize += 3;
-+		return(ret);
-+	}
-+
-+	ptr = ret;
-+	*ptr++ = op;
-+	*ptr++ = '\0';		/* Null "next" pointer. */
-+	*ptr++ = '\0';
-+	g->regcode = ptr;
-+
-+	return(ret);
-+}
-+
-+/*
-+ - regc - emit (if appropriate) a byte of code
-+ */
-+static void
-+regc(struct match_globals *g, char b)
-+{
-+	if (g->regcode != &g->regdummy)
-+		*g->regcode++ = b;
-+	else
-+		g->regsize++;
-+}
-+
-+/*
-+ - reginsert - insert an operator in front of already-emitted operand
-+ *
-+ * Means relocating the operand.
-+ */
-+static void
-+reginsert(struct match_globals *g, char op, char* opnd)
-+{
-+	register char *src;
-+	register char *dst;
-+	register char *place;
-+
-+	if (g->regcode == &g->regdummy) {
-+		g->regsize += 3;
-+		return;
-+	}
-+
-+	src = g->regcode;
-+	g->regcode += 3;
-+	dst = g->regcode;
-+	while (src > opnd)
-+		*--dst = *--src;
-+
-+	place = opnd;		/* Op node, where operand used to be. */
-+	*place++ = op;
-+	*place++ = '\0';
-+	*place++ = '\0';
-+}
-+
-+/*
-+ - regtail - set the next-pointer at the end of a node chain
-+ */
-+static void
-+regtail(struct match_globals *g, char *p, char *val)
-+{
-+	register char *scan;
-+	register char *temp;
-+	register int offset;
-+
-+	if (p == &g->regdummy)
-+		return;
-+
-+	/* Find last node. */
-+	scan = p;
-+	for (;;) {
-+		temp = regnext(g, scan);
-+		if (temp == NULL)
-+			break;
-+		scan = temp;
-+	}
-+
-+	if (OP(scan) == BACK)
-+		offset = scan - val;
-+	else
-+		offset = val - scan;
-+	*(scan+1) = (offset>>8)&0377;
-+	*(scan+2) = offset&0377;
-+}
-+
-+/*
-+ - regoptail - regtail on operand of first argument; nop if operandless
-+ */
-+static void
-+regoptail(struct match_globals *g, char *p, char *val)
-+{
-+	/* "Operandless" and "op != BRANCH" are synonymous in practice. */
-+	if (p == NULL || p == &g->regdummy || OP(p) != BRANCH)
-+		return;
-+	regtail(g, OPERAND(p), val);
-+}
-+
-+/*
-+ * regexec and friends
-+ */
-+
-+
-+/*
-+ * Forwards.
-+ */
-+STATIC int regtry(struct match_globals *g, regexp *prog, char *string);
-+STATIC int regmatch(struct match_globals *g, char *prog);
-+STATIC int regrepeat(struct match_globals *g, char *p);
-+
-+#ifdef DEBUG
-+int regnarrate = 0;
-+void regdump();
-+STATIC char *regprop(char *op);
-+#endif
-+
-+/*
-+ - regexec - match a regexp against a string
-+ */
-+int
-+regexec(regexp *prog, char *string)
-+{
-+	register char *s;
-+	struct match_globals g;
-+
-+	/* Be paranoid... */
-+	if (prog == NULL || string == NULL) {
-+		printk("<3>Regexp: NULL parameter\n");
-+		return(0);
-+	}
-+
-+	/* Check validity of program. */
-+	if (UCHARAT(prog->program) != MAGIC) {
-+		printk("<3>Regexp: corrupted program\n");
-+		return(0);
-+	}
-+
-+	/* If there is a "must appear" string, look for it. */
-+	if (prog->regmust != NULL) {
-+		s = string;
-+		while ((s = strchr(s, prog->regmust[0])) != NULL) {
-+			if (strncmp(s, prog->regmust, prog->regmlen) == 0)
-+				break;	/* Found it. */
-+			s++;
-+		}
-+		if (s == NULL)	/* Not present. */
-+			return(0);
-+	}
-+
-+	/* Mark beginning of line for ^ . */
-+	g.regbol = string;
-+
-+	/* Simplest case:  anchored match need be tried only once. */
-+	if (prog->reganch)
-+		return(regtry(&g, prog, string));
-+
-+	/* Messy cases:  unanchored match. */
-+	s = string;
-+	if (prog->regstart != '\0')
-+		/* We know what char it must start with. */
-+		while ((s = strchr(s, prog->regstart)) != NULL) {
-+			if (regtry(&g, prog, s))
-+				return(1);
-+			s++;
-+		}
-+	else
-+		/* We don't -- general case. */
-+		do {
-+			if (regtry(&g, prog, s))
-+				return(1);
-+		} while (*s++ != '\0');
-+
-+	/* Failure. */
-+	return(0);
-+}
-+
-+/*
-+ - regtry - try match at specific point
-+ */
-+static int			/* 0 failure, 1 success */
-+regtry(struct match_globals *g, regexp *prog, char *string)
-+{
-+	register int i;
-+	register char **sp;
-+	register char **ep;
-+
-+	g->reginput = string;
-+	g->regstartp = prog->startp;
-+	g->regendp = prog->endp;
-+
-+	sp = prog->startp;
-+	ep = prog->endp;
-+	for (i = NSUBEXP; i > 0; i--) {
-+		*sp++ = NULL;
-+		*ep++ = NULL;
-+	}
-+	if (regmatch(g, prog->program + 1)) {
-+		prog->startp[0] = string;
-+		prog->endp[0] = g->reginput;
-+		return(1);
-+	} else
-+		return(0);
-+}
-+
-+/*
-+ - regmatch - main matching routine
-+ *
-+ * Conceptually the strategy is simple:  check to see whether the current
-+ * node matches, call self recursively to see whether the rest matches,
-+ * and then act accordingly.  In practice we make some effort to avoid
-+ * recursion, in particular by going through "ordinary" nodes (that don't
-+ * need to know whether the rest of the match failed) by a loop instead of
-+ * by recursion.
-+ */
-+static int			/* 0 failure, 1 success */
-+regmatch(struct match_globals *g, char *prog)
-+{
-+	register char *scan = prog; /* Current node. */
-+	char *next;		    /* Next node. */
-+
-+#ifdef DEBUG
-+	if (scan != NULL && regnarrate)
-+		fprintf(stderr, "%s(\n", regprop(scan));
-+#endif
-+	while (scan != NULL) {
-+#ifdef DEBUG
-+		if (regnarrate)
-+			fprintf(stderr, "%s...\n", regprop(scan));
-+#endif
-+		next = regnext(g, scan);
-+
-+		switch (OP(scan)) {
-+		case BOL:
-+			if (g->reginput != g->regbol)
-+				return(0);
-+			break;
-+		case EOL:
-+			if (*g->reginput != '\0')
-+				return(0);
-+			break;
-+		case ANY:
-+			if (*g->reginput == '\0')
-+				return(0);
-+			g->reginput++;
-+			break;
-+		case EXACTLY: {
-+				register int len;
-+				register char *opnd;
-+
-+				opnd = OPERAND(scan);
-+				/* Inline the first character, for speed. */
-+				if (*opnd != *g->reginput)
-+					return(0);
-+				len = strlen(opnd);
-+				if (len > 1 && strncmp(opnd, g->reginput, len) != 0)
-+					return(0);
-+				g->reginput += len;
-+			}
-+			break;
-+		case ANYOF:
-+			if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) == NULL)
-+				return(0);
-+			g->reginput++;
-+			break;
-+		case ANYBUT:
-+			if (*g->reginput == '\0' || strchr(OPERAND(scan), *g->reginput) != NULL)
-+				return(0);
-+			g->reginput++;
-+			break;
-+		case NOTHING:
-+		case BACK:
-+			break;
-+		case OPEN+1:
-+		case OPEN+2:
-+		case OPEN+3:
-+		case OPEN+4:
-+		case OPEN+5:
-+		case OPEN+6:
-+		case OPEN+7:
-+		case OPEN+8:
-+		case OPEN+9: {
-+				register int no;
-+				register char *save;
-+
-+				no = OP(scan) - OPEN;
-+				save = g->reginput;
-+
-+				if (regmatch(g, next)) {
-+					/*
-+					 * Don't set startp if some later
-+					 * invocation of the same parentheses
-+					 * already has.
-+					 */
-+					if (g->regstartp[no] == NULL)
-+						g->regstartp[no] = save;
-+					return(1);
-+				} else
-+					return(0);
-+			}
-+			break;
-+		case CLOSE+1:
-+		case CLOSE+2:
-+		case CLOSE+3:
-+		case CLOSE+4:
-+		case CLOSE+5:
-+		case CLOSE+6:
-+		case CLOSE+7:
-+		case CLOSE+8:
-+		case CLOSE+9:
-+			{
-+				register int no;
-+				register char *save;
-+
-+				no = OP(scan) - CLOSE;
-+				save = g->reginput;
-+
-+				if (regmatch(g, next)) {
-+					/*
-+					 * Don't set endp if some later
-+					 * invocation of the same parentheses
-+					 * already has.
-+					 */
-+					if (g->regendp[no] == NULL)
-+						g->regendp[no] = save;
-+					return(1);
-+				} else
-+					return(0);
-+			}
-+			break;
-+		case BRANCH: {
-+				register char *save;
-+
-+				if (OP(next) != BRANCH)		/* No choice. */
-+					next = OPERAND(scan);	/* Avoid recursion. */
-+				else {
-+					do {
-+						save = g->reginput;
-+						if (regmatch(g, OPERAND(scan)))
-+							return(1);
-+						g->reginput = save;
-+						scan = regnext(g, scan);
-+					} while (scan != NULL && OP(scan) == BRANCH);
-+					return(0);
-+					/* NOTREACHED */
-+				}
-+			}
-+			break;
-+		case STAR:
-+		case PLUS: {
-+				register char nextch;
-+				register int no;
-+				register char *save;
-+				register int min;
-+
-+				/*
-+				 * Lookahead to avoid useless match attempts
-+				 * when we know what character comes next.
-+				 */
-+				nextch = '\0';
-+				if (OP(next) == EXACTLY)
-+					nextch = *OPERAND(next);
-+				min = (OP(scan) == STAR) ? 0 : 1;
-+				save = g->reginput;
-+				no = regrepeat(g, OPERAND(scan));
-+				while (no >= min) {
-+					/* If it could work, try it. */
-+					if (nextch == '\0' || *g->reginput == nextch)
-+						if (regmatch(g, next))
-+							return(1);
-+					/* Couldn't or didn't -- back up. */
-+					no--;
-+					g->reginput = save + no;
-+				}
-+				return(0);
-+			}
-+			break;
-+		case END:
-+			return(1);	/* Success! */
-+			break;
-+		default:
-+			printk("<3>Regexp: memory corruption\n");
-+			return(0);
-+			break;
-+		}
-+
-+		scan = next;
-+	}
-+
-+	/*
-+	 * We get here only if there's trouble -- normally "case END" is
-+	 * the terminating point.
-+	 */
-+	printk("<3>Regexp: corrupted pointers\n");
-+	return(0);
-+}
-+
-+/*
-+ - regrepeat - repeatedly match something simple, report how many
-+ */
-+static int
-+regrepeat(struct match_globals *g, char *p)
-+{
-+	register int count = 0;
-+	register char *scan;
-+	register char *opnd;
-+
-+	scan = g->reginput;
-+	opnd = OPERAND(p);
-+	switch (OP(p)) {
-+	case ANY:
-+		count = strlen(scan);
-+		scan += count;
-+		break;
-+	case EXACTLY:
-+		while (*opnd == *scan) {
-+			count++;
-+			scan++;
-+		}
-+		break;
-+	case ANYOF:
-+		while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
-+			count++;
-+			scan++;
-+		}
-+		break;
-+	case ANYBUT:
-+		while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
-+			count++;
-+			scan++;
-+		}
-+		break;
-+	default:		/* Oh dear.  Called inappropriately. */
-+		printk("<3>Regexp: internal foulup\n");
-+		count = 0;	/* Best compromise. */
-+		break;
-+	}
-+	g->reginput = scan;
-+
-+	return(count);
-+}
-+
-+/*
-+ - regnext - dig the "next" pointer out of a node
-+ */
-+static char*
-+regnext(struct match_globals *g, char *p)
-+{
-+	register int offset;
-+
-+	if (p == &g->regdummy)
-+		return(NULL);
-+
-+	offset = NEXT(p);
-+	if (offset == 0)
-+		return(NULL);
-+
-+	if (OP(p) == BACK)
-+		return(p-offset);
-+	else
-+		return(p+offset);
-+}
-+
-+#ifdef DEBUG
-+
-+STATIC char *regprop();
-+
-+/*
-+ - regdump - dump a regexp onto stdout in vaguely comprehensible form
-+ */
-+void
-+regdump(regexp *r)
-+{
-+	register char *s;
-+	register char op = EXACTLY;	/* Arbitrary non-END op. */
-+	register char *next;
-+	/* extern char *strchr(); */
-+
-+
-+	s = r->program + 1;
-+	while (op != END) {	/* While that wasn't END last time... */
-+		op = OP(s);
-+		printf("%2d%s", s-r->program, regprop(s));	/* Where, what. */
-+		next = regnext(s);
-+		if (next == NULL)		/* Next ptr. */
-+			printf("(0)");
-+		else
-+			printf("(%d)", (s-r->program)+(next-s));
-+		s += 3;
-+		if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
-+			/* Literal string, where present. */
-+			while (*s != '\0') {
-+				putchar(*s);
-+				s++;
-+			}
-+			s++;
-+		}
-+		putchar('\n');
-+	}
-+
-+	/* Header fields of interest. */
-+	if (r->regstart != '\0')
-+		printf("start `%c' ", r->regstart);
-+	if (r->reganch)
-+		printf("anchored ");
-+	if (r->regmust != NULL)
-+		printf("must have \"%s\"", r->regmust);
-+	printf("\n");
-+}
-+
-+/*
-+ - regprop - printable representation of opcode
-+ */
-+static char *
-+regprop(char *op)
-+{
-+#define BUFLEN 50
-+	register char *p;
-+	static char buf[BUFLEN];
-+
-+	strcpy(buf, ":");
-+
-+	switch (OP(op)) {
-+	case BOL:
-+		p = "BOL";
-+		break;
-+	case EOL:
-+		p = "EOL";
-+		break;
-+	case ANY:
-+		p = "ANY";
-+		break;
-+	case ANYOF:
-+		p = "ANYOF";
-+		break;
-+	case ANYBUT:
-+		p = "ANYBUT";
-+		break;
-+	case BRANCH:
-+		p = "BRANCH";
-+		break;
-+	case EXACTLY:
-+		p = "EXACTLY";
-+		break;
-+	case NOTHING:
-+		p = "NOTHING";
-+		break;
-+	case BACK:
-+		p = "BACK";
-+		break;
-+	case END:
-+		p = "END";
-+		break;
-+	case OPEN+1:
-+	case OPEN+2:
-+	case OPEN+3:
-+	case OPEN+4:
-+	case OPEN+5:
-+	case OPEN+6:
-+	case OPEN+7:
-+	case OPEN+8:
-+	case OPEN+9:
-+		snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "OPEN%d", OP(op)-OPEN);
-+		p = NULL;
-+		break;
-+	case CLOSE+1:
-+	case CLOSE+2:
-+	case CLOSE+3:
-+	case CLOSE+4:
-+	case CLOSE+5:
-+	case CLOSE+6:
-+	case CLOSE+7:
-+	case CLOSE+8:
-+	case CLOSE+9:
-+		snprintf(buf+strlen(buf),BUFLEN-strlen(buf), "CLOSE%d", OP(op)-CLOSE);
-+		p = NULL;
-+		break;
-+	case STAR:
-+		p = "STAR";
-+		break;
-+	case PLUS:
-+		p = "PLUS";
-+		break;
-+	default:
-+		printk("<3>Regexp: corrupted opcode\n");
-+		break;
-+	}
-+	if (p != NULL)
-+		strncat(buf, p, BUFLEN-strlen(buf));
-+	return(buf);
-+}
-+#endif
-+
-+
---- /dev/null
-+++ b/net/netfilter/regexp/regexp.h
-@@ -0,0 +1,41 @@
-+/*
-+ * Definitions etc. for regexp(3) routines.
-+ *
-+ * Caveat:  this is V8 regexp(3) [actually, a reimplementation thereof],
-+ * not the System V one.
-+ */
-+
-+#ifndef REGEXP_H
-+#define REGEXP_H
-+
-+
-+/*
-+http://www.opensource.apple.com/darwinsource/10.3/expect-1/expect/expect.h ,
-+which contains a version of this library, says:
-+
-+ *
-+ * NSUBEXP must be at least 10, and no greater than 117 or the parser
-+ * will not work properly.
-+ *
-+
-+However, it looks rather like this library is limited to 10.  If you think
-+otherwise, let us know.
-+*/
-+
-+#define NSUBEXP  10
-+typedef struct regexp {
-+	char *startp[NSUBEXP];
-+	char *endp[NSUBEXP];
-+	char regstart;		/* Internal use only. */
-+	char reganch;		/* Internal use only. */
-+	char *regmust;		/* Internal use only. */
-+	int regmlen;		/* Internal use only. */
-+	char program[1];	/* Unwarranted chumminess with compiler. */
-+} regexp;
-+
-+regexp * regcomp(char *exp, int *patternsize);
-+int regexec(regexp *prog, char *string);
-+void regsub(regexp *prog, char *source, char *dest);
-+void regerror(char *s);
-+
-+#endif
---- /dev/null
-+++ b/net/netfilter/regexp/regmagic.h
-@@ -0,0 +1,5 @@
-+/*
-+ * The first byte of the regexp internal "program" is actually this magic
-+ * number; the start node begins in the second byte.
-+ */
-+#define	MAGIC	0234
---- /dev/null
-+++ b/net/netfilter/regexp/regsub.c
-@@ -0,0 +1,95 @@
-+/*
-+ * regsub
-+ * @(#)regsub.c	1.3 of 2 April 86
-+ *
-+ *	Copyright (c) 1986 by University of Toronto.
-+ *	Written by Henry Spencer.  Not derived from licensed software.
-+ *
-+ *	Permission is granted to anyone to use this software for any
-+ *	purpose on any computer system, and to redistribute it freely,
-+ *	subject to the following restrictions:
-+ *
-+ *	1. The author is not responsible for the consequences of use of
-+ *		this software, no matter how awful, even if they arise
-+ *		from defects in it.
-+ *
-+ *	2. The origin of this software must not be misrepresented, either
-+ *		by explicit claim or by omission.
-+ *
-+ *	3. Altered versions must be plainly marked as such, and must not
-+ *		be misrepresented as being the original software.
-+ *
-+ *
-+ * This code was modified by Ethan Sommer to work within the kernel
-+ * (it now uses kmalloc etc..)
-+ *
-+ */
-+#include "regexp.h"
-+#include "regmagic.h"
-+#include <linux/string.h>
-+
-+
-+#ifndef CHARBITS
-+#define	UCHARAT(p)	((int)*(unsigned char *)(p))
-+#else
-+#define	UCHARAT(p)	((int)*(p)&CHARBITS)
-+#endif
-+
-+#if 0
-+//void regerror(char * s)
-+//{
-+//        printk("regexp(3): %s", s);
-+//        /* NOTREACHED */
-+//}
-+#endif
-+
-+/*
-+ - regsub - perform substitutions after a regexp match
-+ */
-+void
-+regsub(regexp * prog, char * source, char * dest)
-+{
-+	register char *src;
-+	register char *dst;
-+	register char c;
-+	register int no;
-+	register int len;
-+	
-+	/* Not necessary and gcc doesn't like it -MLS */
-+	/*extern char *strncpy();*/
-+
-+	if (prog == NULL || source == NULL || dest == NULL) {
-+		regerror("NULL parm to regsub");
-+		return;
-+	}
-+	if (UCHARAT(prog->program) != MAGIC) {
-+		regerror("damaged regexp fed to regsub");
-+		return;
-+	}
-+
-+	src = source;
-+	dst = dest;
-+	while ((c = *src++) != '\0') {
-+		if (c == '&')
-+			no = 0;
-+		else if (c == '\\' && '0' <= *src && *src <= '9')
-+			no = *src++ - '0';
-+		else
-+			no = -1;
-+
-+		if (no < 0) {	/* Ordinary character. */
-+			if (c == '\\' && (*src == '\\' || *src == '&'))
-+				c = *src++;
-+			*dst++ = c;
-+		} else if (prog->startp[no] != NULL && prog->endp[no] != NULL) {
-+			len = prog->endp[no] - prog->startp[no];
-+			(void) strncpy(dst, prog->startp[no], len);
-+			dst += len;
-+			if (len != 0 && *(dst-1) == '\0') {	/* strncpy hit NUL. */
-+				regerror("damaged match string");
-+				return;
-+			}
-+		}
-+	}
-+	*dst++ = '\0';
-+}
---- a/net/netfilter/nf_conntrack_core.c
-+++ b/net/netfilter/nf_conntrack_core.c
-@@ -212,6 +212,14 @@ destroy_conntrack(struct nf_conntrack *n
- 	 * too. */
- 	nf_ct_remove_expectations(ct);
- 
-+	#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
-+	if(ct->layer7.app_proto)
-+		kfree(ct->layer7.app_proto);
-+	if(ct->layer7.app_data)
-+	kfree(ct->layer7.app_data);
-+	#endif
-+
-+
- 	/* We overload first tuple to link into unconfirmed list. */
- 	if (!nf_ct_is_confirmed(ct)) {
- 		BUG_ON(hlist_nulls_unhashed(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode));
---- a/net/netfilter/nf_conntrack_standalone.c
-+++ b/net/netfilter/nf_conntrack_standalone.c
-@@ -200,6 +200,12 @@ static int ct_seq_show(struct seq_file *
- 		goto release;
- #endif
- 
-+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
-+	if(ct->layer7.app_proto &&
-+           seq_printf(s, "l7proto=%s ", ct->layer7.app_proto))
-+		return -ENOSPC;
-+#endif
-+
- 	if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
- 		goto release;
- 
---- a/include/net/netfilter/nf_conntrack.h
-+++ b/include/net/netfilter/nf_conntrack.h
-@@ -116,6 +116,22 @@ struct nf_conn {
- 	u_int32_t secmark;
- #endif
- 
-+#if defined(CONFIG_NETFILTER_XT_MATCH_LAYER7) || \
-+    defined(CONFIG_NETFILTER_XT_MATCH_LAYER7_MODULE)
-+	struct {
-+		/*
-+		 * e.g. "http". NULL before decision. "unknown" after decision
-+		 * if no match.
-+		 */
-+		char *app_proto;
-+		/*
-+		 * application layer data so far. NULL after match decision.
-+		 */
-+		char *app_data;
-+		unsigned int app_data_len;
-+	} layer7;
-+#endif
-+
- 	/* Storage reserved for other modules: */
- 	union nf_conntrack_proto proto;
- 
---- /dev/null
-+++ b/include/linux/netfilter/xt_layer7.h
-@@ -0,0 +1,13 @@
-+#ifndef _XT_LAYER7_H
-+#define _XT_LAYER7_H
-+
-+#define MAX_PATTERN_LEN 8192
-+#define MAX_PROTOCOL_LEN 256
-+
-+struct xt_layer7_info {
-+    char protocol[MAX_PROTOCOL_LEN];
-+    char pattern[MAX_PATTERN_LEN];
-+    u_int8_t invert;
-+};
-+
-+#endif /* _XT_LAYER7_H */
---- a/include/linux/netfilter/Kbuild
-+++ b/include/linux/netfilter/Kbuild
-@@ -40,6 +40,7 @@ header-y += xt_hashlimit.h
- header-y += xt_helper.h
- header-y += xt_iprange.h
- header-y += xt_ipvs.h
-+header-y += xt_layer7.h
- header-y += xt_length.h
- header-y += xt_limit.h
- header-y += xt_mac.h
diff --git a/target/linux/generic/patches-2.6.38/601-netfilter_layer7_pktmatch.patch b/target/linux/generic/patches-2.6.38/601-netfilter_layer7_pktmatch.patch
deleted file mode 100644
index f65e301fd1..0000000000
--- a/target/linux/generic/patches-2.6.38/601-netfilter_layer7_pktmatch.patch
+++ /dev/null
@@ -1,108 +0,0 @@
---- a/include/linux/netfilter/xt_layer7.h
-+++ b/include/linux/netfilter/xt_layer7.h
-@@ -8,6 +8,7 @@ struct xt_layer7_info {
-     char protocol[MAX_PROTOCOL_LEN];
-     char pattern[MAX_PATTERN_LEN];
-     u_int8_t invert;
-+    u_int8_t pkt;
- };
- 
- #endif /* _XT_LAYER7_H */
---- a/net/netfilter/xt_layer7.c
-+++ b/net/netfilter/xt_layer7.c
-@@ -314,33 +314,35 @@ static int match_no_append(struct nf_con
- }
- 
- /* add the new app data to the conntrack.  Return number of bytes added. */
--static int add_data(struct nf_conn * master_conntrack,
--                    char * app_data, int appdatalen)
-+static int add_datastr(char *target, int offset, char *app_data, int len)
- {
- 	int length = 0, i;
--	int oldlength = master_conntrack->layer7.app_data_len;
--
--	/* This is a fix for a race condition by Deti Fliegl. However, I'm not 
--	   clear on whether the race condition exists or whether this really 
--	   fixes it.  I might just be being dense... Anyway, if it's not really 
--	   a fix, all it does is waste a very small amount of time. */
--	if(!master_conntrack->layer7.app_data) return 0;
-+	if (!target) return 0;
- 
- 	/* Strip nulls. Make everything lower case (our regex lib doesn't
- 	do case insensitivity).  Add it to the end of the current data. */
--	for(i = 0; i < maxdatalen-oldlength-1 &&
--		   i < appdatalen; i++) {
-+ 	for(i = 0; i < maxdatalen-offset-1 && i < len; i++) {
- 		if(app_data[i] != '\0') {
- 			/* the kernel version of tolower mungs 'upper ascii' */
--			master_conntrack->layer7.app_data[length+oldlength] =
-+			target[length+offset] =
- 				isascii(app_data[i])? 
- 					tolower(app_data[i]) : app_data[i];
- 			length++;
- 		}
- 	}
-+	target[length+offset] = '\0';
-+
-+	return length;
-+}
-+
-+/* add the new app data to the conntrack.  Return number of bytes added. */
-+static int add_data(struct nf_conn * master_conntrack,
-+                    char * app_data, int appdatalen)
-+{
-+	int length;
- 
--	master_conntrack->layer7.app_data[length+oldlength] = '\0';
--	master_conntrack->layer7.app_data_len = length + oldlength;
-+	length = add_datastr(master_conntrack->layer7.app_data, master_conntrack->layer7.app_data_len, app_data, appdatalen);
-+	master_conntrack->layer7.app_data_len += length;
- 
- 	return length;
- }
-@@ -438,7 +440,7 @@ match(const struct sk_buff *skbin,
- 
- 	enum ip_conntrack_info master_ctinfo, ctinfo;
- 	struct nf_conn *master_conntrack, *conntrack;
--	unsigned char * app_data;
-+	unsigned char *app_data, *tmp_data;
- 	unsigned int pattern_result, appdatalen;
- 	regexp * comppattern;
- 
-@@ -466,8 +468,8 @@ match(const struct sk_buff *skbin,
- 		master_conntrack = master_ct(master_conntrack);
- 
- 	/* if we've classified it or seen too many packets */
--	if(total_acct_packets(master_conntrack) > num_packets ||
--	   master_conntrack->layer7.app_proto) {
-+	if(!info->pkt && (total_acct_packets(master_conntrack) > num_packets ||
-+	   master_conntrack->layer7.app_proto)) {
- 
- 		pattern_result = match_no_append(conntrack, master_conntrack, 
- 						 ctinfo, master_ctinfo, info);
-@@ -500,6 +502,25 @@ match(const struct sk_buff *skbin,
- 	/* the return value gets checked later, when we're ready to use it */
- 	comppattern = compile_and_cache(info->pattern, info->protocol);
- 
-+	if (info->pkt) {
-+		tmp_data = kmalloc(maxdatalen, GFP_ATOMIC);
-+		if(!tmp_data){
-+			if (net_ratelimit())
-+				printk(KERN_ERR "layer7: out of memory in match, bailing.\n");
-+			return info->invert;
-+		}
-+
-+		tmp_data[0] = '\0';
-+		add_datastr(tmp_data, 0, app_data, appdatalen);
-+		pattern_result = ((comppattern && regexec(comppattern, tmp_data)) ? 1 : 0);
-+
-+		kfree(tmp_data);
-+		tmp_data = NULL;
-+		spin_unlock_bh(&l7_lock);
-+
-+		return (pattern_result ^ info->invert);
-+	}
-+
- 	/* On the first packet of a connection, allocate space for app data */
- 	if(total_acct_packets(master_conntrack) == 1 && !skb->cb[0] && 
- 	   !master_conntrack->layer7.app_data){
diff --git a/target/linux/generic/patches-2.6.38/602-netfilter_layer7_match.patch b/target/linux/generic/patches-2.6.38/602-netfilter_layer7_match.patch
deleted file mode 100644
index b2e48c824f..0000000000
--- a/target/linux/generic/patches-2.6.38/602-netfilter_layer7_match.patch
+++ /dev/null
@@ -1,51 +0,0 @@
---- a/net/netfilter/xt_layer7.c
-+++ b/net/netfilter/xt_layer7.c
-@@ -415,7 +415,9 @@ static int layer7_write_proc(struct file
- }
- 
- static bool
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
-+match(const struct sk_buff *skbin, struct xt_action_param *par)
-+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
- match(const struct sk_buff *skbin, const struct xt_match_param *par)
- #else
- match(const struct sk_buff *skbin,
-@@ -597,14 +599,19 @@ match(const struct sk_buff *skbin,
- }
- 
- // load nf_conntrack_ipv4
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
-+static int
-+#else
-+static bool
-+#endif
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
--static bool check(const struct xt_mtchk_param *par)
-+check(const struct xt_mtchk_param *par)
- {
-         if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
-                 printk(KERN_WARNING "can't load conntrack support for "
-                                     "proto=%d\n", par->match->family);
- #else
--static bool check(const char *tablename, const void *inf,
-+check(const char *tablename, const void *inf,
- 		 const struct xt_match *match, void *matchinfo,
- 		 unsigned int hook_mask)
- {
-@@ -612,9 +619,15 @@ static bool check(const char *tablename,
-                 printk(KERN_WARNING "can't load conntrack support for "
-                                     "proto=%d\n", match->family);
- #endif
-+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35)
-+		return -EINVAL;
-+	}
-+	return 0;
-+#else
-                 return 0;
-         }
- 	return 1;
-+#endif
- }
- 
- 
diff --git a/target/linux/generic/patches-2.6.38/603-netfilter_layer7_2.6.36_fix.patch b/target/linux/generic/patches-2.6.38/603-netfilter_layer7_2.6.36_fix.patch
deleted file mode 100644
index 14c5cc6982..0000000000
--- a/target/linux/generic/patches-2.6.38/603-netfilter_layer7_2.6.36_fix.patch
+++ /dev/null
@@ -1,61 +0,0 @@
---- a/net/netfilter/Kconfig
-+++ b/net/netfilter/Kconfig
-@@ -760,6 +760,27 @@ config NETFILTER_XT_MATCH_IPVS
- 
- 	  If unsure, say N.
- 
-+config NETFILTER_XT_MATCH_LAYER7
-+	tristate '"layer7" match support'
-+	depends on EXPERIMENTAL
-+	depends on NETFILTER_XTABLES
-+	depends on NETFILTER_ADVANCED
-+	depends on NF_CONNTRACK
-+	help
-+	  Say Y if you want to be able to classify connections (and their
-+	  packets) based on regular expression matching of their application
-+	  layer data.   This is one way to classify applications such as
-+	  peer-to-peer filesharing systems that do not always use the same
-+	  port.
-+
-+	  To compile it as a module, choose M here.  If unsure, say N.
-+
-+config NETFILTER_XT_MATCH_LAYER7_DEBUG
-+	bool 'Layer 7 debugging output'
-+	depends on NETFILTER_XT_MATCH_LAYER7
-+	help
-+	  Say Y to get lots of debugging output.
-+
- config NETFILTER_XT_MATCH_LENGTH
- 	tristate '"length" match support'
- 	depends on NETFILTER_ADVANCED
-@@ -946,26 +967,11 @@ config NETFILTER_XT_MATCH_STATE
- 
- 	  To compile it as a module, choose M here.  If unsure, say N.
- 
--config NETFILTER_XT_MATCH_LAYER7
--	tristate '"layer7" match support'
--	depends on NETFILTER_XTABLES
--	depends on EXPERIMENTAL && (IP_NF_CONNTRACK || NF_CONNTRACK)
--       depends on NETFILTER_ADVANCED
--	help
--	  Say Y if you want to be able to classify connections (and their
--	  packets) based on regular expression matching of their application
--	  layer data.   This is one way to classify applications such as
--	  peer-to-peer filesharing systems that do not always use the same
--	  port.
--
--	  To compile it as a module, choose M here.  If unsure, say N.
--
- config NETFILTER_XT_MATCH_LAYER7_DEBUG
--        bool 'Layer 7 debugging output'
--        depends on NETFILTER_XT_MATCH_LAYER7
--        help
--          Say Y to get lots of debugging output.
--
-+	bool 'Layer 7 debugging output'
-+	depends on NETFILTER_XT_MATCH_LAYER7
-+	help
-+	  Say Y to get lots of debugging output.
- 
- config NETFILTER_XT_MATCH_STATISTIC
- 	tristate '"statistic" match support'
diff --git a/target/linux/generic/patches-2.6.38/604-netfilter_cisco_794x_iphone.patch b/target/linux/generic/patches-2.6.38/604-netfilter_cisco_794x_iphone.patch
deleted file mode 100644
index 662a499d17..0000000000
--- a/target/linux/generic/patches-2.6.38/604-netfilter_cisco_794x_iphone.patch
+++ /dev/null
@@ -1,118 +0,0 @@
---- a/include/linux/netfilter/nf_conntrack_sip.h
-+++ b/include/linux/netfilter/nf_conntrack_sip.h
-@@ -2,12 +2,15 @@
- #define __NF_CONNTRACK_SIP_H__
- #ifdef __KERNEL__
- 
-+#include <linux/types.h>
-+
- #define SIP_PORT	5060
- #define SIP_TIMEOUT	3600
- 
- struct nf_ct_sip_master {
- 	unsigned int	register_cseq;
- 	unsigned int	invite_cseq;
-+	__be16		forced_dport;
- };
- 
- enum sip_expectation_classes {
---- a/net/ipv4/netfilter/nf_nat_sip.c
-+++ b/net/ipv4/netfilter/nf_nat_sip.c
-@@ -73,6 +73,7 @@ static int map_addr(struct sk_buff *skb,
- 	enum ip_conntrack_info ctinfo;
- 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
- 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
-+	struct nf_conn_help *help = nfct_help(ct);
- 	char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
- 	unsigned int buflen;
- 	__be32 newaddr;
-@@ -85,7 +86,8 @@ static int map_addr(struct sk_buff *skb,
- 	} else if (ct->tuplehash[dir].tuple.dst.u3.ip == addr->ip &&
- 		   ct->tuplehash[dir].tuple.dst.u.udp.port == port) {
- 		newaddr = ct->tuplehash[!dir].tuple.src.u3.ip;
--		newport = ct->tuplehash[!dir].tuple.src.u.udp.port;
-+		newport = help->help.ct_sip_info.forced_dport ? :
-+			  ct->tuplehash[!dir].tuple.src.u.udp.port;
- 	} else
- 		return 1;
- 
-@@ -121,6 +123,7 @@ static unsigned int ip_nat_sip(struct sk
- 	enum ip_conntrack_info ctinfo;
- 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
- 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
-+	struct nf_conn_help *help = nfct_help(ct);
- 	unsigned int coff, matchoff, matchlen;
- 	enum sip_header_types hdr;
- 	union nf_inet_addr addr;
-@@ -229,6 +232,20 @@ next:
- 	    !map_sip_addr(skb, dataoff, dptr, datalen, SIP_HDR_TO))
- 		return NF_DROP;
- 
-+	/* Mangle destination port for Cisco phones, then fix up checksums */
-+	if (dir == IP_CT_DIR_REPLY && help->help.ct_sip_info.forced_dport) {
-+		struct udphdr *uh;
-+
-+		if (!skb_make_writable(skb, skb->len))
-+			return NF_DROP;
-+
-+		uh = (struct udphdr *)(skb->data + ip_hdrlen(skb));
-+		uh->dest = help->help.ct_sip_info.forced_dport;
-+
-+		if (!nf_nat_mangle_udp_packet(skb, ct, ctinfo, 0, 0, NULL, 0))
-+			return NF_DROP;
-+	}
-+
- 	return NF_ACCEPT;
- }
- 
-@@ -280,8 +297,10 @@ static unsigned int ip_nat_sip_expect(st
- 	enum ip_conntrack_info ctinfo;
- 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
- 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
-+	struct nf_conn_help *help = nfct_help(ct);
- 	__be32 newip;
- 	u_int16_t port;
-+	__be16 srcport;
- 	char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
- 	unsigned buflen;
- 
-@@ -294,8 +313,9 @@ static unsigned int ip_nat_sip_expect(st
- 	/* If the signalling port matches the connection's source port in the
- 	 * original direction, try to use the destination port in the opposite
- 	 * direction. */
--	if (exp->tuple.dst.u.udp.port ==
--	    ct->tuplehash[dir].tuple.src.u.udp.port)
-+	srcport = help->help.ct_sip_info.forced_dport ? :
-+		  ct->tuplehash[dir].tuple.src.u.udp.port;
-+	if (exp->tuple.dst.u.udp.port == srcport)
- 		port = ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.port);
- 	else
- 		port = ntohs(exp->tuple.dst.u.udp.port);
---- a/net/netfilter/nf_conntrack_sip.c
-+++ b/net/netfilter/nf_conntrack_sip.c
-@@ -1363,8 +1363,25 @@ static int process_sip_request(struct sk
- {
- 	enum ip_conntrack_info ctinfo;
- 	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
-+	struct nf_conn_help *help = nfct_help(ct);
-+	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
- 	unsigned int matchoff, matchlen;
- 	unsigned int cseq, i;
-+	union nf_inet_addr addr;
-+	__be16 port;
-+
-+	/* Many Cisco IP phones use a high source port for SIP requests, but
-+	 * listen for the response on port 5060.  If we are the local
-+	 * router for one of these phones, save the port number from the
-+	 * Via: header so that nf_nat_sip can redirect the responses to
-+	 * the correct port.
-+	 */
-+	if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen,
-+				    SIP_HDR_VIA_UDP, NULL, &matchoff,
-+				    &matchlen, &addr, &port) > 0 &&
-+	    port != ct->tuplehash[dir].tuple.src.u.udp.port &&
-+	    nf_inet_addr_cmp(&addr, &ct->tuplehash[dir].tuple.src.u3))
-+		help->help.ct_sip_info.forced_dport = port;
- 
- 	for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
- 		const struct sip_handler *handler;
diff --git a/target/linux/generic/patches-2.6.38/606-netfilter_dscp_ipv6_mangle.patch b/target/linux/generic/patches-2.6.38/606-netfilter_dscp_ipv6_mangle.patch
deleted file mode 100644
index 670fd220ac..0000000000
--- a/target/linux/generic/patches-2.6.38/606-netfilter_dscp_ipv6_mangle.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
-Date: Tue, 10 May 2011 08:00:21 +0000 (+0200)
-Subject: netfilter: IPv6: fix DSCP mangle code
-X-Git-Tag: v2.6.39~15^2~13^2~1
-X-Git-Url: http://git390.marist.edu/cgi-bin/gitweb.cgi?p=linux-2.6.git;a=commitdiff_plain;h=1ed2f73d90fb49bcf5704aee7e9084adb882bfc5
-
-netfilter: IPv6: fix DSCP mangle code
-
-The mask indicates the bits one wants to zero out, so it needs to be
-inverted before applying to the original TOS field.
-
-Signed-off-by: Fernando Luis Vazquez Cao <fernando@oss.ntt.co.jp>
-Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
----
-
---- a/net/netfilter/xt_DSCP.c
-+++ b/net/netfilter/xt_DSCP.c
-@@ -99,7 +99,7 @@ tos_tg6(struct sk_buff *skb, const struc
- 	u_int8_t orig, nv;
- 
- 	orig = ipv6_get_dsfield(iph);
--	nv   = (orig & info->tos_mask) ^ info->tos_value;
-+	nv   = (orig & ~info->tos_mask) ^ info->tos_value;
- 
- 	if (orig != nv) {
- 		if (!skb_make_writable(skb, sizeof(struct iphdr)))
diff --git a/target/linux/generic/patches-2.6.38/620-sched_esfq.patch b/target/linux/generic/patches-2.6.38/620-sched_esfq.patch
deleted file mode 100644
index 8a648ecc4d..0000000000
--- a/target/linux/generic/patches-2.6.38/620-sched_esfq.patch
+++ /dev/null
@@ -1,795 +0,0 @@
---- a/include/linux/pkt_sched.h
-+++ b/include/linux/pkt_sched.h
-@@ -173,8 +173,37 @@ struct tc_sfq_xstats {
-  *
-  *	The only reason for this is efficiency, it is possible
-  *	to change these parameters in compile time.
-+ *
-+ *	If you need to play with these values, use esfq instead.
-  */
- 
-+/* ESFQ section */
-+
-+enum
-+{
-+        /* traditional */
-+	TCA_SFQ_HASH_CLASSIC,
-+	TCA_SFQ_HASH_DST,
-+	TCA_SFQ_HASH_SRC,
-+	TCA_SFQ_HASH_FWMARK,
-+	/* conntrack */
-+	TCA_SFQ_HASH_CTORIGDST,
-+	TCA_SFQ_HASH_CTORIGSRC,
-+	TCA_SFQ_HASH_CTREPLDST,
-+	TCA_SFQ_HASH_CTREPLSRC,
-+	TCA_SFQ_HASH_CTNATCHG,
-+};
-+
-+struct tc_esfq_qopt
-+{
-+	unsigned	quantum;	/* Bytes per round allocated to flow */
-+	int		perturb_period;	/* Period of hash perturbation */
-+	__u32		limit;		/* Maximal packets in queue */
-+	unsigned	divisor;	/* Hash divisor  */
-+	unsigned	flows;		/* Maximal number of flows  */
-+	unsigned	hash_kind;	/* Hash function to use for flow identification */
-+};
-+
- /* RED section */
- 
- enum {
---- a/net/sched/Kconfig
-+++ b/net/sched/Kconfig
-@@ -137,6 +137,37 @@ config NET_SCH_SFQ
- 	  To compile this code as a module, choose M here: the
- 	  module will be called sch_sfq.
- 
-+config NET_SCH_ESFQ
-+	tristate "Enhanced Stochastic Fairness Queueing (ESFQ)"
-+	---help---
-+	  Say Y here if you want to use the Enhanced Stochastic Fairness
-+	  Queueing (ESFQ) packet scheduling algorithm for some of your network
-+	  devices or as a leaf discipline for a classful qdisc such as HTB or
-+	  CBQ (see the top of <file:net/sched/sch_esfq.c> for details and
-+	  references to the SFQ algorithm).
-+
-+	  This is an enchanced SFQ version which allows you to control some
-+	  hardcoded values in the SFQ scheduler.
-+
-+	  ESFQ also adds control of the hash function used to identify packet
-+	  flows. The original SFQ discipline hashes by connection; ESFQ add
-+	  several other hashing methods, such as by src IP or by dst IP, which
-+	  can be more fair to users in some networking situations.
-+
-+	  To compile this code as a module, choose M here: the
-+	  module will be called sch_esfq.
-+
-+config NET_SCH_ESFQ_NFCT
-+	bool "Connection Tracking Hash Types"
-+	depends on NET_SCH_ESFQ && NF_CONNTRACK
-+	---help---
-+	  Say Y here to enable support for hashing based on netfilter connection
-+	  tracking information. This is useful for a router that is also using
-+	  NAT to connect privately-addressed hosts to the Internet. If you want
-+	  to provide fair distribution of upstream bandwidth, ESFQ must use
-+	  connection tracking information, since all outgoing packets will share
-+	  the same source address.
-+
- config NET_SCH_TEQL
- 	tristate "True Link Equalizer (TEQL)"
- 	---help---
---- a/net/sched/Makefile
-+++ b/net/sched/Makefile
-@@ -25,6 +25,7 @@ obj-$(CONFIG_NET_SCH_GRED)	+= sch_gred.o
- obj-$(CONFIG_NET_SCH_INGRESS)	+= sch_ingress.o 
- obj-$(CONFIG_NET_SCH_DSMARK)	+= sch_dsmark.o
- obj-$(CONFIG_NET_SCH_SFQ)	+= sch_sfq.o
-+obj-$(CONFIG_NET_SCH_ESFQ)	+= sch_esfq.o
- obj-$(CONFIG_NET_SCH_TBF)	+= sch_tbf.o
- obj-$(CONFIG_NET_SCH_TEQL)	+= sch_teql.o
- obj-$(CONFIG_NET_SCH_PRIO)	+= sch_prio.o
---- /dev/null
-+++ b/net/sched/sch_esfq.c
-@@ -0,0 +1,702 @@
-+/*
-+ * net/sched/sch_esfq.c	Extended Stochastic Fairness Queueing discipline.
-+ *
-+ *		This program is free software; you can redistribute it and/or
-+ *		modify it under the terms of the GNU General Public License
-+ *		as published by the Free Software Foundation; either version
-+ *		2 of the License, or (at your option) any later version.
-+ *
-+ * Authors:	Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
-+ *
-+ * Changes:	Alexander Atanasov, <alex@ssi.bg>
-+ *		Added dynamic depth,limit,divisor,hash_kind options.
-+ *		Added dst and src hashes.
-+ *
-+ * 		Alexander Clouter, <alex@digriz.org.uk>
-+ *		Ported ESFQ to Linux 2.6.
-+ *
-+ * 		Corey Hickey, <bugfood-c@fatooh.org>
-+ *		Maintenance of the Linux 2.6 port.
-+ *		Added fwmark hash (thanks to Robert Kurjata).
-+ *		Added usage of jhash.
-+ *		Added conntrack support.
-+ *		Added ctnatchg hash (thanks to Ben Pfountz).
-+ */
-+
-+#include <linux/module.h>
-+#include <asm/uaccess.h>
-+#include <asm/system.h>
-+#include <linux/bitops.h>
-+#include <linux/types.h>
-+#include <linux/kernel.h>
-+#include <linux/jiffies.h>
-+#include <linux/string.h>
-+#include <linux/mm.h>
-+#include <linux/socket.h>
-+#include <linux/sockios.h>
-+#include <linux/in.h>
-+#include <linux/errno.h>
-+#include <linux/interrupt.h>
-+#include <linux/if_ether.h>
-+#include <linux/inet.h>
-+#include <linux/netdevice.h>
-+#include <linux/etherdevice.h>
-+#include <linux/notifier.h>
-+#include <linux/init.h>
-+#include <net/ip.h>
-+#include <net/netlink.h>
-+#include <linux/ipv6.h>
-+#include <net/route.h>
-+#include <linux/skbuff.h>
-+#include <net/sock.h>
-+#include <net/pkt_sched.h>
-+#include <linux/jhash.h>
-+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
-+#include <net/netfilter/nf_conntrack.h>
-+#endif
-+
-+/*	Stochastic Fairness Queuing algorithm.
-+	For more comments look at sch_sfq.c.
-+	The difference is that you can change limit, depth,
-+	hash table size and choose alternate hash types.
-+
-+	classic:	same as in sch_sfq.c
-+	dst:		destination IP address
-+	src:		source IP address
-+	fwmark:		netfilter mark value
-+	ctorigdst:	original destination IP address
-+	ctorigsrc:	original source IP address
-+	ctrepldst:	reply destination IP address
-+	ctreplsrc:	reply source IP
-+
-+*/
-+
-+#define ESFQ_HEAD 0
-+#define ESFQ_TAIL 1
-+
-+/* This type should contain at least SFQ_DEPTH*2 values */
-+typedef unsigned int esfq_index;
-+
-+struct esfq_head
-+{
-+	esfq_index	next;
-+	esfq_index	prev;
-+};
-+
-+struct esfq_sched_data
-+{
-+/* Parameters */
-+	int		perturb_period;
-+	unsigned	quantum;	/* Allotment per round: MUST BE >= MTU */
-+	int		limit;
-+	unsigned	depth;
-+	unsigned	hash_divisor;
-+	unsigned	hash_kind;
-+/* Variables */
-+	struct timer_list perturb_timer;
-+	int		perturbation;
-+	esfq_index	tail;		/* Index of current slot in round */
-+	esfq_index	max_depth;	/* Maximal depth */
-+
-+	esfq_index	*ht;			/* Hash table */
-+	esfq_index	*next;			/* Active slots link */
-+	short		*allot;			/* Current allotment per slot */
-+	unsigned short	*hash;			/* Hash value indexed by slots */
-+	struct sk_buff_head	*qs;		/* Slot queue */
-+	struct esfq_head	*dep;		/* Linked list of slots, indexed by depth */
-+};
-+
-+/* This contains the info we will hash. */
-+struct esfq_packet_info
-+{
-+	u32	proto;		/* protocol or port */
-+	u32	src;		/* source from packet header */
-+	u32	dst;		/* destination from packet header */
-+	u32	ctorigsrc;	/* original source from conntrack */
-+	u32	ctorigdst;	/* original destination from conntrack */
-+	u32	ctreplsrc;	/* reply source from conntrack */
-+	u32	ctrepldst;	/* reply destination from conntrack */
-+	u32	mark;		/* netfilter mark (fwmark) */
-+};
-+
-+static __inline__ unsigned esfq_jhash_1word(struct esfq_sched_data *q,u32 a)
-+{
-+	return jhash_1word(a, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+static __inline__ unsigned esfq_jhash_2words(struct esfq_sched_data *q, u32 a, u32 b)
-+{
-+	return jhash_2words(a, b, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+static __inline__ unsigned esfq_jhash_3words(struct esfq_sched_data *q, u32 a, u32 b, u32 c)
-+{
-+	return jhash_3words(a, b, c, q->perturbation) & (q->hash_divisor-1);
-+}
-+
-+static unsigned esfq_hash(struct esfq_sched_data *q, struct sk_buff *skb)
-+{
-+	struct esfq_packet_info info;
-+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
-+	enum ip_conntrack_info ctinfo;
-+	struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
-+#endif
-+
-+	switch (skb->protocol) {
-+	case __constant_htons(ETH_P_IP):
-+	{
-+		struct iphdr *iph = ip_hdr(skb);
-+		info.dst = iph->daddr;
-+		info.src = iph->saddr;
-+		if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
-+		    (iph->protocol == IPPROTO_TCP ||
-+		     iph->protocol == IPPROTO_UDP ||
-+		     iph->protocol == IPPROTO_SCTP ||
-+		     iph->protocol == IPPROTO_DCCP ||
-+		     iph->protocol == IPPROTO_ESP))
-+			info.proto = *(((u32*)iph) + iph->ihl);
-+		else
-+			info.proto = iph->protocol;
-+		break;
-+	}
-+	case __constant_htons(ETH_P_IPV6):
-+	{
-+		struct ipv6hdr *iph = ipv6_hdr(skb);
-+		/* Hash ipv6 addresses into a u32. This isn't ideal,
-+		 * but the code is simple. */
-+		info.dst = jhash2(iph->daddr.s6_addr32, 4, q->perturbation);
-+		info.src = jhash2(iph->saddr.s6_addr32, 4, q->perturbation);
-+		if (iph->nexthdr == IPPROTO_TCP ||
-+		    iph->nexthdr == IPPROTO_UDP ||
-+		    iph->nexthdr == IPPROTO_SCTP ||
-+		    iph->nexthdr == IPPROTO_DCCP ||
-+		    iph->nexthdr == IPPROTO_ESP)
-+			info.proto = *(u32*)&iph[1];
-+		else
-+			info.proto = iph->nexthdr;
-+		break;
-+	}
-+	default:
-+		info.dst   = (u32)(unsigned long)skb_dst(skb);
-+		info.src   = (u32)(unsigned long)skb->sk;
-+		info.proto = skb->protocol;
-+	}
-+
-+	info.mark = skb->mark;
-+
-+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
-+	/* defaults if there is no conntrack info */
-+	info.ctorigsrc = info.src;
-+	info.ctorigdst = info.dst;
-+	info.ctreplsrc = info.dst;
-+	info.ctrepldst = info.src;
-+	/* collect conntrack info */
-+	if (ct && ct != &nf_conntrack_untracked) {
-+		if (skb->protocol == __constant_htons(ETH_P_IP)) {
-+			info.ctorigsrc = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
-+			info.ctorigdst = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip;
-+			info.ctreplsrc = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip;
-+			info.ctrepldst = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;
-+		}
-+		else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
-+			/* Again, hash ipv6 addresses into a single u32. */
-+			info.ctorigsrc = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip6, 4, q->perturbation);
-+			info.ctorigdst = jhash2(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3.ip6, 4, q->perturbation);
-+			info.ctreplsrc = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6, 4, q->perturbation);
-+			info.ctrepldst = jhash2(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6, 4, q->perturbation);
-+		}
-+
-+	}
-+#endif
-+
-+	switch(q->hash_kind) {
-+	case TCA_SFQ_HASH_CLASSIC:
-+		return esfq_jhash_3words(q, info.dst, info.src, info.proto);
-+	case TCA_SFQ_HASH_DST:
-+		return esfq_jhash_1word(q, info.dst);
-+	case TCA_SFQ_HASH_SRC:
-+		return esfq_jhash_1word(q, info.src);
-+	case TCA_SFQ_HASH_FWMARK:
-+		return esfq_jhash_1word(q, info.mark);
-+#ifdef CONFIG_NET_SCH_ESFQ_NFCT
-+	case TCA_SFQ_HASH_CTORIGDST:
-+		return esfq_jhash_1word(q, info.ctorigdst);
-+	case TCA_SFQ_HASH_CTORIGSRC:
-+		return esfq_jhash_1word(q, info.ctorigsrc);
-+	case TCA_SFQ_HASH_CTREPLDST:
-+		return esfq_jhash_1word(q, info.ctrepldst);
-+	case TCA_SFQ_HASH_CTREPLSRC:
-+		return esfq_jhash_1word(q, info.ctreplsrc);
-+	case TCA_SFQ_HASH_CTNATCHG:
-+	{
-+		if (info.ctorigdst == info.ctreplsrc)
-+			return esfq_jhash_1word(q, info.ctorigsrc);
-+		return esfq_jhash_1word(q, info.ctreplsrc);
-+	}
-+#endif
-+	default:
-+		if (net_ratelimit())
-+			printk(KERN_WARNING "ESFQ: Unknown hash method. Falling back to classic.\n");
-+	}
-+	return esfq_jhash_3words(q, info.dst, info.src, info.proto);
-+}
-+
-+static inline void esfq_link(struct esfq_sched_data *q, esfq_index x)
-+{
-+	esfq_index p, n;
-+	int d = q->qs[x].qlen + q->depth;
-+
-+	p = d;
-+	n = q->dep[d].next;
-+	q->dep[x].next = n;
-+	q->dep[x].prev = p;
-+	q->dep[p].next = q->dep[n].prev = x;
-+}
-+
-+static inline void esfq_dec(struct esfq_sched_data *q, esfq_index x)
-+{
-+	esfq_index p, n;
-+
-+	n = q->dep[x].next;
-+	p = q->dep[x].prev;
-+	q->dep[p].next = n;
-+	q->dep[n].prev = p;
-+
-+	if (n == p && q->max_depth == q->qs[x].qlen + 1)
-+		q->max_depth--;
-+
-+	esfq_link(q, x);
-+}
-+
-+static inline void esfq_inc(struct esfq_sched_data *q, esfq_index x)
-+{
-+	esfq_index p, n;
-+	int d;
-+
-+	n = q->dep[x].next;
-+	p = q->dep[x].prev;
-+	q->dep[p].next = n;
-+	q->dep[n].prev = p;
-+	d = q->qs[x].qlen;
-+	if (q->max_depth < d)
-+		q->max_depth = d;
-+
-+	esfq_link(q, x);
-+}
-+
-+static unsigned int esfq_drop(struct Qdisc *sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	esfq_index d = q->max_depth;
-+	struct sk_buff *skb;
-+	unsigned int len;
-+
-+	/* Queue is full! Find the longest slot and
-+	   drop a packet from it */
-+
-+	if (d > 1) {
-+		esfq_index x = q->dep[d+q->depth].next;
-+		skb = q->qs[x].prev;
-+		len = skb->len;
-+		__skb_unlink(skb, &q->qs[x]);
-+		kfree_skb(skb);
-+		esfq_dec(q, x);
-+		sch->q.qlen--;
-+		sch->qstats.drops++;
-+		sch->qstats.backlog -= len;
-+		return len;
-+	}
-+
-+	if (d == 1) {
-+		/* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */
-+		d = q->next[q->tail];
-+		q->next[q->tail] = q->next[d];
-+		q->allot[q->next[d]] += q->quantum;
-+		skb = q->qs[d].prev;
-+		len = skb->len;
-+		__skb_unlink(skb, &q->qs[d]);
-+		kfree_skb(skb);
-+		esfq_dec(q, d);
-+		sch->q.qlen--;
-+		q->ht[q->hash[d]] = q->depth;
-+		sch->qstats.drops++;
-+		sch->qstats.backlog -= len;
-+		return len;
-+	}
-+
-+	return 0;
-+}
-+
-+static void esfq_q_enqueue(struct sk_buff *skb, struct esfq_sched_data *q, unsigned int end)
-+{
-+	unsigned hash = esfq_hash(q, skb);
-+	unsigned depth = q->depth;
-+	esfq_index x;
-+
-+	x = q->ht[hash];
-+	if (x == depth) {
-+		q->ht[hash] = x = q->dep[depth].next;
-+		q->hash[x] = hash;
-+	}
-+
-+	if (end == ESFQ_TAIL)
-+		__skb_queue_tail(&q->qs[x], skb);
-+	else
-+		__skb_queue_head(&q->qs[x], skb);
-+
-+	esfq_inc(q, x);
-+	if (q->qs[x].qlen == 1) {		/* The flow is new */
-+		if (q->tail == depth) {	/* It is the first flow */
-+			q->tail = x;
-+			q->next[x] = x;
-+			q->allot[x] = q->quantum;
-+		} else {
-+			q->next[x] = q->next[q->tail];
-+			q->next[q->tail] = x;
-+			q->tail = x;
-+		}
-+	}
-+}
-+
-+static int esfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	esfq_q_enqueue(skb, q, ESFQ_TAIL);
-+	sch->qstats.backlog += skb->len;
-+	if (++sch->q.qlen < q->limit-1) {
-+		sch->bstats.bytes += skb->len;
-+		sch->bstats.packets++;
-+		return 0;
-+	}
-+
-+	sch->qstats.drops++;
-+	esfq_drop(sch);
-+	return NET_XMIT_CN;
-+}
-+
-+static struct sk_buff *esfq_peek(struct Qdisc* sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	esfq_index a;
-+
-+	/* No active slots */
-+	if (q->tail == q->depth)
-+		return NULL;
-+
-+	a = q->next[q->tail];
-+	return skb_peek(&q->qs[a]);
-+}
-+
-+static struct sk_buff *esfq_q_dequeue(struct esfq_sched_data *q)
-+{
-+	struct sk_buff *skb;
-+	unsigned depth = q->depth;
-+	esfq_index a, old_a;
-+
-+	/* No active slots */
-+	if (q->tail == depth)
-+		return NULL;
-+
-+	a = old_a = q->next[q->tail];
-+
-+	/* Grab packet */
-+	skb = __skb_dequeue(&q->qs[a]);
-+	esfq_dec(q, a);
-+
-+	/* Is the slot empty? */
-+	if (q->qs[a].qlen == 0) {
-+		q->ht[q->hash[a]] = depth;
-+		a = q->next[a];
-+		if (a == old_a) {
-+			q->tail = depth;
-+			return skb;
-+		}
-+		q->next[q->tail] = a;
-+		q->allot[a] += q->quantum;
-+	} else if ((q->allot[a] -= skb->len) <= 0) {
-+		q->tail = a;
-+		a = q->next[a];
-+		q->allot[a] += q->quantum;
-+	}
-+
-+	return skb;
-+}
-+
-+static struct sk_buff *esfq_dequeue(struct Qdisc* sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	struct sk_buff *skb;
-+
-+	skb = esfq_q_dequeue(q);
-+	if (skb == NULL)
-+		return NULL;
-+	sch->q.qlen--;
-+	sch->qstats.backlog -= skb->len;
-+	return skb;
-+}
-+
-+static void esfq_q_destroy(struct esfq_sched_data *q)
-+{
-+	del_timer(&q->perturb_timer);
-+	if(q->ht)
-+		kfree(q->ht);
-+	if(q->dep)
-+		kfree(q->dep);
-+	if(q->next)
-+		kfree(q->next);
-+	if(q->allot)
-+		kfree(q->allot);
-+	if(q->hash)
-+		kfree(q->hash);
-+	if(q->qs)
-+		kfree(q->qs);
-+}
-+
-+static void esfq_destroy(struct Qdisc *sch)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	esfq_q_destroy(q);
-+}
-+
-+
-+static void esfq_reset(struct Qdisc* sch)
-+{
-+	struct sk_buff *skb;
-+
-+	while ((skb = esfq_dequeue(sch)) != NULL)
-+		kfree_skb(skb);
-+}
-+
-+static void esfq_perturbation(unsigned long arg)
-+{
-+	struct Qdisc *sch = (struct Qdisc*)arg;
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+
-+	q->perturbation = net_random()&0x1F;
-+
-+	if (q->perturb_period) {
-+		q->perturb_timer.expires = jiffies + q->perturb_period;
-+		add_timer(&q->perturb_timer);
-+	}
-+}
-+
-+static unsigned int esfq_check_hash(unsigned int kind)
-+{
-+	switch (kind) {
-+	case TCA_SFQ_HASH_CTORIGDST:
-+	case TCA_SFQ_HASH_CTORIGSRC:
-+	case TCA_SFQ_HASH_CTREPLDST:
-+	case TCA_SFQ_HASH_CTREPLSRC:
-+	case TCA_SFQ_HASH_CTNATCHG:
-+#ifndef CONFIG_NET_SCH_ESFQ_NFCT
-+	{
-+		if (net_ratelimit())
-+			printk(KERN_WARNING "ESFQ: Conntrack hash types disabled in kernel config. Falling back to classic.\n");
-+		return TCA_SFQ_HASH_CLASSIC;
-+	}
-+#endif
-+	case TCA_SFQ_HASH_CLASSIC:
-+	case TCA_SFQ_HASH_DST:
-+	case TCA_SFQ_HASH_SRC:
-+	case TCA_SFQ_HASH_FWMARK:
-+		return kind;
-+	default:
-+	{
-+		if (net_ratelimit())
-+			printk(KERN_WARNING "ESFQ: Unknown hash type. Falling back to classic.\n");
-+		return TCA_SFQ_HASH_CLASSIC;
-+	}
-+	}
-+}
-+
-+static int esfq_q_init(struct esfq_sched_data *q, struct nlattr *opt)
-+{
-+	struct tc_esfq_qopt *ctl = nla_data(opt);
-+	esfq_index p = ~0U/2;
-+	int i;
-+
-+	if (opt && opt->nla_len < nla_attr_size(sizeof(*ctl)))
-+		return -EINVAL;
-+
-+	q->perturbation = 0;
-+	q->hash_kind = TCA_SFQ_HASH_CLASSIC;
-+	q->max_depth = 0;
-+	if (opt == NULL) {
-+		q->perturb_period = 0;
-+		q->hash_divisor = 1024;
-+		q->tail = q->limit = q->depth = 128;
-+
-+	} else {
-+		struct tc_esfq_qopt *ctl = nla_data(opt);
-+		if (ctl->quantum)
-+			q->quantum = ctl->quantum;
-+		q->perturb_period = ctl->perturb_period*HZ;
-+		q->hash_divisor = ctl->divisor ? : 1024;
-+		q->tail = q->limit = q->depth = ctl->flows ? : 128;
-+
-+		if ( q->depth > p - 1 )
-+			return -EINVAL;
-+
-+		if (ctl->limit)
-+			q->limit = min_t(u32, ctl->limit, q->depth);
-+
-+		if (ctl->hash_kind) {
-+			q->hash_kind = esfq_check_hash(ctl->hash_kind);
-+		}
-+	}
-+
-+	q->ht = kmalloc(q->hash_divisor*sizeof(esfq_index), GFP_KERNEL);
-+	if (!q->ht)
-+		goto err_case;
-+	q->dep = kmalloc((1+q->depth*2)*sizeof(struct esfq_head), GFP_KERNEL);
-+	if (!q->dep)
-+		goto err_case;
-+	q->next = kmalloc(q->depth*sizeof(esfq_index), GFP_KERNEL);
-+	if (!q->next)
-+		goto err_case;
-+	q->allot = kmalloc(q->depth*sizeof(short), GFP_KERNEL);
-+	if (!q->allot)
-+		goto err_case;
-+	q->hash = kmalloc(q->depth*sizeof(unsigned short), GFP_KERNEL);
-+	if (!q->hash)
-+		goto err_case;
-+	q->qs = kmalloc(q->depth*sizeof(struct sk_buff_head), GFP_KERNEL);
-+	if (!q->qs)
-+		goto err_case;
-+
-+	for (i=0; i< q->hash_divisor; i++)
-+		q->ht[i] = q->depth;
-+	for (i=0; i<q->depth; i++) {
-+		skb_queue_head_init(&q->qs[i]);
-+		q->dep[i+q->depth].next = i+q->depth;
-+		q->dep[i+q->depth].prev = i+q->depth;
-+	}
-+
-+	for (i=0; i<q->depth; i++)
-+		esfq_link(q, i);
-+	return 0;
-+err_case:
-+	esfq_q_destroy(q);
-+	return -ENOBUFS;
-+}
-+
-+static int esfq_init(struct Qdisc *sch, struct nlattr *opt)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	int err;
-+
-+	q->quantum = psched_mtu(qdisc_dev(sch)); /* default */
-+	if ((err = esfq_q_init(q, opt)))
-+		return err;
-+
-+	init_timer(&q->perturb_timer);
-+	q->perturb_timer.data = (unsigned long)sch;
-+	q->perturb_timer.function = esfq_perturbation;
-+	if (q->perturb_period) {
-+		q->perturb_timer.expires = jiffies + q->perturb_period;
-+		add_timer(&q->perturb_timer);
-+	}
-+
-+	return 0;
-+}
-+
-+static int esfq_change(struct Qdisc *sch, struct nlattr *opt)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	struct esfq_sched_data new;
-+	struct sk_buff *skb;
-+	int err;
-+
-+	/* set up new queue */
-+	memset(&new, 0, sizeof(struct esfq_sched_data));
-+	new.quantum = psched_mtu(qdisc_dev(sch)); /* default */
-+	if ((err = esfq_q_init(&new, opt)))
-+		return err;
-+
-+	/* copy all packets from the old queue to the new queue */
-+	sch_tree_lock(sch);
-+	while ((skb = esfq_q_dequeue(q)) != NULL)
-+		esfq_q_enqueue(skb, &new, ESFQ_TAIL);
-+
-+	/* clean up the old queue */
-+	esfq_q_destroy(q);
-+
-+	/* copy elements of the new queue into the old queue */
-+	q->perturb_period = new.perturb_period;
-+	q->quantum        = new.quantum;
-+	q->limit          = new.limit;
-+	q->depth          = new.depth;
-+	q->hash_divisor   = new.hash_divisor;
-+	q->hash_kind      = new.hash_kind;
-+	q->tail           = new.tail;
-+	q->max_depth      = new.max_depth;
-+	q->ht    = new.ht;
-+	q->dep   = new.dep;
-+	q->next  = new.next;
-+	q->allot = new.allot;
-+	q->hash  = new.hash;
-+	q->qs    = new.qs;
-+
-+	/* finish up */
-+	if (q->perturb_period) {
-+		q->perturb_timer.expires = jiffies + q->perturb_period;
-+		add_timer(&q->perturb_timer);
-+	} else {
-+		q->perturbation = 0;
-+	}
-+	sch_tree_unlock(sch);
-+	return 0;
-+}
-+
-+static int esfq_dump(struct Qdisc *sch, struct sk_buff *skb)
-+{
-+	struct esfq_sched_data *q = qdisc_priv(sch);
-+	unsigned char *b = skb_tail_pointer(skb);
-+	struct tc_esfq_qopt opt;
-+
-+	opt.quantum = q->quantum;
-+	opt.perturb_period = q->perturb_period/HZ;
-+
-+	opt.limit = q->limit;
-+	opt.divisor = q->hash_divisor;
-+	opt.flows = q->depth;
-+	opt.hash_kind = q->hash_kind;
-+
-+	NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
-+
-+	return skb->len;
-+
-+nla_put_failure:
-+	nlmsg_trim(skb, b);
-+	return -1;
-+}
-+
-+static struct Qdisc_ops esfq_qdisc_ops =
-+{
-+	.next		=	NULL,
-+	.cl_ops		=	NULL,
-+	.id		=	"esfq",
-+	.priv_size	=	sizeof(struct esfq_sched_data),
-+	.enqueue	=	esfq_enqueue,
-+	.dequeue	=	esfq_dequeue,
-+	.peek		=	esfq_peek,
-+	.drop		=	esfq_drop,
-+	.init		=	esfq_init,
-+	.reset		=	esfq_reset,
-+	.destroy	=	esfq_destroy,
-+	.change		=	esfq_change,
-+	.dump		=	esfq_dump,
-+	.owner		=	THIS_MODULE,
-+};
-+
-+static int __init esfq_module_init(void)
-+{
-+	return register_qdisc(&esfq_qdisc_ops);
-+}
-+static void __exit esfq_module_exit(void)
-+{
-+	unregister_qdisc(&esfq_qdisc_ops);
-+}
-+module_init(esfq_module_init)
-+module_exit(esfq_module_exit)
-+MODULE_LICENSE("GPL");
diff --git a/target/linux/generic/patches-2.6.38/621-sched_act_connmark.patch b/target/linux/generic/patches-2.6.38/621-sched_act_connmark.patch
deleted file mode 100644
index 7df4b72609..0000000000
--- a/target/linux/generic/patches-2.6.38/621-sched_act_connmark.patch
+++ /dev/null
@@ -1,172 +0,0 @@
---- /dev/null
-+++ b/net/sched/act_connmark.c
-@@ -0,0 +1,137 @@
-+/*
-+ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify it
-+ * under the terms and conditions of the GNU General Public License,
-+ * version 2, as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope it will be useful, but WITHOUT
-+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-+ * more details.
-+ *
-+ * You should have received a copy of the GNU General Public License along with
-+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-+ * Place - Suite 330, Boston, MA 02111-1307 USA.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/init.h>
-+#include <linux/kernel.h>
-+#include <linux/skbuff.h>
-+#include <linux/rtnetlink.h>
-+#include <linux/pkt_cls.h>
-+#include <linux/ip.h>
-+#include <linux/ipv6.h>
-+#include <net/netlink.h>
-+#include <net/pkt_sched.h>
-+#include <net/act_api.h>
-+
-+#include <net/netfilter/nf_conntrack.h>
-+#include <net/netfilter/nf_conntrack_core.h>
-+
-+#define TCA_ACT_CONNMARK	20
-+
-+#define CONNMARK_TAB_MASK     3
-+static struct tcf_common *tcf_connmark_ht[CONNMARK_TAB_MASK + 1];
-+static u32 connmark_idx_gen;
-+static DEFINE_RWLOCK(connmark_lock);
-+
-+static struct tcf_hashinfo connmark_hash_info = {
-+	.htab	=	tcf_connmark_ht,
-+	.hmask	=	CONNMARK_TAB_MASK,
-+	.lock	=	&connmark_lock,
-+};
-+
-+static int tcf_connmark(struct sk_buff *skb, struct tc_action *a,
-+		       struct tcf_result *res)
-+{
-+	struct nf_conn *c;
-+	enum ip_conntrack_info ctinfo;
-+	int proto;
-+	int r;
-+
-+	if (skb->protocol == htons(ETH_P_IP)) {
-+		if (skb->len < sizeof(struct iphdr))
-+			goto out;
-+		proto = PF_INET;
-+	} else if (skb->protocol == htons(ETH_P_IPV6)) {
-+		if (skb->len < sizeof(struct ipv6hdr))
-+			goto out;
-+		proto = PF_INET6;
-+	} else
-+		goto out;
-+
-+	r = nf_conntrack_in(dev_net(skb->dev), proto, NF_INET_PRE_ROUTING, skb);
-+	if (r != NF_ACCEPT)
-+		goto out;
-+
-+	c = nf_ct_get(skb, &ctinfo);
-+	if (!c)
-+		goto out;
-+
-+	skb->mark = c->mark;
-+	nf_conntrack_put(skb->nfct);
-+	skb->nfct = NULL;
-+
-+out:
-+	return TC_ACT_PIPE;
-+}
-+
-+static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est,
-+			 struct tc_action *a, int ovr, int bind)
-+{
-+	struct tcf_common *pc;
-+
-+	pc = tcf_hash_create(0, est, a, sizeof(*pc), bind,
-+			     &connmark_idx_gen, &connmark_hash_info);
-+	if (IS_ERR(pc))
-+	    return PTR_ERR(pc);
-+
-+	tcf_hash_insert(pc, &connmark_hash_info);
-+
-+	return ACT_P_CREATED;
-+}
-+
-+static inline int tcf_connmark_cleanup(struct tc_action *a, int bind)
-+{
-+	if (a->priv)
-+		return tcf_hash_release(a->priv, bind, &connmark_hash_info);
-+	return 0;
-+}
-+
-+static inline int tcf_connmark_dump(struct sk_buff *skb, struct tc_action *a,
-+				int bind, int ref)
-+{
-+	return skb->len;
-+}
-+
-+static struct tc_action_ops act_connmark_ops = {
-+	.kind		=	"connmark",
-+	.hinfo		=	&connmark_hash_info,
-+	.type		=	TCA_ACT_CONNMARK,
-+	.capab		=	TCA_CAP_NONE,
-+	.owner		=	THIS_MODULE,
-+	.act		=	tcf_connmark,
-+	.dump		=	tcf_connmark_dump,
-+	.cleanup	=	tcf_connmark_cleanup,
-+	.init		=	tcf_connmark_init,
-+	.walk		=	tcf_generic_walker,
-+};
-+
-+MODULE_AUTHOR("Felix Fietkau <nbd@openwrt.org>");
-+MODULE_DESCRIPTION("Connection tracking mark restoring");
-+MODULE_LICENSE("GPL");
-+
-+static int __init connmark_init_module(void)
-+{
-+	return tcf_register_action(&act_connmark_ops);
-+}
-+
-+static void __exit connmark_cleanup_module(void)
-+{
-+	tcf_unregister_action(&act_connmark_ops);
-+}
-+
-+module_init(connmark_init_module);
-+module_exit(connmark_cleanup_module);
---- a/net/sched/Kconfig
-+++ b/net/sched/Kconfig
-@@ -559,6 +559,19 @@ config NET_ACT_CSUM
- 	  To compile this code as a module, choose M here: the
- 	  module will be called act_csum.
- 
-+config NET_ACT_CONNMARK
-+        tristate "Connection Tracking Marking"
-+        depends on NET_CLS_ACT
-+        depends on NF_CONNTRACK
-+        depends on NF_CONNTRACK_MARK
-+        ---help---
-+	  Say Y here to restore the connmark from a scheduler action
-+
-+	  If unsure, say N.
-+
-+	  To compile this code as a module, choose M here: the
-+	  module will be called act_connmark.
-+
- config NET_CLS_IND
- 	bool "Incoming device classification"
- 	depends on NET_CLS_U32 || NET_CLS_FW
---- a/net/sched/Makefile
-+++ b/net/sched/Makefile
-@@ -16,6 +16,7 @@ obj-$(CONFIG_NET_ACT_PEDIT)	+= act_pedit
- obj-$(CONFIG_NET_ACT_SIMP)	+= act_simple.o
- obj-$(CONFIG_NET_ACT_SKBEDIT)	+= act_skbedit.o
- obj-$(CONFIG_NET_ACT_CSUM)	+= act_csum.o
-+obj-$(CONFIG_NET_ACT_CONNMARK)	+= act_connmark.o
- obj-$(CONFIG_NET_SCH_FIFO)	+= sch_fifo.o
- obj-$(CONFIG_NET_SCH_CBQ)	+= sch_cbq.o
- obj-$(CONFIG_NET_SCH_HTB)	+= sch_htb.o
diff --git a/target/linux/generic/patches-2.6.38/622-sched_sfq_fix_enqueue.patch b/target/linux/generic/patches-2.6.38/622-sched_sfq_fix_enqueue.patch
deleted file mode 100644
index b849106873..0000000000
--- a/target/linux/generic/patches-2.6.38/622-sched_sfq_fix_enqueue.patch
+++ /dev/null
@@ -1,41 +0,0 @@
-From: Eric Dumazet <eric.dumazet@gmail.com>
-Date: Fri, 29 Jul 2011 19:22:42 +0000 (+0000)
-Subject: sch_sfq: fix sfq_enqueue()
-X-Git-Tag: v3.1-rc1~24^2~29
-X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Ftorvalds%2Flinux-2.6.git;a=commitdiff_plain;h=e1738bd9cecc5c867b0e2996470c1ff20f66ba79
-
-sch_sfq: fix sfq_enqueue()
-
-commit 8efa88540635 (sch_sfq: avoid giving spurious NET_XMIT_CN signals)
-forgot to call qdisc_tree_decrease_qlen() to signal upper levels that a
-packet (from another flow) was dropped, leading to various problems.
-
-With help from Michal Soltys and Michal Pokrywka, who did a bisection.
-
-Bugzilla ref: https://bugzilla.kernel.org/show_bug.cgi?id=39372
-Debian ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=631945
-
-Reported-by: Lucas Bocchi <lucas.bocchi@gmail.com>
-Reported-and-bisected-by: Michal Pokrywka <wolfmoon@o2.pl>
-Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
-CC: Michal Soltys <soltys@ziu.info>
-Acked-by: Patrick McHardy <kaber@trash.net>
-Signed-off-by: David S. Miller <davem@davemloft.net>
----
-
---- a/net/sched/sch_sfq.c
-+++ b/net/sched/sch_sfq.c
-@@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct
- 	/* Return Congestion Notification only if we dropped a packet
- 	 * from this flow.
- 	 */
--	return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS;
-+	if (qlen != slot->qlen)
-+		return NET_XMIT_CN;
-+
-+	/* As we dropped a packet, better let upper stack know this */
-+	qdisc_tree_decrease_qlen(sch, 1);
-+	return NET_XMIT_SUCCESS;
- }
- 
- static struct sk_buff *
diff --git a/target/linux/generic/patches-2.6.38/630-packet_socket_type.patch b/target/linux/generic/patches-2.6.38/630-packet_socket_type.patch
deleted file mode 100644
index a8ad9171ec..0000000000
--- a/target/linux/generic/patches-2.6.38/630-packet_socket_type.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-This patch allows the user to specify desired packet types (outgoing,
-broadcast, unicast, etc.) on packet sockets via setsockopt.
-This can reduce the load in situations where only a limited number
-of packet types are necessary
-
-Signed-off-by: Felix Fietkau <nbd@openwrt.org>
-
---- a/include/linux/if_packet.h
-+++ b/include/linux/if_packet.h
-@@ -29,6 +29,8 @@ struct sockaddr_ll {
- /* These ones are invisible by user level */
- #define PACKET_LOOPBACK		5		/* MC/BRD frame looped back */
- #define PACKET_FASTROUTE	6		/* Fastrouted frame	*/
-+#define PACKET_MASK_ANY		0xffffffff	/* mask for packet type bits */
-+
- 
- /* Packet socket options */
- 
-@@ -49,6 +51,7 @@ struct sockaddr_ll {
- #define PACKET_VNET_HDR			15
- #define PACKET_TX_TIMESTAMP		16
- #define PACKET_TIMESTAMP		17
-+#define PACKET_RECV_TYPE		18
- 
- struct tpacket_stats {
- 	unsigned int	tp_packets;
---- a/net/packet/af_packet.c
-+++ b/net/packet/af_packet.c
-@@ -211,6 +211,7 @@ struct packet_sock {
- 	unsigned int		tp_loss:1;
- 	unsigned int		tp_tstamp;
- 	struct packet_type	prot_hook ____cacheline_aligned_in_smp;
-+	unsigned int		pkt_type;
- };
- 
- struct packet_skb_cb {
-@@ -355,6 +356,7 @@ static int packet_rcv_spkt(struct sk_buf
- {
- 	struct sock *sk;
- 	struct sockaddr_pkt *spkt;
-+	struct packet_sock *po;
- 
- 	/*
- 	 *	When we registered the protocol we saved the socket in the data
-@@ -362,6 +364,7 @@ static int packet_rcv_spkt(struct sk_buf
- 	 */
- 
- 	sk = pt->af_packet_priv;
-+	po = pkt_sk(sk);
- 
- 	/*
- 	 *	Yank back the headers [hope the device set this
-@@ -374,7 +377,7 @@ static int packet_rcv_spkt(struct sk_buf
- 	 *	so that this procedure is noop.
- 	 */
- 
--	if (skb->pkt_type == PACKET_LOOPBACK)
-+	if (!(po->pkt_type & (1 << skb->pkt_type)))
- 		goto out;
- 
- 	if (!net_eq(dev_net(dev), sock_net(sk)))
-@@ -554,12 +557,12 @@ static int packet_rcv(struct sk_buff *sk
- 	int skb_len = skb->len;
- 	unsigned int snaplen, res;
- 
--	if (skb->pkt_type == PACKET_LOOPBACK)
--		goto drop;
--
- 	sk = pt->af_packet_priv;
- 	po = pkt_sk(sk);
- 
-+	if (!(po->pkt_type & (1 << skb->pkt_type)))
-+		goto drop;
-+
- 	if (!net_eq(dev_net(dev), sock_net(sk)))
- 		goto drop;
- 
-@@ -675,12 +678,12 @@ static int tpacket_rcv(struct sk_buff *s
- 	struct timespec ts;
- 	struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb);
- 
--	if (skb->pkt_type == PACKET_LOOPBACK)
--		goto drop;
--
- 	sk = pt->af_packet_priv;
- 	po = pkt_sk(sk);
- 
-+	if (!(po->pkt_type & (1 << skb->pkt_type)))
-+		goto drop;
-+
- 	if (!net_eq(dev_net(dev), sock_net(sk)))
- 		goto drop;
- 
-@@ -1500,6 +1503,7 @@ static int packet_create(struct net *net
- 	spin_lock_init(&po->bind_lock);
- 	mutex_init(&po->pg_vec_lock);
- 	po->prot_hook.func = packet_rcv;
-+	po->pkt_type = PACKET_MASK_ANY & ~(1 << PACKET_LOOPBACK);
- 
- 	if (sock->type == SOCK_PACKET)
- 		po->prot_hook.func = packet_rcv_spkt;
-@@ -2068,6 +2072,16 @@ packet_setsockopt(struct socket *sock, i
- 		po->tp_tstamp = val;
- 		return 0;
- 	}
-+        case PACKET_RECV_TYPE:
-+        {
-+                unsigned int val;
-+                if (optlen != sizeof(val))
-+                        return -EINVAL;
-+                if (copy_from_user(&val, optval, sizeof(val)))
-+                        return -EFAULT;
-+                po->pkt_type = val & ~PACKET_LOOPBACK;
-+                return 0;
-+        }
- 	default:
- 		return -ENOPROTOOPT;
- 	}
-@@ -2125,6 +2139,13 @@ static int packet_getsockopt(struct sock
- 
- 		data = &val;
- 		break;
-+	case PACKET_RECV_TYPE:
-+		if (len > sizeof(unsigned int))
-+			len = sizeof(unsigned int);
-+		val = po->pkt_type;
-+
-+		data = &val;
-+		break;
- 	case PACKET_VERSION:
- 		if (len > sizeof(int))
- 			len = sizeof(int);
diff --git a/target/linux/generic/patches-2.6.38/640-bridge_no_eap_forward.patch b/target/linux/generic/patches-2.6.38/640-bridge_no_eap_forward.patch
deleted file mode 100644
index dac898276d..0000000000
--- a/target/linux/generic/patches-2.6.38/640-bridge_no_eap_forward.patch
+++ /dev/null
@@ -1,15 +0,0 @@
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -77,7 +77,11 @@ int br_handle_frame_finish(struct sk_buf
- 
- 	dst = NULL;
- 
--	if (is_multicast_ether_addr(dest)) {
-+	if (skb->protocol == htons(ETH_P_PAE)) {
-+		skb2 = skb;
-+		/* Do not forward 802.1x/EAP frames */
-+		skb = NULL;
-+	} else if (is_multicast_ether_addr(dest)) {
- 		mdst = br_mdb_get(br, skb);
- 		if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
- 			if ((mdst && mdst->mglist) ||
diff --git a/target/linux/generic/patches-2.6.38/641-bridge_always_accept_eap.patch b/target/linux/generic/patches-2.6.38/641-bridge_always_accept_eap.patch
deleted file mode 100644
index b3a793e49b..0000000000
--- a/target/linux/generic/patches-2.6.38/641-bridge_always_accept_eap.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -64,7 +64,7 @@ int br_handle_frame_finish(struct sk_buf
- 	    br_multicast_rcv(br, p, skb))
- 		goto drop;
- 
--	if (p->state == BR_STATE_LEARNING)
-+	if ((p->state == BR_STATE_LEARNING) && skb->protocol != htons(ETH_P_PAE))
- 		goto drop;
- 
- 	BR_INPUT_SKB_CB(skb)->brdev = br->dev;
diff --git a/target/linux/generic/patches-2.6.38/642-bridge_port_isolate.patch b/target/linux/generic/patches-2.6.38/642-bridge_port_isolate.patch
deleted file mode 100644
index c051a29f2d..0000000000
--- a/target/linux/generic/patches-2.6.38/642-bridge_port_isolate.patch
+++ /dev/null
@@ -1,103 +0,0 @@
---- a/net/bridge/br_private.h
-+++ b/net/bridge/br_private.h
-@@ -132,6 +132,7 @@ struct net_bridge_port
- 
- 	unsigned long 			flags;
- #define BR_HAIRPIN_MODE		0x00000001
-+#define BR_ISOLATE_MODE		0x00000002
- 
- #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
- 	u32				multicast_startup_queries_sent;
---- a/net/bridge/br_sysfs_if.c
-+++ b/net/bridge/br_sysfs_if.c
-@@ -159,6 +159,22 @@ static ssize_t store_hairpin_mode(struct
- static BRPORT_ATTR(hairpin_mode, S_IRUGO | S_IWUSR,
- 		   show_hairpin_mode, store_hairpin_mode);
- 
-+static ssize_t show_isolate_mode(struct net_bridge_port *p, char *buf)
-+{
-+	int isolate_mode = (p->flags & BR_ISOLATE_MODE) ? 1 : 0;
-+	return sprintf(buf, "%d\n", isolate_mode);
-+}
-+static ssize_t store_isolate_mode(struct net_bridge_port *p, unsigned long v)
-+{
-+	if (v)
-+		p->flags |= BR_ISOLATE_MODE;
-+	else
-+		p->flags &= ~BR_ISOLATE_MODE;
-+	return 0;
-+}
-+static BRPORT_ATTR(isolate_mode, S_IRUGO | S_IWUSR,
-+		   show_isolate_mode, store_isolate_mode);
-+
- #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
- static ssize_t show_multicast_router(struct net_bridge_port *p, char *buf)
- {
-@@ -191,6 +207,7 @@ static struct brport_attribute *brport_a
- 	&brport_attr_hold_timer,
- 	&brport_attr_flush,
- 	&brport_attr_hairpin_mode,
-+	&brport_attr_isolate_mode,
- #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
- 	&brport_attr_multicast_router,
- #endif
---- a/net/bridge/br_input.c
-+++ b/net/bridge/br_input.c
-@@ -95,7 +95,8 @@ int br_handle_frame_finish(struct sk_buf
- 			skb2 = skb;
- 
- 		br->dev->stats.multicast++;
--	} else if ((dst = __br_fdb_get(br, dest)) && dst->is_local) {
-+	} else if ((p->flags & BR_ISOLATE_MODE) ||
-+		   ((dst = __br_fdb_get(br, dest)) && dst->is_local)) {
- 		skb2 = skb;
- 		/* Do not forward the packet since it's local. */
- 		skb = NULL;
---- a/net/bridge/br_forward.c
-+++ b/net/bridge/br_forward.c
-@@ -109,7 +109,7 @@ void br_deliver(const struct net_bridge_
- /* called with rcu_read_lock */
- void br_forward(const struct net_bridge_port *to, struct sk_buff *skb, struct sk_buff *skb0)
- {
--	if (should_deliver(to, skb)) {
-+	if (should_deliver(to, skb) && !(to->flags & BR_ISOLATE_MODE)) {
- 		if (skb0)
- 			deliver_clone(to, skb, __br_forward);
- 		else
-@@ -164,7 +164,8 @@ out:
- static void br_flood(struct net_bridge *br, struct sk_buff *skb,
- 		     struct sk_buff *skb0,
- 		     void (*__packet_hook)(const struct net_bridge_port *p,
--					   struct sk_buff *skb))
-+					   struct sk_buff *skb),
-+		     bool forward)
- {
- 	struct net_bridge_port *p;
- 	struct net_bridge_port *prev;
-@@ -172,6 +173,9 @@ static void br_flood(struct net_bridge *
- 	prev = NULL;
- 
- 	list_for_each_entry_rcu(p, &br->port_list, list) {
-+		if (forward && (p->flags & BR_ISOLATE_MODE))
-+			continue;
-+
- 		prev = maybe_deliver(prev, p, skb, __packet_hook);
- 		if (IS_ERR(prev))
- 			goto out;
-@@ -195,14 +199,14 @@ out:
- /* called with rcu_read_lock */
- void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb)
- {
--	br_flood(br, skb, NULL, __br_deliver);
-+	br_flood(br, skb, NULL, __br_deliver, false);
- }
- 
- /* called under bridge lock */
- void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
- 		      struct sk_buff *skb2)
- {
--	br_flood(br, skb, skb2, __br_forward);
-+	br_flood(br, skb, skb2, __br_forward, true);
- }
- 
- #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
diff --git a/target/linux/generic/patches-2.6.38/643-bridge_remove_ipv6_dependency.patch b/target/linux/generic/patches-2.6.38/643-bridge_remove_ipv6_dependency.patch
deleted file mode 100644
index 7f4f7543e0..0000000000
--- a/target/linux/generic/patches-2.6.38/643-bridge_remove_ipv6_dependency.patch
+++ /dev/null
@@ -1,101 +0,0 @@
---- a/include/net/addrconf.h
-+++ b/include/net/addrconf.h
-@@ -93,6 +93,12 @@ extern void			addrconf_join_solict(struc
- extern void			addrconf_leave_solict(struct inet6_dev *idev,
- 					struct in6_addr *addr);
- 
-+extern int			(*ipv6_dev_get_saddr_hook)(struct net *net,
-+						struct net_device *dev,
-+						const struct in6_addr *daddr,
-+						unsigned int srcprefs,
-+						struct in6_addr *saddr);
-+
- static inline unsigned long addrconf_timeout_fixup(u32 timeout,
- 						    unsigned unit)
- {
---- a/net/bridge/Kconfig
-+++ b/net/bridge/Kconfig
-@@ -6,7 +6,6 @@ config BRIDGE
- 	tristate "802.1d Ethernet Bridging"
- 	select LLC
- 	select STP
--	depends on IPV6 || IPV6=n
- 	---help---
- 	  If you say Y here, then your Linux box will be able to act as an
- 	  Ethernet bridge, which means that the different Ethernet segments it
---- a/net/ipv6/Makefile
-+++ b/net/ipv6/Makefile
-@@ -40,3 +40,4 @@ obj-$(CONFIG_IPV6_TUNNEL) += ip6_tunnel.
- obj-y += addrconf_core.o exthdrs_core.o
- 
- obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_hashtables.o
-+obj-$(subst m,y,$(CONFIG_IPV6)) += inet6_stubs.o
---- a/net/ipv6/addrconf.c
-+++ b/net/ipv6/addrconf.c
-@@ -1119,7 +1119,7 @@ out:
- 	return ret;
- }
- 
--int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
-+static int __ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
- 		       const struct in6_addr *daddr, unsigned int prefs,
- 		       struct in6_addr *saddr)
- {
-@@ -1244,7 +1244,6 @@ try_nextdev:
- 	in6_ifa_put(hiscore->ifa);
- 	return 0;
- }
--EXPORT_SYMBOL(ipv6_dev_get_saddr);
- 
- int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
- 		    unsigned char banned_flags)
-@@ -4718,6 +4717,9 @@ int __init addrconf_init(void)
- 
- 	ipv6_addr_label_rtnl_register();
- 
-+	BUG_ON(ipv6_dev_get_saddr_hook != NULL);
-+	rcu_assign_pointer(ipv6_dev_get_saddr_hook, __ipv6_dev_get_saddr);
-+
- 	return 0;
- errout:
- 	rtnl_af_unregister(&inet6_ops);
-@@ -4736,6 +4738,9 @@ void addrconf_cleanup(void)
- 	struct net_device *dev;
- 	int i;
- 
-+	rcu_assign_pointer(ipv6_dev_get_saddr_hook, NULL);
-+	synchronize_rcu();
-+
- 	unregister_netdevice_notifier(&ipv6_dev_notf);
- 	unregister_pernet_subsys(&addrconf_ops);
- 	ipv6_addr_label_cleanup();
---- /dev/null
-+++ b/net/ipv6/inet6_stubs.c
-@@ -0,0 +1,27 @@
-+/*
-+ *      This program is free software; you can redistribute it and/or
-+ *      modify it under the terms of the GNU General Public License
-+ *      as published by the Free Software Foundation; either version
-+ *      2 of the License, or (at your option) any later version.
-+ */
-+#include <net/ipv6.h>
-+
-+int (*ipv6_dev_get_saddr_hook)(struct net *net, struct net_device *dev,
-+			const struct in6_addr *daddr, unsigned int srcprefs,
-+			struct in6_addr *saddr);
-+
-+EXPORT_SYMBOL(ipv6_dev_get_saddr_hook);
-+
-+int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
-+			const struct in6_addr *daddr, unsigned int prefs,
-+			struct in6_addr *saddr)
-+{
-+	typeof(ipv6_dev_get_saddr_hook) dev_get_saddr = rcu_dereference(ipv6_dev_get_saddr_hook);
-+
-+	if (dev_get_saddr)
-+		return dev_get_saddr(net, dst_dev, daddr, prefs, saddr);
-+
-+	return -EADDRNOTAVAIL;
-+}
-+EXPORT_SYMBOL(ipv6_dev_get_saddr);
-+
diff --git a/target/linux/generic/patches-2.6.38/650-pppoe_header_pad.patch b/target/linux/generic/patches-2.6.38/650-pppoe_header_pad.patch
deleted file mode 100644
index 4875d5f23f..0000000000
--- a/target/linux/generic/patches-2.6.38/650-pppoe_header_pad.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/drivers/net/pppoe.c
-+++ b/drivers/net/pppoe.c
-@@ -855,7 +855,7 @@ static int pppoe_sendmsg(struct kiocb *i
- 		goto end;
- 
- 
--	skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32,
-+	skb = sock_wmalloc(sk, total_len + dev->hard_header_len + 32 + NET_SKB_PAD,
- 			   0, GFP_KERNEL);
- 	if (!skb) {
- 		error = -ENOMEM;
-@@ -863,7 +863,7 @@ static int pppoe_sendmsg(struct kiocb *i
- 	}
- 
- 	/* Reserve space for headers. */
--	skb_reserve(skb, dev->hard_header_len);
-+	skb_reserve(skb, dev->hard_header_len + NET_SKB_PAD);
- 	skb_reset_network_header(skb);
- 
- 	skb->dev = dev;
diff --git a/target/linux/generic/patches-2.6.38/651-wireless_mesh_header.patch b/target/linux/generic/patches-2.6.38/651-wireless_mesh_header.patch
deleted file mode 100644
index 271f8e3591..0000000000
--- a/target/linux/generic/patches-2.6.38/651-wireless_mesh_header.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -145,7 +145,7 @@ static inline bool dev_xmit_complete(int
-  */
- 
- #if defined(CONFIG_WLAN) || defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
--# if defined(CONFIG_MAC80211_MESH)
-+# if 1 || defined(CONFIG_MAC80211_MESH)
- #  define LL_MAX_HEADER 128
- # else
- #  define LL_MAX_HEADER 96
diff --git a/target/linux/generic/patches-2.6.38/700-swconfig.patch b/target/linux/generic/patches-2.6.38/700-swconfig.patch
deleted file mode 100644
index 6825037ce9..0000000000
--- a/target/linux/generic/patches-2.6.38/700-swconfig.patch
+++ /dev/null
@@ -1,25 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -13,6 +13,12 @@ menuconfig PHYLIB
- 
- if PHYLIB
- 
-+config SWCONFIG
-+	tristate "Switch configuration API"
-+	---help---
-+	  Switch configuration API using netlink. This allows
-+	  you to configure the VLAN features of certain switches.
-+
- comment "MII PHY device drivers"
- 
- config MARVELL_PHY
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -3,6 +3,7 @@
- libphy-objs			:= phy.o phy_device.o mdio_bus.o
- 
- obj-$(CONFIG_PHYLIB)		+= libphy.o
-+obj-$(CONFIG_SWCONFIG)		+= swconfig.o
- obj-$(CONFIG_MARVELL_PHY)	+= marvell.o
- obj-$(CONFIG_DAVICOM_PHY)	+= davicom.o
- obj-$(CONFIG_CICADA_PHY)	+= cicada.o
diff --git a/target/linux/generic/patches-2.6.38/701-phy_extension.patch b/target/linux/generic/patches-2.6.38/701-phy_extension.patch
deleted file mode 100644
index a0624d849e..0000000000
--- a/target/linux/generic/patches-2.6.38/701-phy_extension.patch
+++ /dev/null
@@ -1,81 +0,0 @@
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -297,6 +297,50 @@ int phy_ethtool_gset(struct phy_device *
- }
- EXPORT_SYMBOL(phy_ethtool_gset);
- 
-+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr)
-+{
-+	u32 cmd;
-+	int tmp;
-+	struct ethtool_cmd ecmd = { ETHTOOL_GSET };
-+	struct ethtool_value edata = { ETHTOOL_GLINK };
-+
-+	if (get_user(cmd, (u32 *) useraddr))
-+		return -EFAULT;
-+
-+	switch (cmd) {
-+	case ETHTOOL_GSET:
-+		phy_ethtool_gset(phydev, &ecmd);
-+		if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
-+			return -EFAULT;
-+		return 0;
-+
-+	case ETHTOOL_SSET:
-+		if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
-+			return -EFAULT;
-+		return phy_ethtool_sset(phydev, &ecmd);
-+
-+	case ETHTOOL_NWAY_RST:
-+		/* if autoneg is off, it's an error */
-+		tmp = phy_read(phydev, MII_BMCR);
-+		if (tmp & BMCR_ANENABLE) {
-+			tmp |= (BMCR_ANRESTART);
-+			phy_write(phydev, MII_BMCR, tmp);
-+			return 0;
-+		}
-+		return -EINVAL;
-+
-+	case ETHTOOL_GLINK:
-+		edata.data = (phy_read(phydev,
-+				MII_BMSR) & BMSR_LSTATUS) ? 1 : 0;
-+		if (copy_to_user(useraddr, &edata, sizeof(edata)))
-+			return -EFAULT;
-+		return 0;
-+	}
-+
-+	return -EOPNOTSUPP;
-+}
-+EXPORT_SYMBOL(phy_ethtool_ioctl);
-+
- /**
-  * phy_mii_ioctl - generic PHY MII ioctl interface
-  * @phydev: the phy_device struct
-@@ -351,7 +395,7 @@ int phy_mii_ioctl(struct phy_device *phy
- 		}
- 
- 		phy_write(phydev, mii_data->reg_num, val);
--		
-+
- 		if (mii_data->reg_num == MII_BMCR &&
- 		    val & BMCR_RESET &&
- 		    phydev->drv->config_init) {
-@@ -470,7 +514,7 @@ static void phy_force_reduction(struct p
- 	int idx;
- 
- 	idx = phy_find_setting(phydev->speed, phydev->duplex);
--	
-+
- 	idx++;
- 
- 	idx = phy_find_valid(idx, phydev->supported);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -508,6 +508,7 @@ void phy_start_machine(struct phy_device
- void phy_stop_machine(struct phy_device *phydev);
- int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd);
- int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
-+int phy_ethtool_ioctl(struct phy_device *phydev, void *useraddr);
- int phy_mii_ioctl(struct phy_device *phydev,
- 		struct ifreq *ifr, int cmd);
- int phy_start_interrupts(struct phy_device *phydev);
diff --git a/target/linux/generic/patches-2.6.38/702-phy_add_aneg_done_function.patch b/target/linux/generic/patches-2.6.38/702-phy_add_aneg_done_function.patch
deleted file mode 100644
index f37baad729..0000000000
--- a/target/linux/generic/patches-2.6.38/702-phy_add_aneg_done_function.patch
+++ /dev/null
@@ -1,45 +0,0 @@
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -386,9 +386,18 @@ struct phy_driver {
- 	 */
- 	int (*config_aneg)(struct phy_device *phydev);
- 
-+	/* Determine if autonegotiation is done */
-+	int (*aneg_done)(struct phy_device *phydev);
-+
- 	/* Determines the negotiated speed and duplex */
- 	int (*read_status)(struct phy_device *phydev);
- 
-+	/* 
-+	 * Update the value in phydev->link to reflect the 
-+	 * current link value
-+	 */
-+	int (*update_link)(struct phy_device *phydev);
-+
- 	/* Clears any pending interrupts */
- 	int (*ack_interrupt)(struct phy_device *phydev);
- 
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -715,6 +715,9 @@ int genphy_update_link(struct phy_device
- {
- 	int status;
- 
-+	if (phydev->drv->update_link)
-+		return phydev->drv->update_link(phydev);
-+
- 	/* Do a fake read */
- 	status = phy_read(phydev, MII_BMSR);
- 
---- a/drivers/net/phy/phy.c
-+++ b/drivers/net/phy/phy.c
-@@ -106,6 +106,9 @@ static inline int phy_aneg_done(struct p
- {
- 	int retval;
- 
-+	if (phydev->drv->aneg_done)
-+		return phydev->drv->aneg_done(phydev);
-+
- 	retval = phy_read(phydev, MII_BMSR);
- 
- 	return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE);
diff --git a/target/linux/generic/patches-2.6.38/720-phy_adm6996.patch b/target/linux/generic/patches-2.6.38/720-phy_adm6996.patch
deleted file mode 100644
index 9e8e56678b..0000000000
--- a/target/linux/generic/patches-2.6.38/720-phy_adm6996.patch
+++ /dev/null
@@ -1,26 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -98,6 +98,13 @@ config MICREL_PHY
- 	---help---
- 	  Supports the KSZ9021, VSC8201, KS8001 PHYs.
- 
-+config ADM6996_PHY
-+	tristate "Driver for ADM6996 switches"
-+	select SWCONFIG
-+	---help---
-+	  Currently supports the ADM6996FC and ADM6996M switches.
-+	  Support for FC is very limited.
-+
- config FIXED_PHY
- 	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
- 	depends on PHYLIB=y
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -14,6 +14,7 @@ obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
- obj-$(CONFIG_BROADCOM_PHY)	+= broadcom.o
- obj-$(CONFIG_BCM63XX_PHY)	+= bcm63xx.o
- obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
-+obj-$(CONFIG_ADM6996_PHY)	+= adm6996.o
- obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
- obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
- obj-$(CONFIG_FIXED_PHY)		+= fixed.o
diff --git a/target/linux/generic/patches-2.6.38/721-phy_packets.patch b/target/linux/generic/patches-2.6.38/721-phy_packets.patch
deleted file mode 100644
index 640a19bb00..0000000000
--- a/target/linux/generic/patches-2.6.38/721-phy_packets.patch
+++ /dev/null
@@ -1,63 +0,0 @@
---- a/drivers/net/phy/phy_device.c
-+++ b/drivers/net/phy/phy_device.c
-@@ -149,6 +149,18 @@ int phy_scan_fixups(struct phy_device *p
- }
- EXPORT_SYMBOL(phy_scan_fixups);
- 
-+static int generic_receive_skb(struct sk_buff *skb)
-+{
-+	skb->protocol = eth_type_trans(skb, skb->dev);
-+	return netif_receive_skb(skb);
-+}
-+
-+static int generic_rx(struct sk_buff *skb)
-+{
-+	skb->protocol = eth_type_trans(skb, skb->dev);
-+	return netif_rx(skb);
-+}
-+
- static struct phy_device* phy_device_create(struct mii_bus *bus,
- 					    int addr, int phy_id)
- {
-@@ -180,6 +192,8 @@ static struct phy_device* phy_device_cre
- 	dev_set_name(&dev->dev, PHY_ID_FMT, bus->id, addr);
- 
- 	dev->state = PHY_DOWN;
-+	dev->netif_receive_skb = &generic_receive_skb;
-+	dev->netif_rx = &generic_rx;
- 
- 	mutex_init(&dev->lock);
- 	INIT_DELAYED_WORK(&dev->state_queue, phy_state_machine);
---- a/include/linux/phy.h
-+++ b/include/linux/phy.h
-@@ -332,6 +332,20 @@ struct phy_device {
- 	void (*adjust_link)(struct net_device *dev);
- 
- 	void (*adjust_state)(struct net_device *dev);
-+
-+	/*
-+	 * By default these point to the original functions
-+	 * with the same name. adding them to the phy_device
-+	 * allows the phy driver to override them for packet
-+	 * mangling if the ethernet driver supports it
-+	 * This is required to support some really horrible
-+	 * switches such as the Marvell 88E6060
-+	 */
-+	int (*netif_receive_skb)(struct sk_buff *skb);
-+	int (*netif_rx)(struct sk_buff *skb);
-+
-+	/* alignment offset for packets */
-+	int pkt_align;
- };
- #define to_phy_device(d) container_of(d, struct phy_device, dev)
- 
---- a/include/linux/netdevice.h
-+++ b/include/linux/netdevice.h
-@@ -1003,6 +1003,7 @@ struct net_device {
- 	void			*ax25_ptr;	/* AX.25 specific data */
- 	struct wireless_dev	*ieee80211_ptr;	/* IEEE 802.11 specific data,
- 						   assign before registering */
-+	void			*phy_ptr; /* PHY device specific data */
- 
- /*
-  * Cache lines mostly used on receive path (including eth_type_trans())
diff --git a/target/linux/generic/patches-2.6.38/722-phy_mvswitch.patch b/target/linux/generic/patches-2.6.38/722-phy_mvswitch.patch
deleted file mode 100644
index 2025b229a4..0000000000
--- a/target/linux/generic/patches-2.6.38/722-phy_mvswitch.patch
+++ /dev/null
@@ -1,22 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -105,6 +105,9 @@ config ADM6996_PHY
- 	  Currently supports the ADM6996FC and ADM6996M switches.
- 	  Support for FC is very limited.
- 
-+config MVSWITCH_PHY
-+	tristate "Driver for Marvell 88E6060 switches"
-+
- config FIXED_PHY
- 	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
- 	depends on PHYLIB=y
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -15,6 +15,7 @@ obj-$(CONFIG_BROADCOM_PHY)	+= broadcom.o
- obj-$(CONFIG_BCM63XX_PHY)	+= bcm63xx.o
- obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
- obj-$(CONFIG_ADM6996_PHY)	+= adm6996.o
-+obj-$(CONFIG_MVSWITCH_PHY)	+= mvswitch.o
- obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
- obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
- obj-$(CONFIG_FIXED_PHY)		+= fixed.o
diff --git a/target/linux/generic/patches-2.6.38/723-phy_ip175c.patch b/target/linux/generic/patches-2.6.38/723-phy_ip175c.patch
deleted file mode 100644
index 9e13e579dd..0000000000
--- a/target/linux/generic/patches-2.6.38/723-phy_ip175c.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -108,6 +108,10 @@ config ADM6996_PHY
- config MVSWITCH_PHY
- 	tristate "Driver for Marvell 88E6060 switches"
- 
-+config IP17XX_PHY
-+	tristate "Driver for IC+ IP17xx switches"
-+	select SWCONFIG
-+
- config FIXED_PHY
- 	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
- 	depends on PHYLIB=y
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -16,6 +16,7 @@ obj-$(CONFIG_BCM63XX_PHY)	+= bcm63xx.o
- obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
- obj-$(CONFIG_ADM6996_PHY)	+= adm6996.o
- obj-$(CONFIG_MVSWITCH_PHY)	+= mvswitch.o
-+obj-$(CONFIG_IP17XX_PHY)	+= ip17xx.o
- obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
- obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
- obj-$(CONFIG_FIXED_PHY)		+= fixed.o
diff --git a/target/linux/generic/patches-2.6.38/724-phy_ar8216.patch b/target/linux/generic/patches-2.6.38/724-phy_ar8216.patch
deleted file mode 100644
index a718e370f1..0000000000
--- a/target/linux/generic/patches-2.6.38/724-phy_ar8216.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -112,6 +112,10 @@ config IP17XX_PHY
- 	tristate "Driver for IC+ IP17xx switches"
- 	select SWCONFIG
- 
-+config AR8216_PHY
-+	tristate "Driver for Atheros AR8216 switches"
-+	select SWCONFIG
-+
- config FIXED_PHY
- 	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
- 	depends on PHYLIB=y
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -18,6 +18,7 @@ obj-$(CONFIG_ADM6996_PHY)	+= adm6996.o
- obj-$(CONFIG_MVSWITCH_PHY)	+= mvswitch.o
- obj-$(CONFIG_IP17XX_PHY)	+= ip17xx.o
- obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
-+obj-$(CONFIG_AR8216_PHY)	+= ar8216.o
- obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
- obj-$(CONFIG_FIXED_PHY)		+= fixed.o
- obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
diff --git a/target/linux/generic/patches-2.6.38/725-phy_rtl8306.patch b/target/linux/generic/patches-2.6.38/725-phy_rtl8306.patch
deleted file mode 100644
index a6d188f2ce..0000000000
--- a/target/linux/generic/patches-2.6.38/725-phy_rtl8306.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -116,6 +116,10 @@ config AR8216_PHY
- 	tristate "Driver for Atheros AR8216 switches"
- 	select SWCONFIG
- 
-+config RTL8306_PHY
-+	tristate "Driver for Realtek RTL8306S switches"
-+	select SWCONFIG
-+
- config FIXED_PHY
- 	bool "Driver for MDIO Bus/PHY emulation with fixed speed/link PHYs"
- 	depends on PHYLIB=y
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -19,6 +19,7 @@ obj-$(CONFIG_MVSWITCH_PHY)	+= mvswitch.o
- obj-$(CONFIG_IP17XX_PHY)	+= ip17xx.o
- obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
- obj-$(CONFIG_AR8216_PHY)	+= ar8216.o
-+obj-$(CONFIG_RTL8306_PHY)	+= rtl8306.o
- obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
- obj-$(CONFIG_FIXED_PHY)		+= fixed.o
- obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
diff --git a/target/linux/generic/patches-2.6.38/726-phy_rtl8366.patch b/target/linux/generic/patches-2.6.38/726-phy_rtl8366.patch
deleted file mode 100644
index badc0a4e62..0000000000
--- a/target/linux/generic/patches-2.6.38/726-phy_rtl8366.patch
+++ /dev/null
@@ -1,44 +0,0 @@
---- a/drivers/net/phy/Kconfig
-+++ b/drivers/net/phy/Kconfig
-@@ -158,4 +158,29 @@ config MDIO_OCTEON
- 
- 	  If in doubt, say Y.
- 
-+config RTL8366_SMI
-+	tristate "Driver for the RTL8366 SMI interface"
-+	depends on GENERIC_GPIO
-+	---help---
-+	  This module implements the SMI interface protocol which is used
-+	  by some RTL8366 ethernet switch devices via the generic GPIO API.
-+
-+if RTL8366_SMI
-+
-+config RTL8366S_PHY
-+	tristate "Driver for the Realtek RTL8366S switch"
-+	select SWCONFIG
-+
-+config RTL8366RB_PHY
-+	tristate "Driver for the Realtek RTL8366RB switch"
-+	select SWCONFIG
-+
-+config RTL8366S_PHY_DEBUG_FS
-+	bool "RTL8366 switch driver DEBUG_FS support"
-+	depends on RTL8366S_PHY || RTL8366RB_PHY
-+	depends on DEBUG_FS
-+	default n
-+
-+endif # RTL8366_SMI
-+
- endif # PHYLIB
---- a/drivers/net/phy/Makefile
-+++ b/drivers/net/phy/Makefile
-@@ -20,6 +20,9 @@ obj-$(CONFIG_IP17XX_PHY)	+= ip17xx.o
- obj-$(CONFIG_REALTEK_PHY)	+= realtek.o
- obj-$(CONFIG_AR8216_PHY)	+= ar8216.o
- obj-$(CONFIG_RTL8306_PHY)	+= rtl8306.o
-+obj-$(CONFIG_RTL8366_SMI)	+= rtl8366_smi.o
-+obj-$(CONFIG_RTL8366S_PHY)	+= rtl8366s.o
-+obj-$(CONFIG_RTL8366RB_PHY)	+= rtl8366rb.o
- obj-$(CONFIG_LSI_ET1011C_PHY)	+= et1011c.o
- obj-$(CONFIG_FIXED_PHY)		+= fixed.o
- obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
diff --git a/target/linux/generic/patches-2.6.38/750-hostap_txpower.patch b/target/linux/generic/patches-2.6.38/750-hostap_txpower.patch
deleted file mode 100644
index 374a284454..0000000000
--- a/target/linux/generic/patches-2.6.38/750-hostap_txpower.patch
+++ /dev/null
@@ -1,154 +0,0 @@
---- a/drivers/net/wireless/hostap/hostap_ap.c
-+++ b/drivers/net/wireless/hostap/hostap_ap.c
-@@ -2338,13 +2338,13 @@ int prism2_ap_get_sta_qual(local_info_t
- 		addr[count].sa_family = ARPHRD_ETHER;
- 		memcpy(addr[count].sa_data, sta->addr, ETH_ALEN);
- 		if (sta->last_rx_silence == 0)
--			qual[count].qual = sta->last_rx_signal < 27 ?
--				0 : (sta->last_rx_signal - 27) * 92 / 127;
-+                        qual[count].qual = (sta->last_rx_signal - 156) == 0 ?
-+                                0 : (sta->last_rx_signal - 156) * 92 / 64;
- 		else
--			qual[count].qual = sta->last_rx_signal -
--				sta->last_rx_silence - 35;
--		qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
--		qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
-+                        qual[count].qual = (sta->last_rx_signal -
-+                                sta->last_rx_silence) * 92 / 64;
-+                qual[count].level = sta->last_rx_signal;
-+                qual[count].noise = sta->last_rx_silence;
- 		qual[count].updated = sta->last_rx_updated;
- 
- 		sta->last_rx_updated = IW_QUAL_DBM;
-@@ -2410,13 +2410,13 @@ int prism2_ap_translate_scan(struct net_
- 		memset(&iwe, 0, sizeof(iwe));
- 		iwe.cmd = IWEVQUAL;
- 		if (sta->last_rx_silence == 0)
--			iwe.u.qual.qual = sta->last_rx_signal < 27 ?
--				0 : (sta->last_rx_signal - 27) * 92 / 127;
-+	                iwe.u.qual.qual = (sta->last_rx_signal -156) == 0 ?
-+	                        0 : (sta->last_rx_signal - 156) * 92 / 64;
- 		else
--			iwe.u.qual.qual = sta->last_rx_signal -
--				sta->last_rx_silence - 35;
--		iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal);
--		iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
-+                        iwe.u.qual.qual = (sta->last_rx_signal -
-+                                sta->last_rx_silence) * 92 / 64;
-+                iwe.u.qual.level = sta->last_rx_signal;
-+                iwe.u.qual.noise = sta->last_rx_silence;
- 		iwe.u.qual.updated = sta->last_rx_updated;
- 		iwe.len = IW_EV_QUAL_LEN;
- 		current_ev = iwe_stream_add_event(info, current_ev, end_buf,
---- a/drivers/net/wireless/hostap/hostap_config.h
-+++ b/drivers/net/wireless/hostap/hostap_config.h
-@@ -45,4 +45,9 @@
-  */
- /* #define PRISM2_NO_STATION_MODES */
- 
-+/* Enable TX power Setting functions
-+ * (min att = -128 , max att =  127)
-+ */
-+#define RAW_TXPOWER_SETTING
-+
- #endif /* HOSTAP_CONFIG_H */
---- a/drivers/net/wireless/hostap/hostap.h
-+++ b/drivers/net/wireless/hostap/hostap.h
-@@ -90,6 +90,7 @@ extern const struct iw_handler_def hosta
- extern const struct ethtool_ops prism2_ethtool_ops;
- 
- int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-+int hostap_restore_power(struct net_device *dev);
- 
- 
- #endif /* HOSTAP_H */
---- a/drivers/net/wireless/hostap/hostap_hw.c
-+++ b/drivers/net/wireless/hostap/hostap_hw.c
-@@ -932,6 +932,7 @@ static int hfa384x_set_rid(struct net_de
- 			prism2_hw_reset(dev);
- 	}
- 
-+	hostap_restore_power(dev);
- 	return res;
- }
- 
---- a/drivers/net/wireless/hostap/hostap_info.c
-+++ b/drivers/net/wireless/hostap/hostap_info.c
-@@ -433,6 +433,11 @@ static void handle_info_queue_linkstatus
- 	}
- 
- 	/* Get BSSID if we have a valid AP address */
-+
-+	if ( val == HFA384X_LINKSTATUS_CONNECTED ||
-+	     val == HFA384X_LINKSTATUS_DISCONNECTED )
-+			hostap_restore_power(local->dev);
-+
- 	if (connected) {
- 		netif_carrier_on(local->dev);
- 		netif_carrier_on(local->ddev);
---- a/drivers/net/wireless/hostap/hostap_ioctl.c
-+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
-@@ -1477,23 +1477,20 @@ static int prism2_txpower_hfa386x_to_dBm
- 		val = 255;
- 
- 	tmp = val;
--	tmp >>= 2;
- 
--	return -12 - tmp;
-+	return tmp;
- }
- 
- static u16 prism2_txpower_dBm_to_hfa386x(int val)
- {
- 	signed char tmp;
- 
--	if (val > 20)
--		return 128;
--	else if (val < -43)
-+	if (val > 127)
- 		return 127;
-+	else if (val < -128)
-+		return 128;
- 
- 	tmp = val;
--	tmp = -12 - tmp;
--	tmp <<= 2;
- 
- 	return (unsigned char) tmp;
- }
-@@ -4056,3 +4053,35 @@ int hostap_ioctl(struct net_device *dev,
- 
- 	return ret;
- }
-+
-+/* BUG FIX: Restore power setting value when lost due to F/W bug */
-+
-+int hostap_restore_power(struct net_device *dev)
-+{
-+        struct hostap_interface *iface = netdev_priv(dev);
-+       local_info_t *local = iface->local;
-+
-+       u16 val;
-+       int ret = 0;
-+
-+       if (local->txpower_type == PRISM2_TXPOWER_OFF) {
-+                       val = 0xff; /* use all standby and sleep modes */
-+                       ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
-+                                              HFA386X_CR_A_D_TEST_MODES2,
-+                                              &val, NULL);
-+       }
-+
-+#ifdef RAW_TXPOWER_SETTING
-+       if (local->txpower_type == PRISM2_TXPOWER_FIXED) {
-+               val = HFA384X_TEST_CFG_BIT_ALC;
-+               local->func->cmd(dev, HFA384X_CMDCODE_TEST |
-+                                (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL);
-+               val = prism2_txpower_dBm_to_hfa386x(local->txpower);
-+               ret = (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF,
-+                            HFA386X_CR_MANUAL_TX_POWER, &val, NULL));
-+       }
-+#endif /* RAW_TXPOWER_SETTING */
-+       return (ret ? -EOPNOTSUPP : 0);
-+}
-+
-+EXPORT_SYMBOL(hostap_restore_power);
diff --git a/target/linux/generic/patches-2.6.38/810-pci_disable_common_quirks.patch b/target/linux/generic/patches-2.6.38/810-pci_disable_common_quirks.patch
deleted file mode 100644
index c947836166..0000000000
--- a/target/linux/generic/patches-2.6.38/810-pci_disable_common_quirks.patch
+++ /dev/null
@@ -1,43 +0,0 @@
---- a/drivers/pci/Kconfig
-+++ b/drivers/pci/Kconfig
-@@ -62,6 +62,12 @@ config XEN_PCIDEV_FE_DEBUG
- 
- 	  When in doubt, say N.
- 
-+config PCI_DISABLE_COMMON_QUIRKS
-+	bool "PCI disable common quirks"
-+	depends on PCI
-+	help
-+	  If you don't know what to do here, say N.
-+
- config HT_IRQ
- 	bool "Interrupts on hypertransport devices"
- 	default y
---- a/drivers/pci/quirks.c
-+++ b/drivers/pci/quirks.c
-@@ -104,6 +104,7 @@ static void __devinit quirk_mmio_always_
- }
- DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, quirk_mmio_always_on);
- 
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
- /* The Mellanox Tavor device gives false positive parity errors
-  * Mark this device with a broken_parity_status, to allow
-  * PCI scanning code to "skip" this now blacklisted device.
-@@ -1989,7 +1990,9 @@ static void __devinit fixup_rev1_53c810(
- 	}
- }
- DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C810, fixup_rev1_53c810);
-+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */
- 
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
- /* Enable 1k I/O space granularity on the Intel P64H2 */
- static void __devinit quirk_p64h2_1k_io(struct pci_dev *dev)
- {
-@@ -2662,6 +2665,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AT
- 			quirk_msi_intx_disable_bug);
- 
- #endif /* CONFIG_PCI_MSI */
-+#endif /* !CONFIG_PCI_DISABLE_COMMON_QUIRKS */
- 
- /* Allow manual resource allocation for PCI hotplug bridges
-  * via pci=hpmemsize=nnM and pci=hpiosize=nnM parameters. For
diff --git a/target/linux/generic/patches-2.6.38/811-pci_disable_usb_common_quirks.patch b/target/linux/generic/patches-2.6.38/811-pci_disable_usb_common_quirks.patch
deleted file mode 100644
index e1efe9cc39..0000000000
--- a/target/linux/generic/patches-2.6.38/811-pci_disable_usb_common_quirks.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-
---- a/drivers/usb/host/pci-quirks.c
-+++ b/drivers/usb/host/pci-quirks.c
-@@ -134,6 +134,8 @@ reset_needed:
- }
- EXPORT_SYMBOL_GPL(uhci_check_and_reset_hc);
- 
-+#ifndef CONFIG_PCI_DISABLE_COMMON_QUIRKS
-+
- static inline int io_type_enabled(struct pci_dev *pdev, unsigned int mask)
- {
- 	u16 cmd;
-@@ -478,3 +480,5 @@ static void __devinit quirk_usb_early_ha
- 		quirk_usb_handoff_xhci(pdev);
- }
- DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
-+
-+#endif
diff --git a/target/linux/generic/patches-2.6.38/820-usb_add_usb_find_device_by_name.patch b/target/linux/generic/patches-2.6.38/820-usb_add_usb_find_device_by_name.patch
deleted file mode 100644
index d225150c90..0000000000
--- a/target/linux/generic/patches-2.6.38/820-usb_add_usb_find_device_by_name.patch
+++ /dev/null
@@ -1,84 +0,0 @@
---- a/drivers/usb/core/usb.c
-+++ b/drivers/usb/core/usb.c
-@@ -646,6 +646,71 @@ int __usb_get_extra_descriptor(char *buf
- }
- EXPORT_SYMBOL_GPL(__usb_get_extra_descriptor);
- 
-+static struct usb_device *match_device_name(struct usb_device *dev,
-+					    const char *name)
-+{
-+	struct usb_device *ret_dev = NULL;
-+	int child;
-+
-+	dev_dbg(&dev->dev, "check for name %s ...\n", name);
-+
-+	/* see if this device matches */
-+	if (strcmp(dev_name(&dev->dev), name) == 0 ) {
-+		dev_dbg(&dev->dev, "matched this device!\n");
-+		ret_dev = usb_get_dev(dev);
-+		goto exit;
-+	}
-+
-+	/* look through all of the children of this device */
-+	for (child = 0; child < dev->maxchild; ++child) {
-+		if (dev->children[child]) {
-+			usb_lock_device(dev->children[child]);
-+			ret_dev = match_device_name(dev->children[child], name);
-+			usb_unlock_device(dev->children[child]);
-+			if (ret_dev)
-+				goto exit;
-+		}
-+	}
-+exit:
-+	return ret_dev;
-+}
-+
-+/**
-+ * usb_find_device_by_name - find a specific usb device in the system
-+ * @name: the name of the device to find
-+ *
-+ * Returns a pointer to a struct usb_device if such a specified usb
-+ * device is present in the system currently.  The usage count of the
-+ * device will be incremented if a device is found.  Make sure to call
-+ * usb_put_dev() when the caller is finished with the device.
-+ *
-+ * If a device with the specified bus id is not found, NULL is returned.
-+ */
-+struct usb_device *usb_find_device_by_name(const char *name)
-+{
-+	struct list_head *buslist;
-+	struct usb_bus *bus;
-+	struct usb_device *dev = NULL;
-+
-+	mutex_lock(&usb_bus_list_lock);
-+	for (buslist = usb_bus_list.next;
-+	     buslist != &usb_bus_list;
-+	     buslist = buslist->next) {
-+		bus = container_of(buslist, struct usb_bus, bus_list);
-+		if (!bus->root_hub)
-+			continue;
-+		usb_lock_device(bus->root_hub);
-+		dev = match_device_name(bus->root_hub, name);
-+		usb_unlock_device(bus->root_hub);
-+		if (dev)
-+			goto exit;
-+	}
-+exit:
-+	mutex_unlock(&usb_bus_list_lock);
-+	return dev;
-+}
-+EXPORT_SYMBOL_GPL(usb_find_device_by_name);
-+
- /**
-  * usb_alloc_coherent - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
-  * @dev: device the buffer will be used with
---- a/include/linux/usb.h
-+++ b/include/linux/usb.h
-@@ -513,6 +513,7 @@ extern int usb_lock_device_for_reset(str
- extern int usb_reset_device(struct usb_device *dev);
- extern void usb_queue_reset_device(struct usb_interface *dev);
- 
-+extern struct usb_device *usb_find_device_by_name(const char *name);
- 
- /* USB autosuspend and autoresume */
- #ifdef CONFIG_USB_SUSPEND
diff --git a/target/linux/generic/patches-2.6.38/822-usb_serial_option_add_more_devices.patch b/target/linux/generic/patches-2.6.38/822-usb_serial_option_add_more_devices.patch
deleted file mode 100644
index 98ca87885a..0000000000
--- a/target/linux/generic/patches-2.6.38/822-usb_serial_option_add_more_devices.patch
+++ /dev/null
@@ -1,49 +0,0 @@
---- a/drivers/usb/serial/option.c
-+++ b/drivers/usb/serial/option.c
-@@ -148,8 +148,13 @@ static void option_instat_callback(struc
- #define HUAWEI_PRODUCT_K4505			0x1464
- #define HUAWEI_PRODUCT_K3765			0x1465
- #define HUAWEI_PRODUCT_E14AC			0x14AC
-+#define HUAWEI_PRODUCT_K3770			0x14C9
-+#define HUAWEI_PRODUCT_K3771			0x14CA
-+#define HUAWEI_PRODUCT_K4510			0x14CB
-+#define HUAWEI_PRODUCT_K4511			0x14CC
- #define HUAWEI_PRODUCT_ETS1220			0x1803
- #define HUAWEI_PRODUCT_E353			0x1506
-+#define HUAWEI_PRODUCT_E173S			0x1C05
- 
- #define QUANTA_VENDOR_ID			0x0408
- #define QUANTA_PRODUCT_Q101			0xEA02
-@@ -345,6 +350,7 @@ static void option_instat_callback(struc
- /* ALCATEL PRODUCTS */
- #define ALCATEL_VENDOR_ID			0x1bbb
- #define ALCATEL_PRODUCT_X060S			0x0000
-+#define ALCATEL_PRODUCT_X220D			0x0017
- 
- #define PIRELLI_VENDOR_ID			0x1266
- #define PIRELLI_PRODUCT_C100_1			0x1002
-@@ -533,7 +539,16 @@ static const struct usb_device_id option
- 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff) },
- 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) },
- 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) },
-+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) },
-+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) },
-+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) },
-+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) },
-+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) },
-+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) },
-+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) },
-+	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) },
- 	{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) },
-+	{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S) },
- 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) },
- 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) },
- 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) },
-@@ -937,6 +952,7 @@ static const struct usb_device_id option
- 	{ USB_DEVICE(ALINK_VENDOR_ID, 0x9000) },
- 	{ USB_DEVICE_AND_INTERFACE_INFO(ALINK_VENDOR_ID, ALINK_PRODUCT_3GU, 0xff, 0xff, 0xff) },
- 	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S) },
-+	{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220D) },
- 	{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
- 	{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
- 	{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
diff --git a/target/linux/generic/patches-2.6.38/830-ledtrig_morse.patch b/target/linux/generic/patches-2.6.38/830-ledtrig_morse.patch
deleted file mode 100644
index 8d90184556..0000000000
--- a/target/linux/generic/patches-2.6.38/830-ledtrig_morse.patch
+++ /dev/null
@@ -1,18 +0,0 @@
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -439,4 +439,8 @@ config LEDS_TRIGGER_DEFAULT_ON
- comment "iptables trigger is under Netfilter config (LED target)"
- 	depends on LEDS_TRIGGERS
- 
-+config LEDS_TRIGGER_MORSE
-+	tristate "LED Morse Trigger"
-+	depends on LEDS_TRIGGERS
-+
- endif # NEW_LEDS
---- a/drivers/leds/Makefile
-+++ b/drivers/leds/Makefile
-@@ -52,3 +52,4 @@ obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT)	+=
- obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)	+= ledtrig-backlight.o
- obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledtrig-gpio.o
- obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o
-+obj-$(CONFIG_LEDS_TRIGGER_MORSE)	+= ledtrig-morse.o
diff --git a/target/linux/generic/patches-2.6.38/831-ledtrig_netdev.patch b/target/linux/generic/patches-2.6.38/831-ledtrig_netdev.patch
deleted file mode 100644
index 6406adac2a..0000000000
--- a/target/linux/generic/patches-2.6.38/831-ledtrig_netdev.patch
+++ /dev/null
@@ -1,43 +0,0 @@
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -443,4 +443,11 @@ config LEDS_TRIGGER_MORSE
- 	tristate "LED Morse Trigger"
- 	depends on LEDS_TRIGGERS
- 
-+config LEDS_TRIGGER_NETDEV
-+	tristate "LED Netdev Trigger"
-+	depends on NET && LEDS_TRIGGERS
-+	help
-+	  This allows LEDs to be controlled by network device activity.
-+	  If unsure, say Y.
-+
- endif # NEW_LEDS
---- a/drivers/leds/Makefile
-+++ b/drivers/leds/Makefile
-@@ -53,3 +53,4 @@ obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT)	+=
- obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledtrig-gpio.o
- obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o
- obj-$(CONFIG_LEDS_TRIGGER_MORSE)	+= ledtrig-morse.o
-+obj-$(CONFIG_LEDS_TRIGGER_NETDEV)	+= ledtrig-netdev.o
---- a/drivers/leds/ledtrig-netdev.c
-+++ b/drivers/leds/ledtrig-netdev.c
-@@ -307,8 +307,9 @@ done:
- static void netdev_trig_timer(unsigned long arg)
- {
- 	struct led_netdev_data *trigger_data = (struct led_netdev_data *)arg;
--	const struct net_device_stats *dev_stats;
-+	struct rtnl_link_stats64 *dev_stats;
- 	unsigned new_activity;
-+	struct rtnl_link_stats64 temp;
- 
- 	write_lock(&trigger_data->lock);
- 
-@@ -318,7 +319,7 @@ static void netdev_trig_timer(unsigned l
- 		goto no_restart;
- 	}
- 
--	dev_stats = dev_get_stats(trigger_data->net_dev);
-+	dev_stats = dev_get_stats(trigger_data->net_dev, &temp);
- 	new_activity =
- 		((trigger_data->mode & MODE_TX) ? dev_stats->tx_packets : 0) +
- 		((trigger_data->mode & MODE_RX) ? dev_stats->rx_packets : 0);
diff --git a/target/linux/generic/patches-2.6.38/832-ledtrig_usbdev.patch b/target/linux/generic/patches-2.6.38/832-ledtrig_usbdev.patch
deleted file mode 100644
index 25c6745f68..0000000000
--- a/target/linux/generic/patches-2.6.38/832-ledtrig_usbdev.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/drivers/leds/Kconfig
-+++ b/drivers/leds/Kconfig
-@@ -450,4 +450,11 @@ config LEDS_TRIGGER_NETDEV
- 	  This allows LEDs to be controlled by network device activity.
- 	  If unsure, say Y.
- 
-+config LEDS_TRIGGER_USBDEV
-+	tristate "LED USB device Trigger"
-+	depends on USB && LEDS_TRIGGERS
-+	help
-+	  This allows LEDs to be controlled by the presence/activity of
-+	  an USB device. If unsure, say N.
-+
- endif # NEW_LEDS
---- a/drivers/leds/Makefile
-+++ b/drivers/leds/Makefile
-@@ -54,3 +54,4 @@ obj-$(CONFIG_LEDS_TRIGGER_GPIO)		+= ledt
- obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON)	+= ledtrig-default-on.o
- obj-$(CONFIG_LEDS_TRIGGER_MORSE)	+= ledtrig-morse.o
- obj-$(CONFIG_LEDS_TRIGGER_NETDEV)	+= ledtrig-netdev.o
-+obj-$(CONFIG_LEDS_TRIGGER_USBDEV)	+= ledtrig-usbdev.o
diff --git a/target/linux/generic/patches-2.6.38/833-gpio_buttons.patch b/target/linux/generic/patches-2.6.38/833-gpio_buttons.patch
deleted file mode 100644
index 23fa95319b..0000000000
--- a/target/linux/generic/patches-2.6.38/833-gpio_buttons.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- a/drivers/input/misc/Kconfig
-+++ b/drivers/input/misc/Kconfig
-@@ -454,4 +454,20 @@ config INPUT_CMA3000_I2C
- 	  To compile this driver as a module, choose M here: the
- 	  module will be called cma3000_d0x_i2c.
- 
-+config INPUT_GPIO_BUTTONS
-+	tristate "Polled GPIO buttons interface"
-+	depends on GENERIC_GPIO
-+	select INPUT_POLLDEV
-+	help
-+	  This driver implements support for buttons connected
-+	  to GPIO pins of various CPUs (and some other chips).
-+
-+	  Say Y here if your device has buttons connected
-+	  directly to such GPIO pins.  Your board-specific
-+	  setup logic must also provide a platform device,
-+	  with configuration data saying which GPIOs are used.
-+
-+	  To compile this driver as a module, choose M here: the
-+	  module will be called gpio-buttons.
-+
- endif
---- a/drivers/input/misc/Makefile
-+++ b/drivers/input/misc/Makefile
-@@ -43,4 +43,5 @@ obj-$(CONFIG_INPUT_UINPUT)		+= uinput.o
- obj-$(CONFIG_INPUT_WISTRON_BTNS)	+= wistron_btns.o
- obj-$(CONFIG_INPUT_WM831X_ON)		+= wm831x-on.o
- obj-$(CONFIG_INPUT_YEALINK)		+= yealink.o
-+obj-$(CONFIG_INPUT_GPIO_BUTTONS)	+= gpio_buttons.o
- 
diff --git a/target/linux/generic/patches-2.6.38/835-gpiodev.patch b/target/linux/generic/patches-2.6.38/835-gpiodev.patch
deleted file mode 100644
index 900358e6b0..0000000000
--- a/target/linux/generic/patches-2.6.38/835-gpiodev.patch
+++ /dev/null
@@ -1,27 +0,0 @@
---- a/drivers/char/Kconfig
-+++ b/drivers/char/Kconfig
-@@ -1047,6 +1047,14 @@ config NSC_GPIO
- 	  pc8736x_gpio drivers.  If those drivers are built as
- 	  modules, this one will be too, named nsc_gpio
- 
-+config GPIO_DEVICE
-+	tristate "GPIO device support"
-+	depends on GENERIC_GPIO
-+	help
-+	  Say Y to enable Linux GPIO device support.  This allows control of
-+	  GPIO pins using a character device
-+
-+
- config RAW_DRIVER
- 	tristate "RAW driver (/dev/raw/rawN)"
- 	depends on BLOCK
---- a/drivers/char/Makefile
-+++ b/drivers/char/Makefile
-@@ -70,6 +70,7 @@ obj-$(CONFIG_NWFLASH)		+= nwflash.o
- obj-$(CONFIG_SCx200_GPIO)	+= scx200_gpio.o
- obj-$(CONFIG_PC8736x_GPIO)	+= pc8736x_gpio.o
- obj-$(CONFIG_NSC_GPIO)		+= nsc_gpio.o
-+obj-$(CONFIG_GPIO_DEVICE)	+= gpio_dev.o
- obj-$(CONFIG_GPIO_TB0219)	+= tb0219.o
- obj-$(CONFIG_TELCLOCK)		+= tlclk.o
- 
diff --git a/target/linux/generic/patches-2.6.38/840-rtc7301.patch b/target/linux/generic/patches-2.6.38/840-rtc7301.patch
deleted file mode 100644
index 2cc7b03fb6..0000000000
--- a/target/linux/generic/patches-2.6.38/840-rtc7301.patch
+++ /dev/null
@@ -1,250 +0,0 @@
---- a/drivers/rtc/Kconfig
-+++ b/drivers/rtc/Kconfig
-@@ -677,6 +677,15 @@ config RTC_DRV_NUC900
- 	  If you say yes here you get support for the RTC subsystem of the
- 	  NUC910/NUC920 used in embedded systems.
- 
-+config RTC_DRV_RTC7301
-+	tristate "Epson RTC-7301 SF/DG"
-+	help
-+	  If you say Y here you will get support for the
-+	  Epson RTC-7301 SF/DG RTC chips.
-+
-+	  This driver can also be built as a module. If so, the module
-+	  will be called rtc-7301.
-+
- comment "on-CPU RTC drivers"
- 
- config RTC_DRV_DAVINCI
---- a/drivers/rtc/Makefile
-+++ b/drivers/rtc/Makefile
-@@ -83,6 +83,7 @@ obj-$(CONFIG_RTC_DRV_RP5C01)	+= rtc-rp5c
- obj-$(CONFIG_RTC_DRV_RS5C313)	+= rtc-rs5c313.o
- obj-$(CONFIG_RTC_DRV_RS5C348)	+= rtc-rs5c348.o
- obj-$(CONFIG_RTC_DRV_RS5C372)	+= rtc-rs5c372.o
-+obj-$(CONFIG_RTC_DRV_RTC7301)	+= rtc-rtc7301.o
- obj-$(CONFIG_RTC_DRV_RX8025)	+= rtc-rx8025.o
- obj-$(CONFIG_RTC_DRV_RX8581)	+= rtc-rx8581.o
- obj-$(CONFIG_RTC_DRV_S35390A)	+= rtc-s35390a.o
---- /dev/null
-+++ b/drivers/rtc/rtc-rtc7301.c
-@@ -0,0 +1,219 @@
-+/*
-+ * Driver for Epson RTC-7301SF/DG
-+ *
-+ * Copyright (C) 2009 Jose Vasconcellos
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/rtc.h>
-+#include <linux/platform_device.h>
-+#include <linux/io.h>
-+#include <linux/delay.h>
-+#include <linux/bcd.h>
-+
-+#define RTC_NAME "rtc7301"
-+#define RTC_VERSION "0.1"
-+
-+/* Epson RTC-7301 register addresses */
-+#define RTC7301_SEC		0x00
-+#define RTC7301_SEC10		0x01
-+#define RTC7301_MIN		0x02
-+#define RTC7301_MIN10		0x03
-+#define RTC7301_HOUR		0x04
-+#define RTC7301_HOUR10		0x05
-+#define RTC7301_WEEKDAY		0x06
-+#define RTC7301_DAY		0x07
-+#define RTC7301_DAY10		0x08
-+#define RTC7301_MON		0x09
-+#define RTC7301_MON10		0x0A
-+#define RTC7301_YEAR		0x0B
-+#define RTC7301_YEAR10		0x0C
-+#define RTC7301_YEAR100		0x0D
-+#define RTC7301_YEAR1000	0x0E
-+#define RTC7301_CTRLREG		0x0F
-+
-+static uint8_t __iomem *rtc7301_base;
-+
-+#define read_reg(offset) (readb(rtc7301_base + offset) & 0xf)
-+#define write_reg(offset, data) writeb(data, rtc7301_base + (offset))
-+
-+#define rtc7301_isbusy() (read_reg(RTC7301_CTRLREG) & 1)
-+
-+static void rtc7301_init_settings(void)
-+{
-+	int i;
-+
-+	write_reg(RTC7301_CTRLREG, 2);
-+	write_reg(RTC7301_YEAR1000, 2);
-+	udelay(122);
-+
-+	/* bank 1 */
-+	write_reg(RTC7301_CTRLREG, 6);
-+	for (i=0; i<15; i++)
-+		write_reg(i, 0);
-+
-+	/* bank 2 */
-+	write_reg(RTC7301_CTRLREG, 14);
-+	for (i=0; i<15; i++)
-+		write_reg(i, 0);
-+	write_reg(RTC7301_CTRLREG, 0);
-+}
-+
-+static int rtc7301_get_datetime(struct device *dev, struct rtc_time *dt)
-+{
-+	int cnt;
-+	uint8_t buf[16];
-+
-+	cnt = 0;
-+	while (rtc7301_isbusy()) {
-+		udelay(244);
-+		if (cnt++ > 100) {
-+			dev_err(dev, "%s: timeout error %x\n", __func__, rtc7301_base[RTC7301_CTRLREG]);
-+			return -EIO;
-+		}
-+	}
-+
-+	for (cnt=0; cnt<16; cnt++)
-+		buf[cnt] = read_reg(cnt);
-+
-+	if (buf[RTC7301_SEC10] & 8) {
-+		dev_err(dev, "%s: RTC not set\n", __func__);
-+		return -EINVAL;
-+	}
-+
-+	memset(dt, 0, sizeof(*dt));
-+
-+	dt->tm_sec =  buf[RTC7301_SEC] + buf[RTC7301_SEC10]*10;
-+	dt->tm_min =  buf[RTC7301_MIN] + buf[RTC7301_MIN10]*10;
-+	dt->tm_hour = buf[RTC7301_HOUR] + buf[RTC7301_HOUR10]*10;
-+
-+	dt->tm_mday = buf[RTC7301_DAY] + buf[RTC7301_DAY10]*10;
-+	dt->tm_mon =  buf[RTC7301_MON] + buf[RTC7301_MON10]*10 - 1;
-+	dt->tm_year = buf[RTC7301_YEAR] + buf[RTC7301_YEAR10]*10 +
-+		      buf[RTC7301_YEAR100]*100 +
-+		      ((buf[RTC7301_YEAR1000] & 3)*1000) - 1900;
-+
-+	/* the rtc device may contain illegal values on power up
-+	 * according to the data sheet. make sure they are valid.
-+	 */
-+
-+	return rtc_valid_tm(dt);
-+}
-+
-+static int rtc7301_set_datetime(struct device *dev, struct rtc_time *dt)
-+{
-+	int data;
-+
-+	data = dt->tm_year + 1900;
-+	if (data >= 2100 || data < 1900)
-+		return -EINVAL;
-+
-+	write_reg(RTC7301_CTRLREG, 2);
-+       	udelay(122);
-+
-+	data = bin2bcd(dt->tm_sec);
-+	write_reg(RTC7301_SEC, data);
-+	write_reg(RTC7301_SEC10, (data >> 4));
-+
-+	data = bin2bcd(dt->tm_min);
-+	write_reg(RTC7301_MIN, data );
-+	write_reg(RTC7301_MIN10, (data >> 4));
-+
-+	data = bin2bcd(dt->tm_hour);
-+	write_reg(RTC7301_HOUR, data);
-+	write_reg(RTC7301_HOUR10, (data >> 4));
-+
-+	data = bin2bcd(dt->tm_mday);
-+	write_reg(RTC7301_DAY, data);
-+	write_reg(RTC7301_DAY10, (data>> 4));
-+
-+	data = bin2bcd(dt->tm_mon + 1);
-+	write_reg(RTC7301_MON, data);
-+	write_reg(RTC7301_MON10, (data >> 4));
-+
-+	data = bin2bcd(dt->tm_year % 100);
-+	write_reg(RTC7301_YEAR, data);
-+	write_reg(RTC7301_YEAR10, (data >> 4));
-+	data = bin2bcd((1900 + dt->tm_year) / 100);
-+	write_reg(RTC7301_YEAR100, data);
-+
-+	data = bin2bcd(dt->tm_wday);
-+	write_reg(RTC7301_WEEKDAY, data);
-+
-+	write_reg(RTC7301_CTRLREG, 0);
-+
-+	return 0;
-+}
-+
-+static const struct rtc_class_ops rtc7301_rtc_ops = {
-+	.read_time	= rtc7301_get_datetime,
-+	.set_time	= rtc7301_set_datetime,
-+};
-+
-+static int __devinit rtc7301_probe(struct platform_device *pdev)
-+{
-+	struct rtc_device *rtc;
-+	struct resource *res;
-+
-+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-+	if (!res)
-+		return -ENOENT;
-+
-+	rtc7301_base = ioremap_nocache(res->start, 0x1000 /*res->end - res->start + 1*/);
-+	if (!rtc7301_base)
-+		return -EINVAL;
-+
-+	rtc = rtc_device_register(RTC_NAME, &pdev->dev,
-+				&rtc7301_rtc_ops, THIS_MODULE);
-+	if (IS_ERR(rtc)) {
-+		iounmap(rtc7301_base);
-+		return PTR_ERR(rtc);
-+	}
-+
-+	platform_set_drvdata(pdev, rtc);
-+
-+	rtc7301_init_settings();
-+	return 0;
-+}
-+
-+static int __devexit rtc7301_remove(struct platform_device *pdev)
-+{
-+	struct rtc_device *rtc = platform_get_drvdata(pdev);
-+
-+	if (rtc)
-+		rtc_device_unregister(rtc);
-+	if (rtc7301_base)
-+		iounmap(rtc7301_base);
-+	return 0;
-+}
-+
-+static struct platform_driver rtc7301_driver = {
-+	.driver = {
-+		.name	= RTC_NAME,
-+		.owner	= THIS_MODULE,
-+	},
-+	.probe	= rtc7301_probe,
-+	.remove = __devexit_p(rtc7301_remove),
-+};
-+
-+static __init int rtc7301_init(void)
-+{
-+	return platform_driver_register(&rtc7301_driver);
-+}
-+module_init(rtc7301_init);
-+
-+static __exit void rtc7301_exit(void)
-+{
-+	platform_driver_unregister(&rtc7301_driver);
-+}
-+module_exit(rtc7301_exit);
-+
-+MODULE_DESCRIPTION("Epson 7301 RTC driver");
-+MODULE_AUTHOR("Jose Vasconcellos <jvasco@verizon.net>");
-+MODULE_LICENSE("GPL");
-+MODULE_ALIAS("platform:" RTC_NAME);
-+MODULE_VERSION(RTC_VERSION);
diff --git a/target/linux/generic/patches-2.6.38/850-glamo_headers.patch b/target/linux/generic/patches-2.6.38/850-glamo_headers.patch
deleted file mode 100644
index f3cf973651..0000000000
--- a/target/linux/generic/patches-2.6.38/850-glamo_headers.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- a/include/linux/fb.h
-+++ b/include/linux/fb.h
-@@ -125,6 +125,7 @@
- #define FB_ACCEL_TRIDENT_BLADE3D 52	/* Trident Blade3D		*/
- #define FB_ACCEL_TRIDENT_BLADEXP 53	/* Trident BladeXP		*/
- #define FB_ACCEL_CIRRUS_ALPINE   53	/* Cirrus Logic 543x/544x/5480	*/
-+#define FB_ACCEL_GLAMO		50	/* SMedia Glamo                 */
- #define FB_ACCEL_NEOMAGIC_NM2070 90	/* NeoMagic NM2070              */
- #define FB_ACCEL_NEOMAGIC_NM2090 91	/* NeoMagic NM2090              */
- #define FB_ACCEL_NEOMAGIC_NM2093 92	/* NeoMagic NM2093              */
---- a/include/linux/Kbuild
-+++ b/include/linux/Kbuild
-@@ -142,6 +142,8 @@ header-y += generic_serial.h
- header-y += genetlink.h
- header-y += gfs2_ondisk.h
- header-y += gigaset_dev.h
-+header-y += glamofb.h
-+header-y += glamo-engine.h
- header-y += hdlc.h
- header-y += hdlcdrv.h
- header-y += hdreg.h
diff --git a/target/linux/generic/patches-2.6.38/860-01_hotpluggable_spi_gpio.patch b/target/linux/generic/patches-2.6.38/860-01_hotpluggable_spi_gpio.patch
deleted file mode 100644
index f8e6374fa7..0000000000
--- a/target/linux/generic/patches-2.6.38/860-01_hotpluggable_spi_gpio.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-Fix spi-gpio for hotplug.
-
---mb
-
-
-
---- a/drivers/spi/spi_gpio.c
-+++ b/drivers/spi/spi_gpio.c
-@@ -255,7 +255,7 @@ static void spi_gpio_cleanup(struct spi_
- 	spi_bitbang_cleanup(spi);
- }
- 
--static int __init spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
-+static int __devinit spi_gpio_alloc(unsigned pin, const char *label, bool is_in)
- {
- 	int value;
- 
-@@ -269,7 +269,7 @@ static int __init spi_gpio_alloc(unsigne
- 	return value;
- }
- 
--static int __init
-+static int __devinit
- spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label,
- 	u16 *res_flags)
- {
-@@ -311,7 +311,7 @@ done:
- 	return value;
- }
- 
--static int __init spi_gpio_probe(struct platform_device *pdev)
-+static int __devinit spi_gpio_probe(struct platform_device *pdev)
- {
- 	int				status;
- 	struct spi_master		*master;
-@@ -379,7 +379,7 @@ gpio_free:
- 	return status;
- }
- 
--static int __exit spi_gpio_remove(struct platform_device *pdev)
-+static int __devexit spi_gpio_remove(struct platform_device *pdev)
- {
- 	struct spi_gpio			*spi_gpio;
- 	struct spi_gpio_platform_data	*pdata;
-@@ -408,12 +408,13 @@ MODULE_ALIAS("platform:" DRIVER_NAME);
- static struct platform_driver spi_gpio_driver = {
- 	.driver.name	= DRIVER_NAME,
- 	.driver.owner	= THIS_MODULE,
--	.remove		= __exit_p(spi_gpio_remove),
-+	.probe		= spi_gpio_probe,
-+	.remove		= __devexit_p(spi_gpio_remove),
- };
- 
- static int __init spi_gpio_init(void)
- {
--	return platform_driver_probe(&spi_gpio_driver, spi_gpio_probe);
-+	return platform_driver_register(&spi_gpio_driver);
- }
- module_init(spi_gpio_init);
- 
diff --git a/target/linux/generic/patches-2.6.38/861-04_spi_gpio_implement_spi_delay.patch b/target/linux/generic/patches-2.6.38/861-04_spi_gpio_implement_spi_delay.patch
deleted file mode 100644
index 4b145c2734..0000000000
--- a/target/linux/generic/patches-2.6.38/861-04_spi_gpio_implement_spi_delay.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-Implement the SPI-GPIO delay function for busses that need speed limitation.
-
---mb
-
-
-
---- a/drivers/spi/spi_gpio.c
-+++ b/drivers/spi/spi_gpio.c
-@@ -21,6 +21,7 @@
- #include <linux/init.h>
- #include <linux/platform_device.h>
- #include <linux/gpio.h>
-+#include <linux/delay.h>
- 
- #include <linux/spi/spi.h>
- #include <linux/spi/spi_bitbang.h>
-@@ -69,6 +70,7 @@ struct spi_gpio {
-  *		#define	SPI_MOSI_GPIO	120
-  *		#define	SPI_SCK_GPIO	121
-  *		#define	SPI_N_CHIPSEL	4
-+ *		#undef NEED_SPIDELAY
-  *		#include "spi_gpio.c"
-  */
- 
-@@ -76,6 +78,7 @@ struct spi_gpio {
- #define DRIVER_NAME	"spi_gpio"
- 
- #define GENERIC_BITBANG	/* vs tight inlines */
-+#define NEED_SPIDELAY	1
- 
- /* all functions referencing these symbols must define pdata */
- #define SPI_MISO_GPIO	((pdata)->miso)
-@@ -120,12 +123,20 @@ static inline int getmiso(const struct s
- #undef pdata
- 
- /*
-- * NOTE:  this clocks "as fast as we can".  It "should" be a function of the
-- * requested device clock.  Software overhead means we usually have trouble
-- * reaching even one Mbit/sec (except when we can inline bitops), so for now
-- * we'll just assume we never need additional per-bit slowdowns.
-+ * NOTE:  to clock "as fast as we can", set spi_device.max_speed_hz
-+ * and spi_transfer.speed_hz to 0.
-+ * Otherwise this is a function of the requested device clock.
-+ * Software overhead means we usually have trouble
-+ * reaching even one Mbit/sec (except when we can inline bitops). So on small
-+ * embedded devices with fast SPI slaves you usually don't need a delay.
-  */
--#define spidelay(nsecs)	do {} while (0)
-+static inline void spidelay(unsigned nsecs)
-+{
-+#ifdef NEED_SPIDELAY
-+	if (unlikely(nsecs))
-+		ndelay(nsecs);
-+#endif /* NEED_SPIDELAY */
-+}
- 
- #include "spi_bitbang_txrx.h"
- 
diff --git a/target/linux/generic/patches-2.6.38/862-gpio_spi_driver.patch b/target/linux/generic/patches-2.6.38/862-gpio_spi_driver.patch
deleted file mode 100644
index 3d85069566..0000000000
--- a/target/linux/generic/patches-2.6.38/862-gpio_spi_driver.patch
+++ /dev/null
@@ -1,373 +0,0 @@
-THIS CODE IS DEPRECATED.
-
-Please use the new mainline SPI-GPIO driver, as of 2.6.29.
-
---mb
-
-
-
----
- drivers/spi/Kconfig              |    9 +
- drivers/spi/Makefile             |    1 
- drivers/spi/spi_gpio_old.c       |  251 +++++++++++++++++++++++++++++++++++++++
- include/linux/spi/spi_gpio_old.h |   73 +++++++++++
- 4 files changed, 334 insertions(+)
-
---- /dev/null
-+++ b/include/linux/spi/spi_gpio_old.h
-@@ -0,0 +1,73 @@
-+/*
-+ * spi_gpio interface to platform code
-+ *
-+ * Copyright (c) 2008 Piotr Skamruk
-+ * Copyright (c) 2008 Michael Buesch
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+#ifndef _LINUX_SPI_SPI_GPIO
-+#define _LINUX_SPI_SPI_GPIO
-+
-+#include <linux/types.h>
-+#include <linux/spi/spi.h>
-+
-+
-+/**
-+ * struct spi_gpio_platform_data - Data definitions for a SPI-GPIO device.
-+ *
-+ * This structure holds information about a GPIO-based SPI device.
-+ *
-+ * @pin_clk: The GPIO pin number of the CLOCK pin.
-+ *
-+ * @pin_miso: The GPIO pin number of the MISO pin.
-+ *
-+ * @pin_mosi: The GPIO pin number of the MOSI pin.
-+ *
-+ * @pin_cs: The GPIO pin number of the CHIPSELECT pin.
-+ *
-+ * @cs_activelow: If true, the chip is selected when the CS line is low.
-+ *
-+ * @no_spi_delay: If true, no delay is done in the lowlevel bitbanging.
-+ *                Note that doing no delay is not standards compliant,
-+ *                but it might be needed to speed up transfers on some
-+ *                slow embedded machines.
-+ *
-+ * @boardinfo_setup: This callback is called after the
-+ *                   SPI master device was registered, but before the
-+ *                   device is registered.
-+ * @boardinfo_setup_data: Data argument passed to boardinfo_setup().
-+ */
-+struct spi_gpio_platform_data {
-+	unsigned int pin_clk;
-+	unsigned int pin_miso;
-+	unsigned int pin_mosi;
-+	unsigned int pin_cs;
-+	bool cs_activelow;
-+	bool no_spi_delay;
-+	int (*boardinfo_setup)(struct spi_board_info *bi,
-+			       struct spi_master *master,
-+			       void *data);
-+	void *boardinfo_setup_data;
-+};
-+
-+/**
-+ * SPI_GPIO_PLATDEV_NAME - The platform device name string.
-+ *
-+ * The name string that has to be used for platform_device_alloc
-+ * when allocating a spi-gpio device.
-+ */
-+#define SPI_GPIO_PLATDEV_NAME	"spi-gpio"
-+
-+/**
-+ * spi_gpio_next_id - Get another platform device ID number.
-+ *
-+ * This returns the next platform device ID number that has to be used
-+ * for platform_device_alloc. The ID is opaque and should not be used for
-+ * anything else.
-+ */
-+int spi_gpio_next_id(void);
-+
-+#endif /* _LINUX_SPI_SPI_GPIO */
---- /dev/null
-+++ b/drivers/spi/spi_gpio_old.c
-@@ -0,0 +1,251 @@
-+/*
-+ * Bitbanging SPI bus driver using GPIO API
-+ *
-+ * Copyright (c) 2008 Piotr Skamruk
-+ * Copyright (c) 2008 Michael Buesch
-+ *
-+ * based on spi_s3c2410_gpio.c
-+ *   Copyright (c) 2006 Ben Dooks
-+ *   Copyright (c) 2006 Simtec Electronics
-+ * and on i2c-gpio.c
-+ *   Copyright (C) 2007 Atmel Corporation
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License version 2 as
-+ * published by the Free Software Foundation.
-+ */
-+
-+#include <linux/kernel.h>
-+#include <linux/init.h>
-+#include <linux/delay.h>
-+#include <linux/spinlock.h>
-+#include <linux/workqueue.h>
-+#include <linux/module.h>
-+#include <linux/platform_device.h>
-+#include <linux/spi/spi.h>
-+#include <linux/spi/spi_bitbang.h>
-+#include <linux/spi/spi_gpio_old.h>
-+#include <linux/gpio.h>
-+#include <asm/atomic.h>
-+
-+
-+struct spi_gpio {
-+	struct spi_bitbang bitbang;
-+	struct spi_gpio_platform_data *info;
-+	struct platform_device *pdev;
-+	struct spi_board_info bi;
-+};
-+
-+
-+static inline struct spi_gpio *spidev_to_sg(struct spi_device *dev)
-+{
-+	return dev->controller_data;
-+}
-+
-+static inline void setsck(struct spi_device *dev, int val)
-+{
-+	struct spi_gpio *sp = spidev_to_sg(dev);
-+	gpio_set_value(sp->info->pin_clk, val ? 1 : 0);
-+}
-+
-+static inline void setmosi(struct spi_device *dev, int val)
-+{
-+	struct spi_gpio *sp = spidev_to_sg(dev);
-+	gpio_set_value(sp->info->pin_mosi, val ? 1 : 0);
-+}
-+
-+static inline u32 getmiso(struct spi_device *dev)
-+{
-+	struct spi_gpio *sp = spidev_to_sg(dev);
-+	return gpio_get_value(sp->info->pin_miso) ? 1 : 0;
-+}
-+
-+static inline void do_spidelay(struct spi_device *dev, unsigned nsecs)
-+{
-+	struct spi_gpio *sp = spidev_to_sg(dev);
-+
-+	if (!sp->info->no_spi_delay)
-+		ndelay(nsecs);
-+}
-+
-+#define spidelay(nsecs) do {					\
-+	/* Steal the spi_device pointer from our caller.	\
-+	 * The bitbang-API should probably get fixed here... */	\
-+	do_spidelay(spi, nsecs);				\
-+  } while (0)
-+
-+#define EXPAND_BITBANG_TXRX
-+#include "spi_bitbang_txrx.h"
-+
-+static u32 spi_gpio_txrx_mode0(struct spi_device *spi,
-+			       unsigned nsecs, u32 word, u8 bits)
-+{
-+	return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
-+}
-+
-+static u32 spi_gpio_txrx_mode1(struct spi_device *spi,
-+			       unsigned nsecs, u32 word, u8 bits)
-+{
-+	return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
-+}
-+
-+static u32 spi_gpio_txrx_mode2(struct spi_device *spi,
-+			       unsigned nsecs, u32 word, u8 bits)
-+{
-+	return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
-+}
-+
-+static u32 spi_gpio_txrx_mode3(struct spi_device *spi,
-+			       unsigned nsecs, u32 word, u8 bits)
-+{
-+	return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
-+}
-+
-+static void spi_gpio_chipselect(struct spi_device *dev, int on)
-+{
-+	struct spi_gpio *sp = spidev_to_sg(dev);
-+
-+	if (sp->info->cs_activelow)
-+		on = !on;
-+	gpio_set_value(sp->info->pin_cs, on ? 1 : 0);
-+}
-+
-+static int spi_gpio_probe(struct platform_device *pdev)
-+{
-+	struct spi_master *master;
-+	struct spi_gpio_platform_data *pdata;
-+	struct spi_gpio *sp;
-+	struct spi_device *spidev;
-+	int err;
-+
-+	pdata = pdev->dev.platform_data;
-+	if (!pdata)
-+		return -ENXIO;
-+
-+	err = -ENOMEM;
-+	master = spi_alloc_master(&pdev->dev, sizeof(struct spi_gpio));
-+	if (!master)
-+		goto err_alloc_master;
-+
-+	sp = spi_master_get_devdata(master);
-+	platform_set_drvdata(pdev, sp);
-+	sp->info = pdata;
-+
-+	err = gpio_request(pdata->pin_clk, "spi_clock");
-+	if (err)
-+		goto err_request_clk;
-+	err = gpio_request(pdata->pin_mosi, "spi_mosi");
-+	if (err)
-+		goto err_request_mosi;
-+	err = gpio_request(pdata->pin_miso, "spi_miso");
-+	if (err)
-+		goto err_request_miso;
-+	err = gpio_request(pdata->pin_cs, "spi_cs");
-+	if (err)
-+		goto err_request_cs;
-+
-+	sp->bitbang.master = spi_master_get(master);
-+	sp->bitbang.master->bus_num = -1;
-+	sp->bitbang.master->num_chipselect = 1;
-+	sp->bitbang.chipselect = spi_gpio_chipselect;
-+	sp->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_mode0;
-+	sp->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_mode1;
-+	sp->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_mode2;
-+	sp->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_mode3;
-+
-+	gpio_direction_output(pdata->pin_clk, 0);
-+	gpio_direction_output(pdata->pin_mosi, 0);
-+	gpio_direction_output(pdata->pin_cs,
-+			      pdata->cs_activelow ? 1 : 0);
-+	gpio_direction_input(pdata->pin_miso);
-+
-+	err = spi_bitbang_start(&sp->bitbang);
-+	if (err)
-+		goto err_no_bitbang;
-+	err = pdata->boardinfo_setup(&sp->bi, master,
-+				     pdata->boardinfo_setup_data);
-+	if (err)
-+		goto err_bi_setup;
-+	sp->bi.controller_data = sp;
-+	spidev = spi_new_device(master, &sp->bi);
-+	if (!spidev)
-+		goto err_new_dev;
-+
-+	return 0;
-+
-+err_new_dev:
-+err_bi_setup:
-+	spi_bitbang_stop(&sp->bitbang);
-+err_no_bitbang:
-+	spi_master_put(sp->bitbang.master);
-+	gpio_free(pdata->pin_cs);
-+err_request_cs:
-+	gpio_free(pdata->pin_miso);
-+err_request_miso:
-+	gpio_free(pdata->pin_mosi);
-+err_request_mosi:
-+	gpio_free(pdata->pin_clk);
-+err_request_clk:
-+	kfree(master);
-+
-+err_alloc_master:
-+	return err;
-+}
-+
-+static int __devexit spi_gpio_remove(struct platform_device *pdev)
-+{
-+	struct spi_gpio *sp;
-+	struct spi_gpio_platform_data *pdata;
-+
-+	pdata = pdev->dev.platform_data;
-+	sp = platform_get_drvdata(pdev);
-+
-+	gpio_free(pdata->pin_clk);
-+	gpio_free(pdata->pin_mosi);
-+	gpio_free(pdata->pin_miso);
-+	gpio_free(pdata->pin_cs);
-+	spi_bitbang_stop(&sp->bitbang);
-+	spi_master_put(sp->bitbang.master);
-+
-+	return 0;
-+}
-+
-+static struct platform_driver spi_gpio_driver = {
-+	.driver		= {
-+		.name	= SPI_GPIO_PLATDEV_NAME,
-+		.owner	= THIS_MODULE,
-+	},
-+	.probe		= spi_gpio_probe,
-+	.remove		= __devexit_p(spi_gpio_remove),
-+};
-+
-+int spi_gpio_next_id(void)
-+{
-+	static atomic_t counter = ATOMIC_INIT(-1);
-+
-+	return atomic_inc_return(&counter);
-+}
-+EXPORT_SYMBOL(spi_gpio_next_id);
-+
-+static int __init spi_gpio_init(void)
-+{
-+	int err;
-+
-+	err = platform_driver_register(&spi_gpio_driver);
-+	if (err)
-+		printk(KERN_ERR "spi-gpio: register failed: %d\n", err);
-+
-+	return err;
-+}
-+module_init(spi_gpio_init);
-+
-+static void __exit spi_gpio_exit(void)
-+{
-+	platform_driver_unregister(&spi_gpio_driver);
-+}
-+module_exit(spi_gpio_exit);
-+
-+MODULE_AUTHOR("Piot Skamruk <piotr.skamruk at gmail.com>");
-+MODULE_AUTHOR("Michael Buesch");
-+MODULE_DESCRIPTION("Platform independent GPIO bitbanging SPI driver");
-+MODULE_LICENSE("GPL v2");
---- a/drivers/spi/Kconfig
-+++ b/drivers/spi/Kconfig
-@@ -169,6 +169,15 @@ config SPI_IMX_VER_0_7
- config SPI_IMX_VER_2_3
- 	def_bool y if ARCH_MX51 || ARCH_MX53
- 
-+config SPI_GPIO_OLD
-+	tristate "Old GPIO API based bitbanging SPI controller (DEPRECATED)"
-+	depends on SPI_MASTER && GENERIC_GPIO
-+	select SPI_BITBANG
-+	help
-+	  This code is deprecated. Please use the new mainline SPI-GPIO driver.
-+
-+	  If unsure, say N.
-+
- config SPI_IMX
- 	tristate "Freescale i.MX SPI controllers"
- 	depends on ARCH_MXC
---- a/drivers/spi/Makefile
-+++ b/drivers/spi/Makefile
-@@ -23,6 +23,7 @@ dw_spi_midpci-objs			:= dw_spi_pci.o dw_
- obj-$(CONFIG_SPI_DW_MMIO)		+= dw_spi_mmio.o
- obj-$(CONFIG_SPI_EP93XX)		+= ep93xx_spi.o
- obj-$(CONFIG_SPI_GPIO)			+= spi_gpio.o
-+obj-$(CONFIG_SPI_GPIO_OLD)		+= spi_gpio_old.o
- obj-$(CONFIG_SPI_IMX)			+= spi_imx.o
- obj-$(CONFIG_SPI_LM70_LLP)		+= spi_lm70llp.o
- obj-$(CONFIG_SPI_PXA2XX)		+= pxa2xx_spi.o
diff --git a/target/linux/generic/patches-2.6.38/863-gpiommc.patch b/target/linux/generic/patches-2.6.38/863-gpiommc.patch
deleted file mode 100644
index a959b978cb..0000000000
--- a/target/linux/generic/patches-2.6.38/863-gpiommc.patch
+++ /dev/null
@@ -1,843 +0,0 @@
---- /dev/null
-+++ b/drivers/mmc/host/gpiommc.c
-@@ -0,0 +1,608 @@
-+/*
-+ * Driver an MMC/SD card on a bitbanging GPIO SPI bus.
-+ * This module hooks up the mmc_spi and spi_gpio modules and also
-+ * provides a configfs interface.
-+ *
-+ * Copyright 2008 Michael Buesch <mb@bu3sch.de>
-+ *
-+ * Licensed under the GNU/GPL. See COPYING for details.
-+ */
-+
-+#include <linux/mmc/gpiommc.h>
-+#include <linux/platform_device.h>
-+#include <linux/list.h>
-+#include <linux/mutex.h>
-+#include <linux/spi/spi_gpio_old.h>
-+#include <linux/configfs.h>
-+#include <linux/gpio.h>
-+#include <asm/atomic.h>
-+
-+
-+#define PFX				"gpio-mmc: "
-+
-+
-+struct gpiommc_device {
-+	struct platform_device *pdev;
-+	struct platform_device *spi_pdev;
-+	struct spi_board_info boardinfo;
-+};
-+
-+
-+MODULE_DESCRIPTION("GPIO based MMC driver");
-+MODULE_AUTHOR("Michael Buesch");
-+MODULE_LICENSE("GPL");
-+
-+
-+static int gpiommc_boardinfo_setup(struct spi_board_info *bi,
-+				   struct spi_master *master,
-+				   void *data)
-+{
-+	struct gpiommc_device *d = data;
-+	struct gpiommc_platform_data *pdata = d->pdev->dev.platform_data;
-+
-+	/* Bind the SPI master to the MMC-SPI host driver. */
-+	strlcpy(bi->modalias, "mmc_spi", sizeof(bi->modalias));
-+
-+	bi->max_speed_hz = pdata->max_bus_speed;
-+	bi->bus_num = master->bus_num;
-+	bi->mode = pdata->mode;
-+
-+	return 0;
-+}
-+
-+static int gpiommc_probe(struct platform_device *pdev)
-+{
-+	struct gpiommc_platform_data *mmc_pdata = pdev->dev.platform_data;
-+	struct spi_gpio_platform_data spi_pdata;
-+	struct gpiommc_device *d;
-+	int err;
-+
-+	err = -ENXIO;
-+	if (!mmc_pdata)
-+		goto error;
-+
-+#ifdef CONFIG_MMC_SPI_MODULE
-+	err = request_module("mmc_spi");
-+	if (err) {
-+		printk(KERN_WARNING PFX
-+		       "Failed to request mmc_spi module.\n");
-+	}
-+#endif /* CONFIG_MMC_SPI_MODULE */
-+
-+	/* Allocate the GPIO-MMC device */
-+	err = -ENOMEM;
-+	d = kzalloc(sizeof(*d), GFP_KERNEL);
-+	if (!d)
-+		goto error;
-+	d->pdev = pdev;
-+
-+	/* Create the SPI-GPIO device */
-+	d->spi_pdev = platform_device_alloc(SPI_GPIO_PLATDEV_NAME,
-+					    spi_gpio_next_id());
-+	if (!d->spi_pdev)
-+		goto err_free_d;
-+
-+	memset(&spi_pdata, 0, sizeof(spi_pdata));
-+	spi_pdata.pin_clk = mmc_pdata->pins.gpio_clk;
-+	spi_pdata.pin_miso = mmc_pdata->pins.gpio_do;
-+	spi_pdata.pin_mosi = mmc_pdata->pins.gpio_di;
-+	spi_pdata.pin_cs = mmc_pdata->pins.gpio_cs;
-+	spi_pdata.cs_activelow = mmc_pdata->pins.cs_activelow;
-+	spi_pdata.no_spi_delay = mmc_pdata->no_spi_delay;
-+	spi_pdata.boardinfo_setup = gpiommc_boardinfo_setup;
-+	spi_pdata.boardinfo_setup_data = d;
-+
-+	err = platform_device_add_data(d->spi_pdev, &spi_pdata,
-+				       sizeof(spi_pdata));
-+	if (err)
-+		goto err_free_pdev;
-+	err = platform_device_add(d->spi_pdev);
-+	if (err)
-+		goto err_free_pdata;
-+	platform_set_drvdata(pdev, d);
-+
-+	printk(KERN_INFO PFX "MMC-Card \"%s\" "
-+	       "attached to GPIO pins di=%u, do=%u, clk=%u, cs=%u\n",
-+	       mmc_pdata->name, mmc_pdata->pins.gpio_di,
-+	       mmc_pdata->pins.gpio_do,
-+	       mmc_pdata->pins.gpio_clk,
-+	       mmc_pdata->pins.gpio_cs);
-+
-+	return 0;
-+
-+err_free_pdata:
-+	kfree(d->spi_pdev->dev.platform_data);
-+	d->spi_pdev->dev.platform_data = NULL;
-+err_free_pdev:
-+	platform_device_put(d->spi_pdev);
-+err_free_d:
-+	kfree(d);
-+error:
-+	return err;
-+}
-+
-+static int gpiommc_remove(struct platform_device *pdev)
-+{
-+	struct gpiommc_device *d = platform_get_drvdata(pdev);
-+	struct gpiommc_platform_data *pdata = d->pdev->dev.platform_data;
-+
-+	platform_device_unregister(d->spi_pdev);
-+	printk(KERN_INFO PFX "GPIO based MMC-Card \"%s\" removed\n",
-+	       pdata->name);
-+	platform_device_put(d->spi_pdev);
-+
-+	return 0;
-+}
-+
-+#ifdef CONFIG_GPIOMMC_CONFIGFS
-+
-+/* A device that was created through configfs */
-+struct gpiommc_configfs_device {
-+	struct config_item item;
-+	/* The platform device, after registration. */
-+	struct platform_device *pdev;
-+	/* The configuration */
-+	struct gpiommc_platform_data pdata;
-+};
-+
-+#define GPIO_INVALID	-1
-+
-+static inline bool gpiommc_is_registered(struct gpiommc_configfs_device *dev)
-+{
-+	return (dev->pdev != NULL);
-+}
-+
-+static inline struct gpiommc_configfs_device *ci_to_gpiommc(struct config_item *item)
-+{
-+	return item ? container_of(item, struct gpiommc_configfs_device, item) : NULL;
-+}
-+
-+static struct configfs_attribute gpiommc_attr_DI = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "gpio_data_in",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute gpiommc_attr_DO = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "gpio_data_out",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute gpiommc_attr_CLK = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "gpio_clock",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute gpiommc_attr_CS = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "gpio_chipselect",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute gpiommc_attr_CS_activelow = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "gpio_chipselect_activelow",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute gpiommc_attr_spimode = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "spi_mode",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute gpiommc_attr_spidelay = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "spi_delay",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute gpiommc_attr_max_bus_speed = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "max_bus_speed",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute gpiommc_attr_register = {
-+	.ca_owner = THIS_MODULE,
-+	.ca_name = "register",
-+	.ca_mode = S_IRUGO | S_IWUSR,
-+};
-+
-+static struct configfs_attribute *gpiommc_config_attrs[] = {
-+	&gpiommc_attr_DI,
-+	&gpiommc_attr_DO,
-+	&gpiommc_attr_CLK,
-+	&gpiommc_attr_CS,
-+	&gpiommc_attr_CS_activelow,
-+	&gpiommc_attr_spimode,
-+	&gpiommc_attr_spidelay,
-+	&gpiommc_attr_max_bus_speed,
-+	&gpiommc_attr_register,
-+	NULL,
-+};
-+
-+static ssize_t gpiommc_config_attr_show(struct config_item *item,
-+					struct configfs_attribute *attr,
-+					char *page)
-+{
-+	struct gpiommc_configfs_device *dev = ci_to_gpiommc(item);
-+	ssize_t count = 0;
-+	unsigned int gpio;
-+	int err = 0;
-+
-+	if (attr == &gpiommc_attr_DI) {
-+		gpio = dev->pdata.pins.gpio_di;
-+		if (gpio == GPIO_INVALID)
-+			count = snprintf(page, PAGE_SIZE, "not configured\n");
-+		else
-+			count = snprintf(page, PAGE_SIZE, "%u\n", gpio);
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_DO) {
-+		gpio = dev->pdata.pins.gpio_do;
-+		if (gpio == GPIO_INVALID)
-+			count = snprintf(page, PAGE_SIZE, "not configured\n");
-+		else
-+			count = snprintf(page, PAGE_SIZE, "%u\n", gpio);
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_CLK) {
-+		gpio = dev->pdata.pins.gpio_clk;
-+		if (gpio == GPIO_INVALID)
-+			count = snprintf(page, PAGE_SIZE, "not configured\n");
-+		else
-+			count = snprintf(page, PAGE_SIZE, "%u\n", gpio);
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_CS) {
-+		gpio = dev->pdata.pins.gpio_cs;
-+		if (gpio == GPIO_INVALID)
-+			count = snprintf(page, PAGE_SIZE, "not configured\n");
-+		else
-+			count = snprintf(page, PAGE_SIZE, "%u\n", gpio);
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_CS_activelow) {
-+		count = snprintf(page, PAGE_SIZE, "%u\n",
-+				 dev->pdata.pins.cs_activelow);
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_spimode) {
-+		count = snprintf(page, PAGE_SIZE, "%u\n",
-+				 dev->pdata.mode);
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_spidelay) {
-+		count = snprintf(page, PAGE_SIZE, "%u\n",
-+				 !dev->pdata.no_spi_delay);
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_max_bus_speed) {
-+		count = snprintf(page, PAGE_SIZE, "%u\n",
-+				 dev->pdata.max_bus_speed);
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_register) {
-+		count = snprintf(page, PAGE_SIZE, "%u\n",
-+				 gpiommc_is_registered(dev));
-+		goto out;
-+	}
-+	WARN_ON(1);
-+	err = -ENOSYS;
-+out:
-+	return err ? err : count;
-+}
-+
-+static int gpiommc_do_register(struct gpiommc_configfs_device *dev,
-+			       const char *name)
-+{
-+	int err;
-+
-+	if (gpiommc_is_registered(dev))
-+		return 0;
-+
-+	if (!gpio_is_valid(dev->pdata.pins.gpio_di) ||
-+	    !gpio_is_valid(dev->pdata.pins.gpio_do) ||
-+	    !gpio_is_valid(dev->pdata.pins.gpio_clk) ||
-+	    !gpio_is_valid(dev->pdata.pins.gpio_cs)) {
-+		printk(KERN_ERR PFX
-+		       "configfs: Invalid GPIO pin number(s)\n");
-+		return -EINVAL;
-+	}
-+
-+	strlcpy(dev->pdata.name, name,
-+		sizeof(dev->pdata.name));
-+
-+	dev->pdev = platform_device_alloc(GPIOMMC_PLATDEV_NAME,
-+					  gpiommc_next_id());
-+	if (!dev->pdev)
-+		return -ENOMEM;
-+	err = platform_device_add_data(dev->pdev, &dev->pdata,
-+				       sizeof(dev->pdata));
-+	if (err) {
-+		platform_device_put(dev->pdev);
-+		return err;
-+	}
-+	err = platform_device_add(dev->pdev);
-+	if (err) {
-+		platform_device_put(dev->pdev);
-+		return err;
-+	}
-+
-+	return 0;
-+}
-+
-+static void gpiommc_do_unregister(struct gpiommc_configfs_device *dev)
-+{
-+	if (!gpiommc_is_registered(dev))
-+		return;
-+
-+	platform_device_unregister(dev->pdev);
-+	dev->pdev = NULL;
-+}
-+
-+static ssize_t gpiommc_config_attr_store(struct config_item *item,
-+					 struct configfs_attribute *attr,
-+					 const char *page, size_t count)
-+{
-+	struct gpiommc_configfs_device *dev = ci_to_gpiommc(item);
-+	int err = -EINVAL;
-+	unsigned long data;
-+
-+	if (attr == &gpiommc_attr_register) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		if (data == 1)
-+			err = gpiommc_do_register(dev, item->ci_name);
-+		if (data == 0) {
-+			gpiommc_do_unregister(dev);
-+			err = 0;
-+		}
-+		goto out;
-+	}
-+
-+	if (gpiommc_is_registered(dev)) {
-+		/* The rest of the config parameters can only be set
-+		 * as long as the device is not registered, yet. */
-+		err = -EBUSY;
-+		goto out;
-+	}
-+
-+	if (attr == &gpiommc_attr_DI) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		if (!gpio_is_valid(data))
-+			goto out;
-+		dev->pdata.pins.gpio_di = data;
-+		err = 0;
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_DO) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		if (!gpio_is_valid(data))
-+			goto out;
-+		dev->pdata.pins.gpio_do = data;
-+		err = 0;
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_CLK) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		if (!gpio_is_valid(data))
-+			goto out;
-+		dev->pdata.pins.gpio_clk = data;
-+		err = 0;
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_CS) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		if (!gpio_is_valid(data))
-+			goto out;
-+		dev->pdata.pins.gpio_cs = data;
-+		err = 0;
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_CS_activelow) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		if (data != 0 && data != 1)
-+			goto out;
-+		dev->pdata.pins.cs_activelow = data;
-+		err = 0;
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_spimode) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		switch (data) {
-+		case 0:
-+			dev->pdata.mode = SPI_MODE_0;
-+			break;
-+		case 1:
-+			dev->pdata.mode = SPI_MODE_1;
-+			break;
-+		case 2:
-+			dev->pdata.mode = SPI_MODE_2;
-+			break;
-+		case 3:
-+			dev->pdata.mode = SPI_MODE_3;
-+			break;
-+		default:
-+			goto out;
-+		}
-+		err = 0;
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_spidelay) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		if (data != 0 && data != 1)
-+			goto out;
-+		dev->pdata.no_spi_delay = !data;
-+		err = 0;
-+		goto out;
-+	}
-+	if (attr == &gpiommc_attr_max_bus_speed) {
-+		err = strict_strtoul(page, 10, &data);
-+		if (err)
-+			goto out;
-+		err = -EINVAL;
-+		if (data > UINT_MAX)
-+			goto out;
-+		dev->pdata.max_bus_speed = data;
-+		err = 0;
-+		goto out;
-+	}
-+	WARN_ON(1);
-+	err = -ENOSYS;
-+out:
-+	return err ? err : count;
-+}
-+
-+static void gpiommc_config_item_release(struct config_item *item)
-+{
-+	struct gpiommc_configfs_device *dev = ci_to_gpiommc(item);
-+
-+	kfree(dev);
-+}
-+
-+static struct configfs_item_operations gpiommc_config_item_ops = {
-+	.release		= gpiommc_config_item_release,
-+	.show_attribute		= gpiommc_config_attr_show,
-+	.store_attribute	= gpiommc_config_attr_store,
-+};
-+
-+static struct config_item_type gpiommc_dev_ci_type = {
-+	.ct_item_ops	= &gpiommc_config_item_ops,
-+	.ct_attrs	= gpiommc_config_attrs,
-+	.ct_owner	= THIS_MODULE,
-+};
-+
-+static struct config_item *gpiommc_make_item(struct config_group *group,
-+					     const char *name)
-+{
-+	struct gpiommc_configfs_device *dev;
-+
-+	if (strlen(name) > GPIOMMC_MAX_NAMELEN) {
-+		printk(KERN_ERR PFX "configfs: device name too long\n");
-+		return NULL;
-+	}
-+
-+	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-+	if (!dev)
-+		return NULL;
-+
-+	config_item_init_type_name(&dev->item, name,
-+				   &gpiommc_dev_ci_type);
-+
-+	/* Assign default configuration */
-+	dev->pdata.pins.gpio_di = GPIO_INVALID;
-+	dev->pdata.pins.gpio_do = GPIO_INVALID;
-+	dev->pdata.pins.gpio_clk = GPIO_INVALID;
-+	dev->pdata.pins.gpio_cs = GPIO_INVALID;
-+	dev->pdata.pins.cs_activelow = 1;
-+	dev->pdata.mode = SPI_MODE_0;
-+	dev->pdata.no_spi_delay = 0;
-+	dev->pdata.max_bus_speed = 5000000; /* 5 MHz */
-+
-+	return &(dev->item);
-+}
-+
-+static void gpiommc_drop_item(struct config_group *group,
-+			      struct config_item *item)
-+{
-+	struct gpiommc_configfs_device *dev = ci_to_gpiommc(item);
-+
-+	gpiommc_do_unregister(dev);
-+	kfree(dev);
-+}
-+
-+static struct configfs_group_operations gpiommc_ct_group_ops = {
-+	.make_item	= gpiommc_make_item,
-+	.drop_item	= gpiommc_drop_item,
-+};
-+
-+static struct config_item_type gpiommc_ci_type = {
-+	.ct_group_ops	= &gpiommc_ct_group_ops,
-+	.ct_owner	= THIS_MODULE,
-+};
-+
-+static struct configfs_subsystem gpiommc_subsys = {
-+	.su_group = {
-+		.cg_item = {
-+			.ci_namebuf = GPIOMMC_PLATDEV_NAME,
-+			.ci_type = &gpiommc_ci_type,
-+		},
-+	},
-+	.su_mutex = __MUTEX_INITIALIZER(gpiommc_subsys.su_mutex),
-+};
-+
-+#endif /* CONFIG_GPIOMMC_CONFIGFS */
-+
-+static struct platform_driver gpiommc_plat_driver = {
-+	.probe	= gpiommc_probe,
-+	.remove	= gpiommc_remove,
-+	.driver	= {
-+		.name	= GPIOMMC_PLATDEV_NAME,
-+		.owner	= THIS_MODULE,
-+	},
-+};
-+
-+int gpiommc_next_id(void)
-+{
-+	static atomic_t counter = ATOMIC_INIT(-1);
-+
-+	return atomic_inc_return(&counter);
-+}
-+EXPORT_SYMBOL(gpiommc_next_id);
-+
-+static int __init gpiommc_modinit(void)
-+{
-+	int err;
-+
-+	err = platform_driver_register(&gpiommc_plat_driver);
-+	if (err)
-+		return err;
-+
-+#ifdef CONFIG_GPIOMMC_CONFIGFS
-+	config_group_init(&gpiommc_subsys.su_group);
-+	err = configfs_register_subsystem(&gpiommc_subsys);
-+	if (err) {
-+		platform_driver_unregister(&gpiommc_plat_driver);
-+		return err;
-+	}
-+#endif /* CONFIG_GPIOMMC_CONFIGFS */
-+
-+	return 0;
-+}
-+module_init(gpiommc_modinit);
-+
-+static void __exit gpiommc_modexit(void)
-+{
-+#ifdef CONFIG_GPIOMMC_CONFIGFS
-+	configfs_unregister_subsystem(&gpiommc_subsys);
-+#endif
-+	platform_driver_unregister(&gpiommc_plat_driver);
-+}
-+module_exit(gpiommc_modexit);
---- a/drivers/mmc/host/Kconfig
-+++ b/drivers/mmc/host/Kconfig
-@@ -437,6 +437,31 @@ config MMC_TMIO
- 	  This provides support for the SD/MMC cell found in TC6393XB,
- 	  T7L66XB and also HTC ASIC3
- 
-+config GPIOMMC
-+	tristate "MMC/SD over GPIO-based SPI"
-+	depends on MMC && MMC_SPI && SPI_GPIO_OLD
-+	help
-+	  This driver hooks up the mmc_spi and spi_gpio modules so that
-+	  MMC/SD cards can be used on a GPIO based bus by bitbanging
-+	  the SPI protocol in software.
-+
-+	  This driver provides a configfs interface to dynamically create
-+	  and destroy GPIO-based MMC/SD card devices. It also provides
-+	  a platform device interface API.
-+	  See Documentation/gpiommc.txt for details.
-+
-+	  The module will be called gpiommc.
-+
-+	  If unsure, say N.
-+
-+config GPIOMMC_CONFIGFS
-+	bool
-+	depends on GPIOMMC && CONFIGFS_FS
-+	default y
-+	help
-+	  This option automatically enables configfs support for gpiommc
-+	  if configfs is available.
-+
- config MMC_CB710
- 	tristate "ENE CB710 MMC/SD Interface support"
- 	depends on PCI
---- a/drivers/mmc/host/Makefile
-+++ b/drivers/mmc/host/Makefile
-@@ -30,6 +30,7 @@ obj-$(CONFIG_MMC_SDRICOH_CS)	+= sdricoh_
- obj-$(CONFIG_MMC_TMIO)		+= tmio_mmc.o
- obj-$(CONFIG_MMC_CB710)	+= cb710-mmc.o
- obj-$(CONFIG_MMC_VIA_SDMMC)	+= via-sdmmc.o
-+obj-$(CONFIG_GPIOMMC)		+= gpiommc.o
- obj-$(CONFIG_SDH_BFIN)		+= bfin_sdh.o
- obj-$(CONFIG_MMC_DW)		+= dw_mmc.o
- obj-$(CONFIG_MMC_SH_MMCIF)	+= sh_mmcif.o
---- /dev/null
-+++ b/include/linux/mmc/gpiommc.h
-@@ -0,0 +1,71 @@
-+/*
-+ * Device driver for MMC/SD cards driven over a GPIO bus.
-+ *
-+ * Copyright (c) 2008 Michael Buesch
-+ *
-+ * Licensed under the GNU/GPL version 2.
-+ */
-+#ifndef LINUX_GPIOMMC_H_
-+#define LINUX_GPIOMMC_H_
-+
-+#include <linux/types.h>
-+
-+
-+#define GPIOMMC_MAX_NAMELEN		15
-+#define GPIOMMC_MAX_NAMELEN_STR		__stringify(GPIOMMC_MAX_NAMELEN)
-+
-+/**
-+ * struct gpiommc_pins - Hardware pin assignments
-+ *
-+ * @gpio_di: The GPIO number of the DATA IN pin
-+ * @gpio_do: The GPIO number of the DATA OUT pin
-+ * @gpio_clk: The GPIO number of the CLOCK pin
-+ * @gpio_cs: The GPIO number of the CHIPSELECT pin
-+ * @cs_activelow: If true, the chip is considered selected if @gpio_cs is low.
-+ */
-+struct gpiommc_pins {
-+	unsigned int gpio_di;
-+	unsigned int gpio_do;
-+	unsigned int gpio_clk;
-+	unsigned int gpio_cs;
-+	bool cs_activelow;
-+};
-+
-+/**
-+ * struct gpiommc_platform_data - Platform data for a MMC-over-SPI-GPIO device.
-+ *
-+ * @name: The unique name string of the device.
-+ * @pins: The hardware pin assignments.
-+ * @mode: The hardware mode. This is either SPI_MODE_0,
-+ *        SPI_MODE_1, SPI_MODE_2 or SPI_MODE_3. See the SPI documentation.
-+ * @no_spi_delay: Do not use delays in the lowlevel SPI bitbanging code.
-+ *                This is not standards compliant, but may be required for some
-+ *                embedded machines to gain reasonable speed.
-+ * @max_bus_speed: The maximum speed of the SPI bus, in Hertz.
-+ */
-+struct gpiommc_platform_data {
-+	char name[GPIOMMC_MAX_NAMELEN + 1];
-+	struct gpiommc_pins pins;
-+	u8 mode;
-+	bool no_spi_delay;
-+	unsigned int max_bus_speed;
-+};
-+
-+/**
-+ * GPIOMMC_PLATDEV_NAME - The platform device name string.
-+ *
-+ * The name string that has to be used for platform_device_alloc
-+ * when allocating a gpiommc device.
-+ */
-+#define GPIOMMC_PLATDEV_NAME	"gpiommc"
-+
-+/**
-+ * gpiommc_next_id - Get another platform device ID number.
-+ *
-+ * This returns the next platform device ID number that has to be used
-+ * for platform_device_alloc. The ID is opaque and should not be used for
-+ * anything else.
-+ */
-+int gpiommc_next_id(void);
-+
-+#endif /* LINUX_GPIOMMC_H_ */
---- /dev/null
-+++ b/Documentation/gpiommc.txt
-@@ -0,0 +1,97 @@
-+GPIOMMC - Driver for an MMC/SD card on a bitbanging GPIO SPI bus
-+================================================================
-+
-+The gpiommc module hooks up the mmc_spi and spi_gpio modules for running an
-+MMC or SD card on GPIO pins.
-+
-+Two interfaces for registering a new MMC/SD card device are provided:
-+A static platform-device based mechanism and a dynamic configfs based interface.
-+
-+
-+Registering devices via platform-device
-+=======================================
-+
-+The platform-device interface is used for registering MMC/SD devices that are
-+part of the hardware platform. This is most useful only for embedded machines
-+with MMC/SD devices statically connected to the platform GPIO bus.
-+
-+The data structures are declared in <linux/mmc/gpiommc.h>.
-+
-+To register a new device, define an instance of struct gpiommc_platform_data.
-+This structure holds any information about how the device is hooked up to the
-+GPIO pins and what hardware modes the device supports. See the docbook-style
-+documentation in the header file for more information on the struct fields.
-+
-+Then allocate a new instance of a platform device by doing:
-+
-+	pdev = platform_device_alloc(GPIOMMC_PLATDEV_NAME, gpiommc_next_id());
-+
-+This will allocate the platform device data structures and hook it up to the
-+gpiommc driver.
-+Then add the gpiommc_platform_data to the platform device.
-+
-+	err = platform_device_add_data(pdev, pdata, sizeof(struct gpiommc_platform_data));
-+
-+You may free the local instance of struct gpiommc_platform_data now. (So the
-+struct may be allocated on the stack, too).
-+Now simply register the platform device.
-+
-+	err = platform_device_add(pdev);
-+
-+Done. The gpiommc probe routine will be invoked now and you should see a kernel
-+log message for the added device.
-+
-+
-+Registering devices via configfs
-+================================
-+
-+MMC/SD cards connected via GPIO often are a pretty dynamic thing, as for example
-+selfmade hacks for soldering an MMC/SD card to standard GPIO pins on embedded
-+hardware are a common situation.
-+So we provide a dynamic interface to conveniently handle adding and removing
-+devices from userspace, without the need to recompile the kernel.
-+
-+The "gpiommc" subdirectory at the configfs mountpoint is used for handling
-+the dynamic configuration.
-+
-+To create a new device, it must first be allocated with mkdir.
-+The following command will allocate a device named "my_mmc":
-+	mkdir /config/gpiommc/my_mmc
-+
-+There are several configuration files available in the new
-+/config/gpiommc/my_mmc/ directory:
-+
-+gpio_data_in			= The SPI data-IN GPIO pin number.
-+gpio_data_out			= The SPI data-OUT GPIO pin number.
-+gpio_clock			= The SPI Clock GPIO pin number.
-+gpio_chipselect			= The SPI Chipselect GPIO pin number.
-+gpio_chipselect_activelow	= Boolean. If 0, Chipselect is active-HIGH.
-+				  If 1, Chipselect is active-LOW.
-+spi_mode			= The SPI data mode. Can be 0-3.
-+spi_delay			= Enable all delays in the lowlevel bitbanging.
-+max_bus_speed			= The maximum SPI bus speed. In Hertz.
-+
-+register			= Not a configuration parameter.
-+				  Used to register the configured card
-+				  with the kernel.
-+
-+The device must first get configured and then registered by writing "1" to
-+the "register" file.
-+The configuration parameters "gpio_data_in", "gpio_data_out", "gpio_clock"
-+and "gpio_chipselect" are essential and _must_ be configured before writing
-+"1" to the "register" file. The registration will fail, otherwise.
-+
-+The default values for the other parameters are:
-+gpio_chipselect_activelow	= 1		(CS active-LOW)
-+spi_mode			= 0		(SPI_MODE_0)
-+spi_delay			= 1		(enabled)
-+max_bus_speed			= 5000000	(5 Mhz)
-+
-+Configuration values can not be changed after registration. To unregister
-+the device, write a "0" to the "register" file. The configuration can be
-+changed again after unregistering.
-+
-+To completely remove the device, simply rmdir the directory
-+(/config/gpiommc/my_mmc in this example).
-+There's no need to first unregister the device before removing it. That will
-+be done automatically.
---- a/MAINTAINERS
-+++ b/MAINTAINERS
-@@ -2884,6 +2884,11 @@ T:	git git://git.kernel.org/pub/scm/linu
- S:	Maintained
- F:	drivers/media/video/gspca/
- 
-+GPIOMMC DRIVER
-+P:	Michael Buesch
-+M:	mb@bu3sch.de
-+S:	Maintained
-+
- HARDWARE MONITORING
- M:	Jean Delvare <khali@linux-fr.org>
- M:	Guenter Roeck <guenter.roeck@ericsson.com>
diff --git a/target/linux/generic/patches-2.6.38/864-gpiommc_configfs_locking.patch b/target/linux/generic/patches-2.6.38/864-gpiommc_configfs_locking.patch
deleted file mode 100644
index 2e4e820b2b..0000000000
--- a/target/linux/generic/patches-2.6.38/864-gpiommc_configfs_locking.patch
+++ /dev/null
@@ -1,58 +0,0 @@
-The gpiommc configfs context structure needs locking, as configfs
-does not lock access between files.
-
---- a/drivers/mmc/host/gpiommc.c
-+++ b/drivers/mmc/host/gpiommc.c
-@@ -143,6 +143,8 @@ struct gpiommc_configfs_device {
- 	struct platform_device *pdev;
- 	/* The configuration */
- 	struct gpiommc_platform_data pdata;
-+	/* Mutex to protect this structure */
-+	struct mutex mutex;
- };
- 
- #define GPIO_INVALID	-1
-@@ -233,6 +235,8 @@ static ssize_t gpiommc_config_attr_show(
- 	unsigned int gpio;
- 	int err = 0;
- 
-+	mutex_lock(&dev->mutex);
-+
- 	if (attr == &gpiommc_attr_DI) {
- 		gpio = dev->pdata.pins.gpio_di;
- 		if (gpio == GPIO_INVALID)
-@@ -293,6 +297,8 @@ static ssize_t gpiommc_config_attr_show(
- 	WARN_ON(1);
- 	err = -ENOSYS;
- out:
-+	mutex_unlock(&dev->mutex);
-+
- 	return err ? err : count;
- }
- 
-@@ -352,6 +358,8 @@ static ssize_t gpiommc_config_attr_store
- 	int err = -EINVAL;
- 	unsigned long data;
- 
-+	mutex_lock(&dev->mutex);
-+
- 	if (attr == &gpiommc_attr_register) {
- 		err = strict_strtoul(page, 10, &data);
- 		if (err)
-@@ -477,6 +485,8 @@ static ssize_t gpiommc_config_attr_store
- 	WARN_ON(1);
- 	err = -ENOSYS;
- out:
-+	mutex_unlock(&dev->mutex);
-+
- 	return err ? err : count;
- }
- 
-@@ -513,6 +523,7 @@ static struct config_item *gpiommc_make_
- 	if (!dev)
- 		return NULL;
- 
-+	mutex_init(&dev->mutex);
- 	config_item_init_type_name(&dev->item, name,
- 				   &gpiommc_dev_ci_type);
- 
diff --git a/target/linux/generic/patches-2.6.38/870-hifn795x_byteswap.patch b/target/linux/generic/patches-2.6.38/870-hifn795x_byteswap.patch
deleted file mode 100644
index 3a37c951ec..0000000000
--- a/target/linux/generic/patches-2.6.38/870-hifn795x_byteswap.patch
+++ /dev/null
@@ -1,17 +0,0 @@
---- a/drivers/crypto/hifn_795x.c
-+++ b/drivers/crypto/hifn_795x.c
-@@ -682,12 +682,12 @@ static inline u32 hifn_read_1(struct hif
- 
- static inline void hifn_write_0(struct hifn_device *dev, u32 reg, u32 val)
- {
--	writel((__force u32)cpu_to_le32(val), dev->bar[0] + reg);
-+	writel(val, dev->bar[0] + reg);
- }
- 
- static inline void hifn_write_1(struct hifn_device *dev, u32 reg, u32 val)
- {
--	writel((__force u32)cpu_to_le32(val), dev->bar[1] + reg);
-+	writel(val, dev->bar[1] + reg);
- }
- 
- static void hifn_wait_puc(struct hifn_device *dev)
diff --git a/target/linux/generic/patches-2.6.38/900-slab_maxsize.patch b/target/linux/generic/patches-2.6.38/900-slab_maxsize.patch
deleted file mode 100644
index 55e2516a69..0000000000
--- a/target/linux/generic/patches-2.6.38/900-slab_maxsize.patch
+++ /dev/null
@@ -1,13 +0,0 @@
---- a/include/linux/slab.h
-+++ b/include/linux/slab.h
-@@ -128,8 +128,8 @@ const char *kmem_cache_name(struct kmem_
-  * to do various tricks to work around compiler limitations in order to
-  * ensure proper constant folding.
-  */
--#define KMALLOC_SHIFT_HIGH	((MAX_ORDER + PAGE_SHIFT - 1) <= 25 ? \
--				(MAX_ORDER + PAGE_SHIFT - 1) : 25)
-+#define KMALLOC_SHIFT_HIGH	((MAX_ORDER + PAGE_SHIFT - 1) <= 17 ? \
-+				(MAX_ORDER + PAGE_SHIFT - 1) : 17)
- 
- #define KMALLOC_MAX_SIZE	(1UL << KMALLOC_SHIFT_HIGH)
- #define KMALLOC_MAX_ORDER	(KMALLOC_SHIFT_HIGH - PAGE_SHIFT)
diff --git a/target/linux/generic/patches-2.6.38/910-kobject_uevent.patch b/target/linux/generic/patches-2.6.38/910-kobject_uevent.patch
deleted file mode 100644
index f15749fa17..0000000000
--- a/target/linux/generic/patches-2.6.38/910-kobject_uevent.patch
+++ /dev/null
@@ -1,32 +0,0 @@
---- a/lib/kobject_uevent.c
-+++ b/lib/kobject_uevent.c
-@@ -49,6 +49,18 @@ static const char *kobject_actions[] = {
- 	[KOBJ_OFFLINE] =	"offline",
- };
- 
-+u64 uevent_next_seqnum(void)
-+{
-+	u64 seq;
-+
-+	spin_lock(&sequence_lock);
-+	seq = ++uevent_seqnum;
-+	spin_unlock(&sequence_lock);
-+
-+	return seq;
-+}
-+EXPORT_SYMBOL_GPL(uevent_next_seqnum);
-+
- /**
-  * kobject_action_type - translate action string to numeric type
-  *
-@@ -244,9 +256,7 @@ int kobject_uevent_env(struct kobject *k
- 		kobj->state_remove_uevent_sent = 1;
- 
- 	/* we will send an event, so request a new sequence number */
--	spin_lock(&sequence_lock);
--	seq = ++uevent_seqnum;
--	spin_unlock(&sequence_lock);
-+	seq = uevent_next_seqnum();
- 	retval = add_uevent_var(env, "SEQNUM=%llu", (unsigned long long)seq);
- 	if (retval)
- 		goto exit;
diff --git a/target/linux/generic/patches-2.6.38/911-kobject_add_broadcast_uevent.patch b/target/linux/generic/patches-2.6.38/911-kobject_add_broadcast_uevent.patch
deleted file mode 100644
index 7b36ab6115..0000000000
--- a/target/linux/generic/patches-2.6.38/911-kobject_add_broadcast_uevent.patch
+++ /dev/null
@@ -1,85 +0,0 @@
---- a/include/linux/kobject.h
-+++ b/include/linux/kobject.h
-@@ -31,6 +31,8 @@
- #define UEVENT_NUM_ENVP			32	/* number of env pointers */
- #define UEVENT_BUFFER_SIZE		2048	/* buffer for the variables */
- 
-+struct sk_buff;
-+
- /* path to the userspace helper executed on an event */
- extern char uevent_helper[];
- 
-@@ -215,6 +217,10 @@ int add_uevent_var(struct kobj_uevent_en
- 
- int kobject_action_type(const char *buf, size_t count,
- 			enum kobject_action *type);
-+
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+		     gfp_t allocation);
-+
- #else
- static inline int kobject_uevent(struct kobject *kobj,
- 				 enum kobject_action action)
-@@ -231,6 +237,16 @@ static inline int add_uevent_var(struct
- static inline int kobject_action_type(const char *buf, size_t count,
- 				      enum kobject_action *type)
- { return -EINVAL; }
-+
-+void kfree_skb(struct sk_buff *);
-+
-+static inline int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+				   gfp_t allocation)
-+{
-+	kfree_skb(skb);
-+	return 0;
-+}
-+
- #endif
- 
- #endif /* _KOBJECT_H_ */
---- a/lib/kobject_uevent.c
-+++ b/lib/kobject_uevent.c
-@@ -377,6 +377,43 @@ int add_uevent_var(struct kobj_uevent_en
- EXPORT_SYMBOL_GPL(add_uevent_var);
- 
- #if defined(CONFIG_NET)
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+		     gfp_t allocation)
-+{
-+	struct uevent_sock *ue_sk;
-+	int err = 0;
-+
-+	/* send netlink message */
-+	mutex_lock(&uevent_sock_mutex);
-+	list_for_each_entry(ue_sk, &uevent_sock_list, list) {
-+		struct sock *uevent_sock = ue_sk->sk;
-+		struct sk_buff *skb2;
-+
-+		skb2 = skb_clone(skb, allocation);
-+		if (!skb2)
-+			break;
-+
-+		err = netlink_broadcast(uevent_sock, skb2, pid, group,
-+					allocation);
-+		if (err)
-+			break;
-+	}
-+	mutex_unlock(&uevent_sock_mutex);
-+
-+	kfree_skb(skb);
-+	return err;
-+}
-+#else
-+int broadcast_uevent(struct sk_buff *skb, __u32 pid, __u32 group,
-+		     gfp_t allocation)
-+{
-+	kfree_skb(skb);
-+	return 0;
-+}
-+#endif
-+EXPORT_SYMBOL_GPL(broadcast_uevent);
-+
-+#if defined(CONFIG_NET)
- static int uevent_net_init(struct net *net)
- {
- 	struct uevent_sock *ue_sk;
diff --git a/target/linux/generic/patches-2.6.38/920-unable_to_open_console.patch b/target/linux/generic/patches-2.6.38/920-unable_to_open_console.patch
deleted file mode 100644
index 767f777d1d..0000000000
--- a/target/linux/generic/patches-2.6.38/920-unable_to_open_console.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/init/main.c
-+++ b/init/main.c
-@@ -899,7 +899,7 @@ static int __init kernel_init(void * unu
- 
- 	/* Open the /dev/console on the rootfs, this should never fail */
- 	if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
--		printk(KERN_WARNING "Warning: unable to open an initial console.\n");
-+		printk(KERN_WARNING "Please be patient, while OpenWrt loads ...\n");
- 
- 	(void) sys_dup(0);
- 	(void) sys_dup(0);
diff --git a/target/linux/generic/patches-2.6.38/921-use_preinit_as_init.patch b/target/linux/generic/patches-2.6.38/921-use_preinit_as_init.patch
deleted file mode 100644
index d46c13b334..0000000000
--- a/target/linux/generic/patches-2.6.38/921-use_preinit_as_init.patch
+++ /dev/null
@@ -1,14 +0,0 @@
---- a/init/main.c
-+++ b/init/main.c
-@@ -852,10 +852,7 @@ static noinline int init_post(void)
- 		printk(KERN_WARNING "Failed to execute %s.  Attempting "
- 					"defaults...\n", execute_command);
- 	}
--	run_init_process("/sbin/init");
--	run_init_process("/etc/init");
--	run_init_process("/bin/init");
--	run_init_process("/bin/sh");
-+	run_init_process("/etc/preinit");
- 
- 	panic("No init found.  Try passing init= option to kernel. "
- 	      "See Linux Documentation/init.txt for guidance.");
diff --git a/target/linux/generic/patches-2.6.38/930-crashlog.patch b/target/linux/generic/patches-2.6.38/930-crashlog.patch
deleted file mode 100644
index 8c8f05c260..0000000000
--- a/target/linux/generic/patches-2.6.38/930-crashlog.patch
+++ /dev/null
@@ -1,242 +0,0 @@
---- /dev/null
-+++ b/include/linux/crashlog.h
-@@ -0,0 +1,12 @@
-+#ifndef __CRASHLOG_H
-+#define __CRASHLOG_H
-+
-+#ifdef CONFIG_CRASHLOG
-+void __init crashlog_init_mem(struct bootmem_data *bdata);
-+#else
-+static inline void crashlog_init_mem(struct bootmem_data *bdata)
-+{
-+}
-+#endif
-+
-+#endif
---- a/init/Kconfig
-+++ b/init/Kconfig
-@@ -862,6 +862,10 @@ config RELAY
- 
- 	  If unsure, say N.
- 
-+config CRASHLOG
-+	bool "Crash logging"
-+	depends on !NO_BOOTMEM && !HAVE_MEMBLOCK
-+
- config BLK_DEV_INITRD
- 	bool "Initial RAM filesystem and RAM disk (initramfs/initrd) support"
- 	depends on BROKEN || !FRV
---- a/kernel/Makefile
-+++ b/kernel/Makefile
-@@ -107,6 +107,7 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.
- obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
- obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
- obj-$(CONFIG_PADATA) += padata.o
-+obj-$(CONFIG_CRASHLOG) += crashlog.o
- 
- ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
- # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
---- /dev/null
-+++ b/kernel/crashlog.c
-@@ -0,0 +1,171 @@
-+/*
-+ * Crash information logger
-+ * Copyright (C) 2010 Felix Fietkau <nbd@openwrt.org>
-+ *
-+ * Based on ramoops.c
-+ *   Copyright (C) 2010 Marco Stornelli <marco.stornelli@gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or
-+ * modify it under the terms of the GNU General Public License
-+ * version 2 as published by the Free Software Foundation.
-+ *
-+ * This program is distributed in the hope that it will be useful, but
-+ * WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-+ * 02110-1301 USA
-+ *
-+ */
-+
-+#include <linux/module.h>
-+#include <linux/bootmem.h>
-+#include <linux/debugfs.h>
-+#include <linux/crashlog.h>
-+#include <linux/kmsg_dump.h>
-+#include <linux/module.h>
-+#include <linux/pfn.h>
-+#include <asm/io.h>
-+
-+#define CRASHLOG_PAGES	4
-+#define CRASHLOG_SIZE	(CRASHLOG_PAGES * PAGE_SIZE)
-+#define CRASHLOG_MAGIC	0xa1eedead
-+
-+/*
-+ * Start the log at 1M before the end of RAM, as some boot loaders like
-+ * to use the end of the RAM for stack usage and other things
-+ * If this fails, fall back to using the last part.
-+ */
-+#define CRASHLOG_OFFSET	(1024 * 1024)
-+
-+struct crashlog_data {
-+	u32 magic;
-+	u32 len;
-+	u8 data[];
-+};
-+
-+static struct debugfs_blob_wrapper crashlog_blob;
-+static unsigned long crashlog_addr = 0;
-+static struct crashlog_data *crashlog_buf;
-+static struct kmsg_dumper dump;
-+static bool first = true;
-+
-+extern struct list_head *crashlog_modules;
-+
-+void __init crashlog_init_mem(bootmem_data_t *bdata)
-+{
-+	unsigned long addr;
-+
-+	if (crashlog_addr)
-+		return;
-+
-+	addr = PFN_PHYS(bdata->node_low_pfn) - CRASHLOG_OFFSET;
-+	if (reserve_bootmem(addr, CRASHLOG_SIZE, BOOTMEM_EXCLUSIVE) < 0) {
-+		printk("Crashlog failed to allocate RAM at address 0x%lx\n", addr);
-+		bdata->node_low_pfn -= CRASHLOG_PAGES;
-+		addr = PFN_PHYS(bdata->node_low_pfn);
-+	}
-+	crashlog_addr = addr;
-+}
-+
-+static void __init crashlog_copy(void)
-+{
-+	if (crashlog_buf->magic != CRASHLOG_MAGIC)
-+		return;
-+
-+	if (!crashlog_buf->len || crashlog_buf->len >
-+	    CRASHLOG_SIZE - sizeof(*crashlog_buf))
-+		return;
-+
-+	crashlog_blob.size = crashlog_buf->len;
-+	crashlog_blob.data = kmemdup(crashlog_buf->data,
-+		crashlog_buf->len, GFP_KERNEL);
-+
-+	debugfs_create_blob("crashlog", 0700, NULL, &crashlog_blob);
-+}
-+
-+static int get_maxlen(void)
-+{
-+	return CRASHLOG_SIZE - sizeof(*crashlog_buf) - crashlog_buf->len;
-+}
-+
-+static void crashlog_printf(const char *fmt, ...)
-+{
-+	va_list args;
-+	int len = get_maxlen();
-+
-+	if (!len)
-+		return;
-+
-+	va_start(args, fmt);
-+	crashlog_buf->len += vsnprintf(
-+		&crashlog_buf->data[crashlog_buf->len],
-+		len, fmt, args);
-+	va_end(args);
-+}
-+
-+static void crashlog_do_dump(struct kmsg_dumper *dumper,
-+		enum kmsg_dump_reason reason, const char *s1, unsigned long l1,
-+		const char *s2, unsigned long l2)
-+{
-+	unsigned long s1_start, s2_start;
-+	unsigned long l1_cpy, l2_cpy;
-+	struct timeval tv;
-+	struct module *m;
-+	char *buf;
-+	int len;
-+
-+	if (!first)
-+		crashlog_printf("\n===================================\n");
-+
-+	do_gettimeofday(&tv);
-+	crashlog_printf("Time: %lu.%lu\n",
-+		(long)tv.tv_sec, (long)tv.tv_usec);
-+
-+	if (first) {
-+		crashlog_printf("Modules:");
-+		list_for_each_entry(m, crashlog_modules, list) {
-+			crashlog_printf("\t%s@%p+%x", m->name,
-+			m->module_core, m->core_size,
-+			m->module_init, m->init_size);
-+		}
-+		crashlog_printf("\n");
-+		first = false;
-+	}
-+
-+	buf = (char *)&crashlog_buf->data[crashlog_buf->len];
-+	len = get_maxlen();
-+
-+	l2_cpy = min(l2, (unsigned long)len);
-+	l1_cpy = min(l1, (unsigned long)len - l2_cpy);
-+
-+	s2_start = l2 - l2_cpy;
-+	s1_start = l1 - l1_cpy;
-+
-+	memcpy(buf, s1 + s1_start, l1_cpy);
-+	memcpy(buf + l1_cpy, s2 + s2_start, l2_cpy);
-+	crashlog_buf->len += l1_cpy + l2_cpy;
-+}
-+
-+
-+int __init crashlog_init_fs(void)
-+{
-+	if (!crashlog_addr)
-+		return -ENOMEM;
-+
-+	crashlog_buf = ioremap(crashlog_addr, CRASHLOG_SIZE);
-+
-+	crashlog_copy();
-+
-+	crashlog_buf->magic = CRASHLOG_MAGIC;
-+	crashlog_buf->len = 0;
-+
-+	dump.dump = crashlog_do_dump;
-+	kmsg_dump_register(&dump);
-+
-+	return 0;
-+}
-+module_init(crashlog_init_fs);
---- a/mm/bootmem.c
-+++ b/mm/bootmem.c
-@@ -15,6 +15,7 @@
- #include <linux/module.h>
- #include <linux/kmemleak.h>
- #include <linux/range.h>
-+#include <linux/crashlog.h>
- #include <linux/memblock.h>
- 
- #include <asm/bug.h>
-@@ -227,6 +228,7 @@ static unsigned long __init free_all_boo
- 	if (!bdata->node_bootmem_map)
- 		return 0;
- 
-+	crashlog_init_mem(bdata);
- 	start = bdata->node_min_pfn;
- 	end = bdata->node_low_pfn;
- 
---- a/kernel/module.c
-+++ b/kernel/module.c
-@@ -106,6 +106,9 @@ static LIST_HEAD(modules);
- #ifdef CONFIG_KGDB_KDB
- struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */
- #endif /* CONFIG_KGDB_KDB */
-+#ifdef CONFIG_CRASHLOG
-+struct list_head *crashlog_modules = &modules;
-+#endif
- 
- 
- /* Block module loading/unloading? */
diff --git a/target/linux/generic/patches-2.6.38/940-ocf_kbuild_integration.patch b/target/linux/generic/patches-2.6.38/940-ocf_kbuild_integration.patch
deleted file mode 100644
index 3c322f3d14..0000000000
--- a/target/linux/generic/patches-2.6.38/940-ocf_kbuild_integration.patch
+++ /dev/null
@@ -1,20 +0,0 @@
---- a/crypto/Kconfig
-+++ b/crypto/Kconfig
-@@ -866,3 +866,6 @@ config CRYPTO_USER_API_SKCIPHER
- source "drivers/crypto/Kconfig"
- 
- endif	# if CRYPTO
-+
-+source "crypto/ocf/Kconfig"
-+
---- a/crypto/Makefile
-+++ b/crypto/Makefile
-@@ -89,6 +89,8 @@ obj-$(CONFIG_CRYPTO_USER_API) += af_alg.
- obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
- obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
- 
-+obj-$(CONFIG_OCF_OCF) += ocf/
-+
- #
- # generic algorithms and the async_tx api
- #
diff --git a/target/linux/generic/patches-2.6.38/941-ocf_20110720.patch b/target/linux/generic/patches-2.6.38/941-ocf_20110720.patch
deleted file mode 100644
index d52cc9882e..0000000000
--- a/target/linux/generic/patches-2.6.38/941-ocf_20110720.patch
+++ /dev/null
@@ -1,133 +0,0 @@
---- a/kernel/pid.c
-+++ b/kernel/pid.c
-@@ -427,6 +427,7 @@ struct task_struct *find_task_by_vpid(pi
- {
- 	return find_task_by_pid_ns(vnr, current->nsproxy->pid_ns);
- }
-+EXPORT_SYMBOL(find_task_by_vpid);
- 
- struct pid *get_task_pid(struct task_struct *task, enum pid_type type)
- {
---- a/drivers/char/random.c
-+++ b/drivers/char/random.c
-@@ -129,6 +129,9 @@
-  *                                unsigned int value);
-  * 	void add_interrupt_randomness(int irq);
-  *
-+ *      void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
-+ *      int random_input_wait(void);
-+ *
-  * add_input_randomness() uses the input layer interrupt timing, as well as
-  * the event type information from the hardware.
-  *
-@@ -140,6 +143,13 @@
-  * a better measure, since the timing of the disk interrupts are more
-  * unpredictable.
-  *
-+ * random_input_words() just provides a raw block of entropy to the input
-+ * pool, such as from a hardware entropy generator.
-+ *
-+ * random_input_wait() suspends the caller until such time as the
-+ * entropy pool falls below the write threshold, and returns a count of how
-+ * much entropy (in bits) is needed to sustain the pool.
-+ *
-  * All of these routines try to estimate how many bits of randomness a
-  * particular randomness source.  They do this by keeping track of the
-  * first and second order deltas of the event timings.
-@@ -715,6 +725,63 @@ void add_disk_randomness(struct gendisk
- }
- #endif
- 
-+/*
-+ * random_input_words - add bulk entropy to pool
-+ *
-+ * @buf: buffer to add
-+ * @wordcount: number of __u32 words to add
-+ * @ent_count: total amount of entropy (in bits) to credit
-+ *
-+ * this provides bulk input of entropy to the input pool
-+ *
-+ */
-+void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
-+{
-+	mix_pool_bytes(&input_pool, buf, wordcount*4);
-+
-+	credit_entropy_bits(&input_pool, ent_count);
-+
-+	DEBUG_ENT("crediting %d bits => %d\n",
-+		  ent_count, input_pool.entropy_count);
-+	/*
-+	 * Wake up waiting processes if we have enough
-+	 * entropy.
-+	 */
-+	if (input_pool.entropy_count >= random_read_wakeup_thresh)
-+		wake_up_interruptible(&random_read_wait);
-+}
-+EXPORT_SYMBOL(random_input_words);
-+
-+/*
-+ * random_input_wait - wait until random needs entropy
-+ *
-+ * this function sleeps until the /dev/random subsystem actually
-+ * needs more entropy, and then return the amount of entropy
-+ * that it would be nice to have added to the system.
-+ */
-+int random_input_wait(void)
-+{
-+	int count;
-+
-+	wait_event_interruptible(random_write_wait, 
-+			 input_pool.entropy_count < random_write_wakeup_thresh);
-+
-+	count = random_write_wakeup_thresh - input_pool.entropy_count;
-+
-+        /* likely we got woken up due to a signal */
-+	if (count <= 0) count = random_read_wakeup_thresh; 
-+
-+	DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
-+		  count,
-+		  input_pool.entropy_count, random_write_wakeup_thresh);
-+
-+	return count;
-+}
-+EXPORT_SYMBOL(random_input_wait);
-+
-+
-+#define EXTRACT_SIZE 10
-+
- /*********************************************************************
-  *
-  * Entropy extraction routines
---- a/fs/fcntl.c
-+++ b/fs/fcntl.c
-@@ -142,6 +142,7 @@ SYSCALL_DEFINE1(dup, unsigned int, filde
- 	}
- 	return ret;
- }
-+EXPORT_SYMBOL(sys_dup);
- 
- #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
- 
---- a/include/linux/miscdevice.h
-+++ b/include/linux/miscdevice.h
-@@ -18,6 +18,7 @@
- #define APOLLO_MOUSE_MINOR	7
- #define PC110PAD_MINOR		9
- /*#define ADB_MOUSE_MINOR	10	FIXME OBSOLETE */
-+#define CRYPTODEV_MINOR		70	/* /dev/crypto */
- #define WATCHDOG_MINOR		130	/* Watchdog timer     */
- #define TEMP_MINOR		131	/* Temperature Sensor */
- #define RTC_MINOR		135
---- a/include/linux/random.h
-+++ b/include/linux/random.h
-@@ -54,6 +54,10 @@ extern void add_input_randomness(unsigne
- 				 unsigned int value);
- extern void add_interrupt_randomness(int irq);
- 
-+extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
-+extern int random_input_wait(void);
-+#define HAS_RANDOM_INPUT_WAIT 1
-+
- extern void get_random_bytes(void *buf, int nbytes);
- void generate_random_uuid(unsigned char uuid_out[16]);
- 
diff --git a/target/linux/generic/patches-2.6.38/950-vm_exports.patch b/target/linux/generic/patches-2.6.38/950-vm_exports.patch
deleted file mode 100644
index 7ccede586f..0000000000
--- a/target/linux/generic/patches-2.6.38/950-vm_exports.patch
+++ /dev/null
@@ -1,126 +0,0 @@
---- a/mm/shmem.c
-+++ b/mm/shmem.c
-@@ -2730,6 +2730,16 @@ out:
- 
- /* common code */
- 
-+void shmem_set_file(struct vm_area_struct *vma, struct file *file)
-+{
-+	if (vma->vm_file)
-+		fput(vma->vm_file);
-+	vma->vm_file = file;
-+	vma->vm_ops = &shmem_vm_ops;
-+	vma->vm_flags |= VM_CAN_NONLINEAR;
-+}
-+EXPORT_SYMBOL_GPL(shmem_set_file);
-+
- /**
-  * shmem_file_setup - get an unlinked file living in tmpfs
-  * @name: name for dentry (to be seen in /proc/<pid>/maps
-@@ -2807,10 +2817,7 @@ int shmem_zero_setup(struct vm_area_stru
- 	if (IS_ERR(file))
- 		return PTR_ERR(file);
- 
--	if (vma->vm_file)
--		fput(vma->vm_file);
--	vma->vm_file = file;
--	vma->vm_ops = &shmem_vm_ops;
--	vma->vm_flags |= VM_CAN_NONLINEAR;
-+	shmem_set_file(vma, file);
-+
- 	return 0;
- }
---- a/fs/file.c
-+++ b/fs/file.c
-@@ -268,6 +268,7 @@ int expand_files(struct files_struct *fi
- 	/* All good, so we try */
- 	return expand_fdtable(files, nr);
- }
-+EXPORT_SYMBOL_GPL(expand_files);
- 
- static int count_open_files(struct fdtable *fdt)
- {
---- a/kernel/exit.c
-+++ b/kernel/exit.c
-@@ -513,6 +513,7 @@ struct files_struct *get_files_struct(st
- 
- 	return files;
- }
-+EXPORT_SYMBOL_GPL(get_files_struct);
- 
- void put_files_struct(struct files_struct *files)
- {
-@@ -534,6 +535,7 @@ void put_files_struct(struct files_struc
- 		rcu_read_unlock();
- 	}
- }
-+EXPORT_SYMBOL_GPL(put_files_struct);
- 
- void reset_files_struct(struct files_struct *files)
- {
---- a/kernel/fork.c
-+++ b/kernel/fork.c
-@@ -193,6 +193,7 @@ void __put_task_struct(struct task_struc
- 	if (!profile_handoff_task(tsk))
- 		free_task(tsk);
- }
-+EXPORT_SYMBOL_GPL(__put_task_struct);
- 
- /*
-  * macro override instead of weak attribute alias, to workaround
---- a/kernel/sched.c
-+++ b/kernel/sched.c
-@@ -4641,6 +4641,7 @@ int can_nice(const struct task_struct *p
- 	return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) ||
- 		capable(CAP_SYS_NICE));
- }
-+EXPORT_SYMBOL_GPL(can_nice);
- 
- #ifdef __ARCH_WANT_SYS_NICE
- 
---- a/mm/memory.c
-+++ b/mm/memory.c
-@@ -1229,6 +1229,7 @@ unsigned long zap_page_range(struct vm_a
- 		tlb_finish_mmu(tlb, address, end);
- 	return end;
- }
-+EXPORT_SYMBOL_GPL(zap_page_range);
- 
- /**
-  * zap_vma_ptes - remove ptes mapping the vma
-@@ -2699,6 +2700,7 @@ int vmtruncate_range(struct inode *inode
- 
- 	return 0;
- }
-+EXPORT_SYMBOL_GPL(vmtruncate_range);
- 
- /*
-  * We enter with non-exclusive mmap_sem (to exclude vma changes,
---- a/mm/vmalloc.c
-+++ b/mm/vmalloc.c
-@@ -1193,6 +1193,7 @@ void unmap_kernel_range(unsigned long ad
- 	vunmap_page_range(addr, end);
- 	flush_tlb_kernel_range(addr, end);
- }
-+EXPORT_SYMBOL_GPL(unmap_kernel_range);
- 
- int map_vm_area(struct vm_struct *area, pgprot_t prot, struct page ***pages)
- {
-@@ -1308,6 +1309,7 @@ struct vm_struct *get_vm_area(unsigned l
- 	return __get_vm_area_node(size, 1, flags, VMALLOC_START, VMALLOC_END,
- 				-1, GFP_KERNEL, __builtin_return_address(0));
- }
-+EXPORT_SYMBOL_GPL(get_vm_area);
- 
- struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags,
- 				void *caller)
---- a/include/linux/mm.h
-+++ b/include/linux/mm.h
-@@ -864,6 +864,7 @@ extern void show_free_areas(void);
- 
- int shmem_lock(struct file *file, int lock, struct user_struct *user);
- struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags);
-+void shmem_set_file(struct vm_area_struct *vma, struct file *file);
- int shmem_zero_setup(struct vm_area_struct *);
- 
- #ifndef CONFIG_MMU
diff --git a/target/linux/generic/patches-2.6.38/960-decompress_unlzo_fix.patch b/target/linux/generic/patches-2.6.38/960-decompress_unlzo_fix.patch
deleted file mode 100644
index ee7c118ef0..0000000000
--- a/target/linux/generic/patches-2.6.38/960-decompress_unlzo_fix.patch
+++ /dev/null
@@ -1,23 +0,0 @@
---- /dev/null
-+++ b/include/linux/decompress/unlzo_mm.h
-@@ -0,0 +1,10 @@
-+#ifndef UNLZO_MM_H
-+#define UNLZO_MM_H
-+
-+#ifdef STATIC
-+#define INIT
-+#else
-+#define INIT __init
-+#endif
-+
-+#endif
---- a/lib/decompress_unlzo.c
-+++ b/lib/decompress_unlzo.c
-@@ -38,6 +38,7 @@
- 
- #include <linux/types.h>
- #include <linux/lzo.h>
-+#include <linux/decompress/unlzo_mm.h>
- #include <linux/decompress/mm.h>
- 
- #include <linux/compiler.h>
diff --git a/target/linux/generic/patches-2.6.38/970-mips-gcc-4.6-set-but-unused-fixes.patch b/target/linux/generic/patches-2.6.38/970-mips-gcc-4.6-set-but-unused-fixes.patch
deleted file mode 100644
index 1721a8fa76..0000000000
--- a/target/linux/generic/patches-2.6.38/970-mips-gcc-4.6-set-but-unused-fixes.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- a/arch/mips/mm/tlbex.c
-+++ b/arch/mips/mm/tlbex.c
-@@ -1151,8 +1151,8 @@ static void __cpuinit build_r4000_tlb_re
- 	struct uasm_reloc *r = relocs;
- 	u32 *f;
- 	unsigned int final_len;
--	struct mips_huge_tlb_info htlb_info;
--	enum vmalloc64_mode vmalloc_mode;
-+	struct mips_huge_tlb_info htlb_info __maybe_unused;
-+	enum vmalloc64_mode vmalloc_mode __maybe_unused;
- 
- 	memset(tlb_handler, 0, sizeof(tlb_handler));
- 	memset(labels, 0, sizeof(labels));
---- a/arch/mips/mm/c-r4k.c
-+++ b/arch/mips/mm/c-r4k.c
-@@ -1075,7 +1075,7 @@ static int __cpuinit probe_scache(void)
- 	unsigned long flags, addr, begin, end, pow2;
- 	unsigned int config = read_c0_config();
- 	struct cpuinfo_mips *c = &current_cpu_data;
--	int tmp;
-+	int tmp __maybe_unused;
- 
- 	if (config & CONF_SC)
- 		return 0;